Ok! :)
Richard On Wed, Aug 7, 2013 at 10:10 AM, Massimo Di Pierro < [email protected]> wrote: > Please send me a patch when you test it. ;-) > > On Wednesday, 7 August 2013 07:51:58 UTC-5, Richard wrote: > >> No change... Auth seems to delegate entirely the validation on username >> input field in case ldap_auth is used as authentication method. >> >> I guess this simple refactor (not tested) could do the tricks at least >> for Active directory : >> >> if not IS_EMAIL()(username)[1]: >> domain = [] >> for x in ldap_basedn.split(','): >> if "DC=" in x.upper(): >> domain.append(x.split('=')[-1]**) >> identifier = "%s@%s" % (username, '.'.join(domain)) >> else: return ERROR... >> username_bare = username.split("@")[0] >> >> Richard >> >> >> >> On Wed, Aug 7, 2013 at 8:42 AM, Richard Vézina <[email protected]>wrote: >> >>> Hello, >>> >>> I was about to post this (I think I answer your question) : >>> >>> Hello, >>> >>> I think I found a flaw in the interaction between Auth and LDAP contrib >>> (web2py 2.4.7). >>> >>> If I set LDAP as unique authentification method >>> (auth.settings.login_methods = LDAP) as written in the book, web2py should >>> leaves LDAP to create user... The things is web2py Auth seems to create >>> user even if it LDAP that is responsible of doing it. I mean, I carefully >>> read the code of LDAP and the only way it could create a new user is if >>> manage_groups=True by calling do_manage_groups() since the other place >>> where LDAP is instert new user it set email, first_name and last_name. In >>> my case, if user use email instead of username (that should not be email, >>> but I can't enforce this with the custom IS_NOT_EMAIL() validator I wrote) >>> for login a new user get inserted like this : first_name = email (or the >>> content of username input that is an email), username = email and >>> registration_id = email. As far as I can see the only way LDAP could >>> produce this result is if the do_manage_groups method is called, but it >>> can't be call if manage_groups is set to False. So, the only remaining >>> possibility is that Auth is creating the new user because it recieve a bad >>> signal from LDAP. >>> >>> I make a couples tests and found that the insert new user base on the >>> credentials of already existing user that log with it email instead of it >>> username occure at line 2147-2148. So I guess Auth recieve a True flag from >>> LDAP mean the user exist in directory, since web2py can't match a existing >>> user base on the wrong username (email) it insert a new user with wrong >>> setting. >>> >>> The origin of this is multifold. First, I think it could be prevent if >>> there was a IS_NOT_EMAIL() validator on the username field, for some reason >>> I can't get it to work properly with LDAP because of the way LDAP is >>> working the validator seems to be skipped, and the username is first check >>> against directory. Maybe using IS_NOT_EMAIL() inside ldap_auth contrib >>> could solve this issue. Other possible origin is the way ldap_auth is >>> written. I mean it seems that for saving a variable "username" is >>> re-used... I think that the issue is coming from line 8 of code extract >>> below : >>> >>> if ldap_mode == 'ad': >>> # Microsoft Active Directory >>> if '@' not in username: >>> domain = [] >>> for x in ldap_basedn.split(','): >>> if "DC=" in x.upper(): >>> domain.append(x.split('=')[-1]**) >>> username = "%s@%s" % (username, '.'.join(domain)) >>> username_bare = username.split("@")[0] >>> con.set_option(ldap.OPT_**PROTOCOL_VERSION, 3) >>> # In cases where ForestDnsZones and DomainDnsZones are >>> found, >>> # result will look like the following: >>> # >>> ['ldap://ForestDnsZones.**domain.com/DC=ForestDnsZones<http://ForestDnsZones.domain.com/DC=ForestDnsZones> >>> , >>> # DC=domain,DC=com'] >>> if ldap_binddn: >>> # need to search directory with an admin account 1st >>> con.simple_bind_s(ldap_binddn, ldap_bindpw) >>> else: >>> # credentials should be in the form of >>> [email protected] >>> con.simple_bind_s(username, password) >>> # this will throw an index error if the account is not >>> found >>> # in the ldap_basedn >>> requested_attrs = ['sAMAccountName'] >>> if manage_user: >>> requested_attrs.extend([user_**firstname_attrib, >>> user_lastname_attrib, >>> user_mail_attrib]) >>> result = con.search_ext_s( >>> ldap_basedn, ldap.SCOPE_SUBTREE, >>> "(&(sAMAccountName=%s)(%s))" % ( >>> ldap.filter.escape_filter_** >>> chars(username_bare), >>> filterstr), >>> requested_attrs)[0][1] >>> if not isinstance(result, dict): >>> # result should be a dict in the form >>> # {'sAMAccountName': [username_bare]} >>> logger.warning('User [%s] not found!' % username) >>> return False >>> if ldap_binddn: >>> # We know the user exists & is in the correct OU >>> # so now we just check the password >>> con.simple_bind_s(username, password) >>> username = username_bare >>> >>> This peace of code is pretty unreliable : It start by re-creating a >>> email and store it in username vars if username it recieves from web2py is >>> not a email before derive a username_bare from the altered username var and >>> at the end it finally set username = username_bare... Why all this just to >>> avoid create a var?! >>> >>> I propose to refator this using creating a new ID or identifier var to >>> store connection "identifier" var instead reusing the username for that. >>> Then it will require to determine if the IS_NOT_EMAIL() should go at Auth >>> level or ldap_auth. I don't know so much LDAP in general and even less the >>> different implementation, so I don't know if some implementation use email >>> as an identifier or not. Since, the Auth class as mechanism to create >>> missing user I don't no if it intentional to allow the creation of user >>> with email as username or not... So, maybe it a option in to use >>> IS_NOT_EMAIL() on username field in this case it will require that >>> IS_NOT_EMAIL be at level of Auth. Maybe, I didn't be able to make work my >>> custom validator because of the order of validator (I had set multiple >>> validator on username), I will try to set only IS_NOT_EMAIL and report here >>> if it solve the problem I have with LDAP authentication. >>> >>> Thanks >>> >>> Richard >>> >>> >>> >>> On Wed, Aug 7, 2013 at 7:22 AM, Massimo Di Pierro <[email protected] >>> > wrote: >>> >>>> How would you change this? >>>> >>>> >>>> On Monday, 5 August 2013 15:42:39 UTC-5, Richard wrote: >>>> >>>>> Hello, >>>>> >>>>> Is there a way to prevent user to log with there email? I set LDAP >>>>> authentication, I create a username field on custom auth_user model and >>>>> set >>>>> auth.define_tables(username=**Tr**ue) >>>>> >>>>> But I notice that I can still login with [email protected]. In this >>>>> case, ldap_auth create a new user with first_name and username = >>>>> [email protected] >>>>> >>>>> So, I think there is a flaw here in ldap_auth : >>>>> >>>>> if ldap_mode == 'ad': >>>>> # Microsoft Active Directory >>>>> if '@' not in username: >>>>> domain = [] >>>>> for x in ldap_basedn.split(','): >>>>> if "DC=" in x.upper(): >>>>> domain.append(x.split('=')[-1]****) >>>>> username = "%s@%s" % (username, '.'.join(domain)) >>>>> username_bare = username.split("@")[0] >>>>> >>>>> Since it seems to recreate email as username... >>>>> >>>>> Thanks >>>>> >>>>> Richard >>>>> >>>> -- >>>> >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "web2py-users" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to web2py+un...@**googlegroups.com. >>>> >>>> For more options, visit >>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out> >>>> . >>>> >>>> >>>> >>> >>> >> -- > > --- > You received this message because you are subscribed to the Google Groups > "web2py-users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.

