I have not forgotten. I opened issue 1645. On Tuesday, 13 August 2013 15:13:30 UTC-5, Richard wrote: > > Massimo, > > If you are concern about possible backward compatibility issue that this > change could raise... Maybe we could find a way to let the ldap_auth return > validator error to form (to user)... I could live with that too... I just > didn't find a easy way to make it works from ldap_auth (mean a lot of > refactoring could be required and I don't want to screw up ldap_auth for > others, I am not equiped to test it properly over different ldap > implementation). I just have to change a single line in tools.py + add a > IS_NOT_EMAIL() validator, that was the easiest... > > :) > > Richard > > > On Tue, Aug 13, 2013 at 10:19 AM, Richard Vézina > <[email protected]<javascript:> > > wrote: > >> No problem! >> >> As long as there is a solution in the next version I will be happy... >> Curious to know what is bugging you though, adding a new validator? Maybe >> the IS_MAIL() could be hack in order that it usage could be reversed, >> something like this : IS_MAIL(..., complement=True), then it will return >> true if the string is not a email... So don't need a new validator. >> >> Richard >> >> >> >> >> On Tue, Aug 13, 2013 at 10:04 AM, Massimo Di Pierro < >> [email protected] <javascript:>> wrote: >> >>> I need to review this. I understand the problem but I am not convinced >>> by the solution. I will need one week. >>> >>> >>> On Monday, 12 August 2013 08:46:31 UTC-5, Richard wrote: >>> >>>> UP! >>>> >>>> >>>> >>>> On Fri, Aug 9, 2013 at 10:59 AM, Richard Vézina >>>> <[email protected]>wrote: >>>> >>>>> Here the patch!! >>>>> >>>>> I have not been able to use the IS_NOT_EMAIL() validator from >>>>> validators.py didn't understand how validators are import in tools.py... >>>>> >>>>> NOTE : >>>>> About my precedent mail... the "auth_table.username.requires = >>>>> IS_NOT_IN_DB(db, auth_table.username" from the book is not require if the >>>>> user use the "auth.define_tables(username=**True)" and the >>>>> recommended auth_tables customization mechanism. So, I think the book >>>>> should be revised this way : >>>>> >>>>> "In case you use old style customizing auth_tables. Make sure your >>>>> username field definition looks like that : >>>>> Field('username', 'string', >>>>> notnull=True, >>>>> required=True, >>>>> requires=[IS_NOT_EMPTY(error_**message=T(auth.messages.is_* >>>>> *empty)), >>>>> IS_NOT_IN_DB(db, 'auth_user.username'), >>>>> IS_NOT_EMAIL()] >>>>> ), >>>>> >>>>> Where you make sure you use these validators in order to make sure >>>>> email is not used as username and there is no duplicated username in your >>>>> auth_user table." >>>>> >>>>> :) >>>>> >>>>> Richard >>>>> >>>>> >>>>> >>>>> >>>>> On Wed, Aug 7, 2013 at 1:48 PM, Richard Vézina >>>>> <[email protected]>wrote: >>>>> >>>>>> I would also add this : >>>>>> >>>>>> tmpvalidator = [IS_NOT_EMPTY(error_message=se**lf.messages.is_empty), >>>>>> IS_NOT_IN_DB(db, 'auth_user.username'), IS_NOT_EMAIL()] >>>>>> >>>>>> Since this line in the book : >>>>>> >>>>>> auth_table.username.requires = IS_NOT_IN_DB(db, auth_table.username) >>>>>> >>>>>> >>>>>> Doesn't seem to works and could be erase since who want a duplicated >>>>>> username in his auth_user?? >>>>>> >>>>>> >>>>>> Richard >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Wed, Aug 7, 2013 at 1:35 PM, Richard Vézina <[email protected] >>>>>> > wrote: >>>>>> >>>>>>> Better then that I think : >>>>>>> >>>>>>> In gluon/tools.py in Auth login() near line 2006 : >>>>>>> >>>>>>> Replace : >>>>>>> tmpvalidator = IS_NOT_EMPTY(error_message=**self.messages.is_empty) >>>>>>> >>>>>>> With : >>>>>>> if 'username' in table_user.fields or \ >>>>>>> not self.settings.login_email_**validate: >>>>>>> tmpvalidator = >>>>>>> [IS_NOT_EMPTY(error_message=**self.messages.is_empty), >>>>>>> IS_NOT_EMAIL()] >>>>>>> >>>>>>> Will require to add this new validator though : >>>>>>> >>>>>>> class IS_NOT_EMAIL: >>>>>>> def __init__(self, error_message='You can\'t use email as >>>>>>> username'): >>>>>>> self.e = error_message >>>>>>> def __call__(self, value): >>>>>>> if not IS_EMAIL()(value)[1]: >>>>>>> return (value, self.e) >>>>>>> return (value, None) >>>>>>> >>>>>>> What you think about that?? >>>>>>> >>>>>>> Richard >>>>>>> >>>>>>> >>>>>>> On Wed, Aug 7, 2013 at 1:23 PM, Richard Vézina < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> from gluon.validators import IS_EMAIL >>>>>>>> >>>>>>>> if ldap_mode == 'ad': >>>>>>>> # Microsoft Active Directory >>>>>>>> if IS_EMAIL()(username)[1] is not None: >>>>>>>> #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)) >>>>>>>> else: >>>>>>>> return False >>>>>>>> username_bare = username.split("@")[0] >>>>>>>> >>>>>>>> >>>>>>>> This prevent login to occure and new user to be inserted when email >>>>>>>> is used as username... however it not returning any advise to the >>>>>>>> user... I >>>>>>>> will try to figure out how to implement validation from ldap_auth and >>>>>>>> get >>>>>>>> back with a patch. >>>>>>>> >>>>>>>> Richard >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Wed, Aug 7, 2013 at 10:56 AM, Richard Vézina < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> 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_**PROTOC**OL_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_**f** >>>>>>>>>>>> irstname_attrib, >>>>>>>>>>>> user_lastname_attrib, >>>>>>>>>>>> user_mail_attrib]) >>>>>>>>>>>> result = con.search_ext_s( >>>>>>>>>>>> ldap_basedn, ldap.SCOPE_SUBTREE, >>>>>>>>>>>> "(&(sAMAccountName=%s)(%s))" % ( >>>>>>>>>>>> ldap.filter.escape_filter_** >>>>>>>>>>>> char**s(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/**grou** >>>>>>>>>>>>> ps/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 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] <javascript:>. >>> 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.

