Hedley Roos <[email protected]>
writes:

>> As I'm using betahaus.emaillogin[1] in my application I'm wanting to
>> override the generation of the username as this is a little confusing
>> for users as they expect to login with their email address but we're
>> still asking them to enter a username.
>
> Hi
>
> I haven't been paying attention to this thread but since Ross asked
> others for help I'll try.

Thank you, thank you!  :)

> Assuming you simply want to let users log in with their email
> addresses I can help. I do that exact thing with remember in a site,
> and I'll provide code. The key to everything is the correct use of
> getUserName instead of getId. There are a few methods in membrane and
> remember that need to be monkey patched. The monkey patching is *not*
> a hack - there are errors in these methods but I haven't had the time
> to jump in and fix them. Sorry Ross!

Hey, thanks for reporting them!  Can you summarize what the errors are
as you see them so your observations are at least documented here?
Thanks!

> If you subclass from member.py then you must override getUserName as
> such:
>
>     def getUserName(self):
>         """
>         Override
>         """
>         return self.getEmail()
>
> If you do not have your own class then you'll have to monkey member.py
> (I don't think that method is ZCA aware yet).

To be clear, I think the right thing to do here (and in almost any OO
situation) is to subclass rather than monkey-patch and membrane/remember
are explicitly oriented to be extended in this way.  In fact the
argument should probably be made that this is exactly the right level
for using class inheritance and *not* the ZCA.  IOW, please don't monkey
patch, or over-use the ZCA, use basic OO and subclass to create your own
member content type.  This is not, of course, a membrane/remember issue
or even a ZCA issue but simply a Python/OO best practice issue.

> I attach the patches. Individual methods have comments explaining what
> has been done. Roche Compaan had a big hand in this.
>
> NB:
> 1. You must update your membrane_tool catalog once you decide that
> users are going to use email address as login
> 2. You must of course enforce unique email addresses in a validator.
> 3. Leave the username field on all forms since that is going to be the
> id of the member object. Change the help text for the username to
> indicate that it is a nickname.
>
> Hope this helps
> Hedley
>
>
>
> from Products.PlonePAS.tools.memberdata import MemberDataTool \
>      as BaseTool
> from Products.CMFCore.utils import getToolByName
> from Products.membrane.tools.membrane import MembraneTool
> from Products.membrane.plugins.usermanager import MembraneUserManager
> from Products.remember.content.member import BaseMember
> from Products.remember.tools.memberdata import MemberDataContainer
> from Products.remember.config import ALLOWED_MEMBER_ID_PATTERN
>
> # Make call to getUserName instead of getId
> def wrapUser(self, user):
>         """
>         If possible, returns the Member object that corresponds to the
>         given User object.
>         """
>         mbtool = getToolByName(self, 'membrane_tool')
>         mem = mbtool.getUserAuthProvider(user.getUserName())
>         if mem is None:
>             return BaseTool.wrapUser(self, user)
>         return mem.__of__(self).__of__(user)
>
> # Make call to getId instead of getUserName
> def register(self):
>         """
>         perform any registration information necessary after a member is 
> registered
>         """
>         rtool = getToolByName(self, 'portal_registration')
>         site_props = getToolByName(self, 'portal_properties').site_properties
>         
>         # XXX unicode names break sending the email
>         unicode_name = self.getFullname()
>         self.setFullname(str(unicode_name))
>         if site_props.validate_email or self.getMail_me():
>             rtool.registeredNotify(self.getId())
>
>         self.setFullname(unicode_name)
>
> # Patch validate_id to getMemberById instead of mbtool.getUserAuthProvider
> # since the latter does lookups on login, not id
> def validate_id(self, id):
>     # we can't always trust the id argument, b/c the autogen'd
>     # id will be passed in if the reg form id field is blank
>     form = self.REQUEST.form
>     if form.has_key('id') and not form['id']:
>         return self.translate('Input is required but no input given.',
>                               default='You did not enter a login name.'),
>     elif self.id and id != self.id:
>         # we only validate if we're changing the id
>         mtool = getToolByName(self, 'portal_membership')
>         if mtool.getMemberById(id) is not None or \
>                not ALLOWED_MEMBER_ID_PATTERN.match(id) or \
>                id == 'Anonymous User':
>             msg = "The login name you selected is already " + \
>                   "in use or is not valid. Please choose another."
>             return self.translate(msg, default=msg)
>
>
> MemberDataContainer.wrapUser = wrapUser
> BaseMember.register = register
> BaseMember.validate_id = validate_id

>From this, it looks like the only thing that *might* need
monkey-patching would be the wrapUser method.  Am I missing anything?

I look forward to hearing more about the errors elsewhere that
necessitate monkey patching.

Ross



--
Archive: 
http://www.openplans.org/projects/remember/lists/remember/archive/2009/06/1244106704224
To unsubscribe send an email with subject "unsubscribe" to 
[email protected].  Please contact 
[email protected] for questions.

Reply via email to