Re: [Archetypes-users] membrane user email property
from
"Richard Amerman"
on Dec 20, 2006 04:09 AM
Thanks Rob!
See below:
On 12/19/06, Rob Miller <ra@...> wrote:
>
> Richard Amerman wrote:
> > I have a membrane based user that is working great except for three
> > items (that I know of):
>
> you'll probably get a better response on the remember list:
>
> http://openplans.org/projects/remember/lists/remember
>
> i'm planning on renaming the list to "plone-membership" or something like
> that
> soon, because i'd like that list to be about membrane, remember, b-org, or
> even just general Plone member management questions, not just about
> remember.
Sounds great! +1
> Both the email and full name are not showing up in the member (not
> > showing up in the prefs_users_overview listing for example)
> >
> > The reset password check box is grayed out.
> >
> > Any pointers would be great!
>
> it'd probably help if you could provide links to your code in an SVN repo,
> or
> at least include your class and schema definitions.
The user type (Contributor) is below:
also, is it just on the Plone control panel screens where you're having the
> problems? or are the fields also not showing up / not working correctly
> on
> the member object(s) edit forms?
The main place is in the control panel where the email is blank, the full
name is not displayed, and the password reset button is grayed out.
I need to add some more unit tests specifically for this kind of thing. I
will be looking into that in the morning.
Not very pretty, combo of AGX and had coding.
====================================================================
from AccessControl import ClassSecurityInfo
from Products.Archetypes.atapi import *
import zope
from Products.HealthResourceConnection.interfaces.IContributorModifiedEventimport
IContributorModifiedEvent
from Products.HealthResourceConnection.config import *
# additional imports from tagged value 'import'
from Products.membrane.interfaces import IUserAuthProvider
from Products.membrane.interfaces import IPropertiesProvider
from Products.membrane.interfaces import IUserChanger
from Products.membrane.interfaces import IGroupsProvider
from Products.membrane.interfaces import IGroupAwareRolesProvider
from Products.membrane.interfaces import IUserAuthentication
from Products.membrane.interfaces import IMembraneUserManagement
from zope.app.annotation.interfaces import IAttributeAnnotatable,
IAnnotations
from Products.HealthResourceConnection import Permissions
from zope.interface import implements
from sha import sha
from Products.membrane.interfaces import IUserRelated
from Acquisition import aq_inner, aq_parent
from Products.CMFCore.utils import getToolByName
from zope.event import notify
from AccessControl import ClassSecurityInfo
from Products.Archetypes.atapi import *
from Products.membrane.interfaces import IUserRoles
##code-section module-header #fill in your manual code here
##/code-section module-header
schema = Schema((
StringField(
name='id',
widget=StringWidget(
label="User Name",
descriiption="Username for this Contributor",
label_msgid='HealthResourceConnection_label_id',
i18n_domain='HealthResourceConnection',
),
languageIndependent=True,
write_permission=Permissions.ManageUsers,
required=True
),
StringField(
name='password',
required=False,
widget=PasswordWidget
(
label="Password",
description="Password for this Contributor. Leave this blank if
you don't want ot change the password.",
label_msgid='HealthResourceConnection_label_password',
description_msgid='HealthResourceConnection_help_password',
i18n_domain='HealthResourceConnection',
),
languageIndependent=True,
mode="w",
write_permission=Permissions.SetPassword
),
StringField(
name='confirmPassword',
widget=PasswordWidget
(
label='Confirmpassword',
label_msgid='HealthResourceConnection_label_confirmPassword',
i18n_domain='HealthResourceConnection',
),
required=False,
mode="w"
),
LinesField(
name='roles_',
mutator="setRoles",
widget=MultiSelectionWidget(
label="Roles",
description="The roles this Contributor will have",
label_msgid='HealthResourceConnection_label_roles_',
description_msgid='HealthResourceConnection_help_roles_',
i18n_domain='HealthResourceConnection',
),
languageIndependent=True,
multiValued=1,
vocabulary=["Member","PartnerAdmin"],
edit_accessor="getRawRoles",
accessor="getRoles",
write_permission=Permissions.ManageUsers
),
StringField(
name='title',
widget=StringWidget(
label='Title',
label_msgid='HealthResourceConnection_label_title',
i18n_domain='HealthResourceConnection',
)
),
StringField(
name='email',
widget=StringWidget(
label='Email',
label_msgid='HealthResourceConnection_label_email',
i18n_domain='HealthResourceConnection',
),
required=True,
validators=("python:('isEmail'", ')')
),
StringField(
name='first_name',
widget=StringWidget(
label='First_name',
label_msgid='HealthResourceConnection_label_first_name',
i18n_domain='HealthResourceConnection',
)
),
StringField(
name='last_name',
widget=StringWidget(
label='Last_name',
label_msgid='HealthResourceConnection_label_last_name',
i18n_domain='HealthResourceConnection',
)
),
),
)
##code-section after-local-schema #fill in your manual code here
##/code-section after-local-schema
Contributor_schema = BaseFolderSchema.copy() + \
schema.copy()
##code-section after-schema #fill in your manual code here
class ContributorModifiedEvent(object):
"""Event to notify that Contributors have been saved.
"""
implements(IContributorModifiedEvent)
def __init__(self, context):
self.context = context
##/code-section after-schema
class Contributor(BaseFolder):
"""
"""
security = ClassSecurityInfo()
__implements__ = (getattr(BaseFolder,'__implements__',()),)
# zope3 interfaces
zope.interface.implements(IPropertiesProvider, IUserAuthProvider,
IUserChanger, IGroupsProvider, IGroupAwareRolesProvider,
IUserAuthentication, IAttributeAnnotatable, IUserRelated, IUserRoles,
IMembraneUserManagement, IContributorModifiedEvent)
# This name appears in the 'add' box
archetype_name = 'Contributor'
meta_type = 'Contributor'
portal_type = 'Contributor'
allowed_content_types = ['Address']
filter_content_types = 1
global_allow = 0
content_icon = 'contributor.gif'
immediate_view = 'base_view'
default_view = 'base_view'
suppl_views = ()
typeDescription = "Contributor"
typeDescMsgId = 'description_edit_contributor'
_at_rename_after_creation = True
schema = Contributor_schema
##code-section class-header #fill in your manual code here
##/code-section class-header
# Methods
security.declarePrivate('at_post_create_script')
def at_post_create_script(self):
"""Notify that the Contributor has been saved.
"""
notify(ContributorModifiedEvent(self))
security.declarePrivate('at_post_edit_script')
def at_post_edit_script(self):
"""Notify that the Contributor has been saved.
"""
notify(ContributorModifiedEvent(self))
security.declareProtected(Permissions.SetPassword, 'setPassword')
def setPassword(self,value):
if value:
annotations = IAnnotations(self)
annotations[PASSWORD_KEY] = sha(value).digest()
security.declareProtected(Permissions.SetPassword, 'setConfirmPassword')
def setConfirmPassword(self,value):
# Do nothing - this value is used for verification only
pass
security.declarePrivate('validate_id')
def validate_id(self, value):
"""Ensure the id is unique, also among groups globally
"""
if value != self.getId():
parent = aq_parent(aq_inner(self))
if value in parent.objectIds():
return "An object with id '%s' already exists in this
folder" % value
membership = getToolByName(self, 'portal_membership')
if membership.getMemberById(value) is not None:
return "A user with id '%s' already exists in the portal" %
value
security.declarePrivate('post_validate')
def post_validate(self,REQUEST,errors):
form = REQUEST.form
if form.has_key('password') or form.has_key('confirmPassword'):
password = form.get('password', None)
confirm = form.get('confirmPassword', None)
annotations = IAnnotations(self)
passwordDigest = annotations.get(PASSWORD_KEY, None)
if not passwordDigest:
if not password and not confirm:
errors['password'] = u'An initial password must be set'
return
if password or confirm:
if password != confirm:
errors['password'] = errors['confirmPassword'] =
u'Passwords do not match'
security.declarePublic('getUserName')
def getUserName(self):
"""
"""
return self.getId()
security.declarePrivate('verifyCredentials')
def verifyCredentials(self,credentials):
"""
"""
login = credentials.get('login', None)
password = credentials.get('password', None)
if login is None or password is None:
return False
digest = sha(password).digest()
annotations = IAnnotations(self)
passwordDigest = annotations.get(PASSWORD_KEY, None)
return (login == self.getUserName() and digest == passwordDigest)
security.declarePrivate('doAddUser')
def doAddUser(self,login,password):
"""
This can't be done unless we have a canonical place to store users
some implementations may wish to define one and implement this.
"""
raise NotImplementedError
security.declarePrivate('doChangeUser')
def doChangeUser(self,login,password,**kw):
"""
"""
self.setPassword(password)
if kw:
self.edit(**kw)
security.declarePrivate('doDeleteUser')
def doDeleteUser(self,login):
"""
"""
parent = aq_parent(aq_inner(self))
parent.manage_delObjects([self.getId()])
security.declarePublic('fullname')
def fullname(self):
"""
"""
fulname = self.getFirst_name() + self.getLast_name()
return fulname
security.declarePublic('id')
def id(self):
"""
"""
return self.getId()
security.declarePublic('getUserId')
def getUserId(self):
"""
"""
return self.getId()
security.declarePublic('getPartners')
def getPartners(self):
"""
Get a list of Partners that this Contributor belongs to
"""
brlist = self.getBackReferenceImpl()
partners = []
for p in brlist:
partners.append(p.getSourceObject())
return partners
registerType(Contributor, PROJECTNAME)