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.

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!

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).

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

Reply via email to