I struggled with that a little bit as I was following the application flow particularly in the login method. All the other methods (well, except the reset request method) are after login and there is already a user object. That's why it was so easy for me to just put onvalidate modifications in the change pass and register methods.
The flow tripped me up a bit on the login side. Since we haven't tried to select the user record from the database at the time of validation, we don't know if the user exists at all. The user lookup happens in the model code a bit farther down... well, actually pretty much immediately after the form is accepted post-validation. However.... If we could pass the entire form object to the validator, the validator could then fetch the user row from the database and perform the necessary initialization of salt & algorithm for this user's stored password. Like you, I'm not sure if that's cleaner or not though... Something I was aiming for when I started looking at this was to be able to easily change the hash algorithm used without requiring all users to reset their passwords. I made my edits with this in mind. When doing the check password routine I extract the algorithm and salt from the stored password string. That means whatever the "preference" is for hashing, the stored password hash algorithm is honored. When a password is encrypted, as in register or change_password, the preferred hashing preferences are honored. That mindset is important to me for two reasons. First, my day-job is information security. Several times in the recent past I've had to tell people "don't use ____ anymore because it's weak". The application I'm working on now has about 1300 users and the passwords were hashed with sha1. My preference is nothing less than sha256. This approach will allow users to authenticate with what's in place, but when they change their password it gets stored with the new hash algo. On Sep 28, 9:46 pm, Massimo Di Pierro <massimo.dipie...@gmail.com> wrote: > Anyway, I have not looked into this with sufficient detail to know > what is cleaner (or dirtier). > I we pass an optional record argument to validate we will need to > change sqlhtml as well. > > Massimo > > On Sep 28, 8:11 pm, Dave <dave.st...@gmail.com> wrote: > > > > > > > > > That may be an even better way to accomplish this task. I actually > > considered using some sort of self-reference first, but didn't find it > > there. > > > On Sep 28, 9:00 pm, Massimo Di Pierro <massimo.dipie...@gmail.com> > > wrote: > > > > I was thinking about this... how about editing the validate function > > > in dal.py and allow it to pass the current record to the validators? > > > We cannot change the APIs but a validator is an object so we can just > > > pass the current record by attaching it as an attribute to the > > > validator object. CRYPT could check if the current record exists and > > > use it to extract the salt. In this case you woud change only the > > > validate function in dal.py and CRYPT. > > > > On Sep 28, 6:39 pm, Dave <dave.st...@gmail.com> wrote: > > > > > I've made this work. I still need a little bit of time to make it > > > > backward compatible with non-salted passwords though. > > > > > First things first, I had to disable the CRYPT validator. Although it > > > > makes handling passwords easier, encrypting them at the validator > > > > level really limits a lot of account enforcement options. > > > > > Next I created an extra utility library with two methods: > > > > crypt(password='', algorithm='sha256', salt='') and > > > > check_password(plain_password='', encrypted_password=''). The crypt > > > > function is pretty simple. It returns a hexdigest given a specified > > > > algorithm, string and salt. If no salt is specified, a 16 character > > > > salt is randomly generated. > > > > > Finally I had to do some tweaking in the Auth class. First I changed > > > > the login method to check the password with my check_password instead > > > > of a simple string compare. Next I had to add a "onvalidate" method > > > > to the 'register' and 'change_password' methods to encrypt the > > > > password. The change_password was actually a little more involved > > > > because I had to customize the old_password validator to use my > > > > check_password method. > > > > > I'm not quite ready to share the diff files because I want to re-work > > > > it so that it's reverse compatible with auth_user data created with > > > > the default settings. > > > > > On Sep 21, 1:05 pm, Dave <dave.st...@gmail.com> wrote: > > > > > > Well clearly I've sparked plenty of discussion. I am working on this > > > > > to fit my app need. Once I have a working model that doesn't break > > > > > other applications that use the default hashing and CRYPT functions > > > > > I'll post my work. As others have commented, the typical way for > > > > > storing the password would be {algorithm}$salt$hash. I have no > > > > > problem with that. The previous developer of the app I am working on > > > > > just chose to store thesaltin a separate field in the table. It's > > > > > fairly trivial for me to convert the 1500 or so user password strings. > > > > > > Stay tuned and I'll post something later this week or next. > > > > > > On Sep 20, 11:36 pm, Massimo Di Pierro <massimo.dipie...@gmail.com> > > > > > wrote: > > > > > > > This will be useful put presents a technical difficulty because of > > > > > > the > > > > > > way CRYPT works. CRYPT is the validator that check is a password is > > > > > > valid, and it does not know what is stored in db therefore it does > > > > > > not > > > > > > know thesalt. Anyway, let me know if you have a suggestion. > > > > > > > Massimo > > > > > > > On Sep 20, 9:25 pm, Dave <dave.st...@gmail.com> wrote: > > > > > > > > I have just started using web2py but already, I'm quite > > > > > > > impressed. In > > > > > > > the past couple days I've already rolled out an entire site > > > > > > > rewrite > > > > > > > and I'm working on my second project. > > > > > > > > The project I'm working on right now is currently in PHP. I was > > > > > > > in > > > > > > > the process of converting it to a Java / Spring MVC project when I > > > > > > > discovered web2py and decided that'd be a much easier, simpler and > > > > > > > quicker way to roll the app. > > > > > > > > So, let me get to my point.. The current application utilizes > > > > > > > the php > > > > > > > sha1() function with aper-usersaltstored in the database. Thesalt > > > > > > > is randomly generated each time the password is changed. This is > > > > > > > similar to the default configuration on most linux boxes. > > > > > > > > I need to make some changes to the Auth class to support the per- > > > > > > > record passwordsaltinstead of application-widesalt. Does it make > > > > > > > sense for me to provide my edits as part of the project, in case > > > > > > > someone else thinks the functionality is useful? I plan on > > > > > > > basically > > > > > > > checking to see if there is a 'salt' field in the user auth > > > > > > > table, and > > > > > > > if so, append that to the plain text password before passing it > > > > > > > to the > > > > > > > appropriate hashlib function. > > > > > > > > Thoughts?