Hello,
I've got an application where I'm sharing a database with a second (non web2py) framework. I want my web2py application to handle user registration and would like to avoid users having two passwords (partly so that only web2py ever writes to the auth_user table).
Inevitably, the hashed password storage formats differ, but I can match the hash algorithm between the two frameworks:
db.auth_user.password.requires = CRYPT(digest_alg='sha512')
Then I can just calculate the value of a second hashed password field in the foreign format - it involves recoding the string as base64, not hex, but that can be achieved using a computed field.
def alt_password(r):
passwd = r.password.split('$')
alt = base64.b64encode(passwd[1].decode('hex')) + \
'*' + base64.b64encode(passwd[2].decode('hex'))
return alt
auth.settings.extra_fields['auth_user']= [
Field('alt_password', compute=lambda r: alt_password(r))
]
Except... the simple_hash function in web2py uses (password + salt) as an input and the second framework uses (salt + password), which means there is no way to reproduce the second format from the stored hashed password. I can hack the web2py utils.py file on my installation to reverse this but I wanted to check if there was a more elegant way of overloading the simple_hash function without having to change the codebase, which makes my application unstable to upgrade.
I did wonder about extending the settings to include a salt order, but I think that would mean you'd have to extend the password string to record the order: alg$order$salt$hash. That seems like a bit of a big change for a fairly fringe use case!