[web2py-dev] password udpate by get_or_create_user()

61 views
Skip to first unread message

Richard

unread,
Oct 6, 2015, 3:37:30 PM10/6/15
to web2py-developers
Hello,

From web2py get_or_create_user() docstring :

"
Used for alternate login methods:
            If the user exists already then password is updated.
            If the user doesn't yet exist, then they are created.
"

Is there any reason why password get update ?

I found that my auth_user_archive table manage with db.auth_user._enable_record_versioning() get populated with a lot of unmeaningful record related to user authentication that trigger an user record update because of get_or_create_user() call from login()...

I fix the issue that I had with ldap_auth login method that was suffuring from a similar problem here : 


But they maybe have a good reason why password is updated all the time... Or it just because we can check if it has change or not in case of some authentication methods??

If we can't fix that, do we have a granular way to determine which record update trigger a record version to be inserted in archive table?

Thanks

Richard

Richard Vézina

unread,
Oct 6, 2015, 4:10:40 PM10/6/15
to web2py-d...@googlegroups.com
This works :

if request.function != 'get_or_create_user':
    db.auth_user._enable_record_versioning(archive_db=db,
                                                                      archive_name='auth_user_archive',
                                                                      current_record='current_record',
                                                                      is_active='is_active')



--
-- mail from:GoogleGroups "web2py-developers" mailing list
make speech: web2py-d...@googlegroups.com
unsubscribe: web2py-develop...@googlegroups.com
details : http://groups.google.com/group/web2py-developers
the project: http://code.google.com/p/web2py/
official : http://www.web2py.com/
---
You received this message because you are subscribed to the Google Groups "web2py-developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py-develop...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Richard Vézina

unread,
Oct 8, 2015, 10:56:52 AM10/8/15
to web2py-d...@googlegroups.com
Is there any reason why password get update ?

Niphlod

unread,
Oct 13, 2015, 5:04:21 PM10/13/15
to web2py-developers
imho its a documenting typo. Seeing the code, only "email" gets updated. Even so, the pydal shouldn't archive the record if no changes are made.

Niphlod

unread,
Oct 13, 2015, 5:18:58 PM10/13/15
to web2py-developers
BTW: I can recall where this comment may come from.

At some point in history, web2py changed how password got stored in the table (md5-->sha1-->pbkdf2), but being the witty backward-compatible-friendly guys we are, we put some really crazy logic - that actually works/worked - to validate the password against the "old" scheme, take the raw value (since login-time is the only moment web2py "knows" the original), then recalculate it against the "new" scheme and update it.

anyway, this should only happen when the password is actually passed. If no password is given, nothing of the above should apply.

PS: sorry, it took a while to dig this from the historical mind.

Richard Vézina

unread,
Oct 13, 2015, 8:04:22 PM10/13/15
to web2py-d...@googlegroups.com
No prob... I remember that, and I did make my own logic to make sure that all password get update on next user login...

So, if I follow you we should change get_or_create_user() in order that the password get updated only when it changes... Or you propose that we fix web2py so _enable_record_versioning() check if there is a change or not in the record before archiving it?? Or even both at the same time??

Richard

Richard Vézina

unread,
Oct 13, 2015, 10:12:33 PM10/13/15
to web2py-d...@googlegroups.com
Hello,

I try that :

from gluon.tools import Auth

# Then inside def ldap_auth()
    auth = Auth(db)

# Then latter after "if manager_user:"

                update_or_insert_values = {'first_name': store_user_firstname,
                                           'last_name': store_user_lastname,
                                           'email': store_user_mail}
                # if '@' not in username:
                #     # user as username
                #     # ################
                #     fields = ['first_name', 'last_name', 'email']
                #     user_in_db = db(db.auth_user.username == username)
                # elif '@' in username:
                #     # user as email
                #     # #############
                #     fields = ['first_name', 'last_name']
                #     user_in_db = db(db.auth_user.email == username)
                if '@' not in username:
                    # user as username
                    # ################
                    fields = ['first_name', 'last_name', 'username', 'email']
                    update_or_insert_values['username'] = username
                elif '@' in username:
                    # user as email
                    # #############
                    fields = ['first_name', 'last_name', 'email']
                    update_or_insert_values['email'] = username
                update_or_insert_values = {f: update_or_insert_values[f] for f in fields}
                # if user_in_db.count() > 0:
                #     actual_values = user_in_db.select(*[db.auth_user[f] for f in fields]).first().as_dict()
                #     if update_or_insert_values != actual_values:  # We don't update record if values are the same
                #         user_in_db.update(**update_or_insert_values)
                # else:
                #     db.auth_user.insert(**update_or_insert_values)
                auth.get_or_create_user(keys=update_or_insert_values, update_fields=fields)

I thought that with this implementation I could get rid of the issue with ldap_auth.py contrib of duplicating user already existing... But it seems that `get_or_create_user()` in that... In the book it says that :

"When a new user logins for the first time, web2py creates a new db.auth_user record associated to the user. It will use the registration_id field to store a unique id for the user."

So, since registration_id is generated by web2py on registration and ldap_auth.py is not using it even if we find the right user no matter the user register with username or email get_or_create_user() will duplicate user in auth_user because of the check done in the lines preceding this comment :



It seems to me that get_or_create_user() is not sufficient to replace the custom update made by ldap_auth.py and solving the duplicated user issue that happen when a user is using email instead of username with LDAP authentication and `auth.define_tables(username=True) is used

I will get back to this in couples of days, but if some of you have ideas... They are welcome...

Richard
Reply all
Reply to author
Forward
0 new messages