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=self.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_**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.


Reply via email to