i agree

On Thursday, 22 August 2013 11:16:20 UTC-5, Richard wrote:
>
> Hello,
>
> I just push these change in production, then face some exception... Some 
> of our users have email as username some don't... So the fix I found is not 
> the proper solution... I think we will have to improve ldap_auth logic to 
> get out of the mud with this... I will look throught this a bit more see 
> what I can come up with. What ldap_auth should do is to check user 
> credentials, if the user log with email but he already have a user with the 
> same username and password it should use this user instead of creating a 
> new user with email as username and missing first_name and many other field 
> empty...
>
> Richard
>
>
> On Wed, Aug 21, 2013 at 9:34 AM, Richard Vézina 
> <[email protected]<javascript:>
> > wrote:
>
>> No problem, thank for the follow...
>>
>> Richard
>>
>>
>> On Wed, Aug 21, 2013 at 4:51 AM, Massimo Di Pierro 
>> <[email protected]<javascript:>
>> > wrote:
>>
>>> 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]
>>>> > 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]> 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=**T**rue)" 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_**m**
>>>>>>>> essage=T(auth.messages.is_**empt**y)),
>>>>>>>>                     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=**sel**
>>>>>>>>>> f.messages.is_empty)
>>>>>>>>>>
>>>>>>>>>> With :
>>>>>>>>>>         if 'username' in table_user.fields or \
>>>>>>>>>>                 not self.settings.login_email_**vali**date:
>>>>>>>>>>             tmpvalidator = 
>>>>>>>>>> [IS_NOT_EMPTY(error_message=**se**lf.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/**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.

Reply via email to