from BTrees.OOBTree import OOBTree
from Products.CMFCore.permissions import ManagePortal, AddPortalMember
from Products.CMFCore.exceptions import AccessControl_Unauthorized
+from Products.CMFDefault.exceptions import EmailAddressInvalid
from Products.CMFCore.utils import getToolByName
from Products.CMFCore.utils import getUtilityByInterfaceName
+from Products.CMFDefault.utils import checkEmailAddress
from Products.GroupUserFolder.GroupsToolPermissions import ManageGroups
from Products.Plinn.utils import Message as _
+from Products.Plinn.utils import translate
+from Products.Plinn.utils import encodeQuopriEmail
+from Products.Plinn.utils import encodeMailHeader
from DateTime import DateTime
from types import TupleType, ListType
from uuid import uuid4
MODE_ANONYMOUS = 'anonymous'
security.declarePublic('MODE_ANONYMOUS')
+MODE_PASS_ANONYMOUS = 'pass_anonymous'
+security.declarePublic('MODE_PASS_ANONYMOUS')
+
MODE_MANAGER = 'manager'
security.declarePublic('MODE_MANAGER')
MODE_REVIEWED = 'reviewed'
security.declarePublic('MODE_REVIEWED')
-MODES = [MODE_ANONYMOUS, MODE_MANAGER, MODE_REVIEWED]
+MODES = [MODE_ANONYMOUS, MODE_PASS_ANONYMOUS, MODE_MANAGER, MODE_REVIEWED]
security.declarePublic('MODES')
DEFAULT_MEMBER_GROUP = 'members'
urlTool = getToolByName(self, 'portal_url')
portal = urlTool.getPortalObject()
- if mode in [MODE_ANONYMOUS, MODE_REVIEWED] :
+ if mode in [MODE_ANONYMOUS, MODE_PASS_ANONYMOUS, MODE_REVIEWED] :
portal.manage_permission(AddPortalMember, roles = ['Anonymous', 'Manager'], acquire=1)
elif mode == MODE_MANAGER :
portal.manage_permission(AddPortalMember, roles = ['Manager', 'UserManager'], acquire=0)
p=Permission(AddPortalMember, [], portal)
return p.getRoles()
- if mode in [MODE_ANONYMOUS, MODE_REVIEWED] :
+ if mode in [MODE_ANONYMOUS, MODE_PASS_ANONYMOUS, MODE_REVIEWED] :
if 'Anonymous' in rolesOfAddPortalMemberPerm() : return False
elif mode == MODE_MANAGER :
security.declareProtected(AddPortalMember, 'addMember')
def addMember(self, id, password, roles=(), groups=(DEFAULT_MEMBER_GROUP,), domains='', properties=None) :
""" Idem CMFCore but without default role """
- BaseRegistrationTool.addMember(self, id, password, roles=roles,
- domains=domains, properties=properties)
- if self.getMode() in [MODE_ANONYMOUS, MODE_MANAGER] :
+ if self.getMode() != MODE_REVIEWED :
gtool = getToolByName(self, 'portal_groups')
mtool = getToolByName(self, 'portal_membership')
utool = getToolByName(self, 'portal_url')
portal = utool.getPortalObject()
+
+ if self.getMode() == MODE_PASS_ANONYMOUS :
+ private_collections = portal.get('private_collections')
+ if not private_collections :
+ raise AccessControl_Unauthorized()
+ return
+ data = private_collections.data
+ lines = filter(None, [l.strip() for l in data.split('\n')])
+ assert len(lines) % 3 == 0
+ collecInfos = {}
+ for i in xrange(0, len(lines), 3) :
+ collecInfos[lines[i]] = {'pw' : lines[i+1],
+ 'path' : lines[i+2]}
+ if not (collecInfos.has_key(properties.get('collection_id')) and \
+ collecInfos[properties.get('collection_id')]['pw'] == properties.get('collection_password')) :
+ raise AccessControl_Unauthorized('Wrong primary credentials')
+ return
+
+
+ BaseRegistrationTool.addMember(self, id, password, roles=roles,
+ domains=domains, properties=properties)
+
isGrpManager = mtool.checkPermission(ManageGroups, portal) ## TODO : CMF2.1 compat
aclu = self.aq_inner.acl_users
aclu.changeUser(aclu.getGroupPrefix() +gid, roles=['Member', ])
g = gtool.getGroupById(gid)
g.addMember(id)
+ else :
+ BaseRegistrationTool.addMember(self, id, password, roles=roles,
+ domains=domains, properties=properties)
def afterAdd(self, member, id, password, properties):
""" add uuid / (userid, expiration) pair and return uuid """
self.clearExpiredPasswordResetRequests()
mtool = getUtilityByInterfaceName('Products.CMFCore.interfaces.IMembershipTool')
- if mtool.getMemberById(userid) :
+ member = mtool.getMemberById(userid)
+ if not member :
+ try :
+ checkEmailAddress(userid)
+ member = mtool.searchMembers('email', userid)
+ if member :
+ userid = member[0]['username']
+ member = mtool.getMemberById(userid)
+ except EmailAddressInvalid :
+ pass
+ if member :
uuid = str(uuid4())
+ while self._passwordResetRequests.has_key(uuid) :
+ uuid = str(uuid4())
self._passwordResetRequests[uuid] = (userid, DateTime() + 1)
- return uuid
+ utool = getUtilityByInterfaceName('Products.CMFCore.interfaces.IURLTool')
+ ptool = getUtilityByInterfaceName('Products.CMFCore.interfaces.IPropertiesTool')
+ # fuck : mailhost récupéré avec getUtilityByInterfaceName n'est pas correctement
+ # wrappé. Un « unrestrictedTraverse » ne marche pas.
+ # mailhost = getUtilityByInterfaceName('Products.MailHost.interfaces.IMailHost')
+ portal = utool.getPortalObject()
+ mailhost = portal.MailHost
+ sender = encodeQuopriEmail(ptool.getProperty('email_from_name'), ptool.getProperty('email_from_address'))
+ to = encodeQuopriEmail(member.getMemberFullName(nameBefore=0), member.getProperty('email'))
+ subject = translate(_('How to reset your password on the %s website')) % ptool.getProperty('title')
+ subject = encodeMailHeader(subject)
+ options = {'fullName' : member.getMemberFullName(nameBefore=0),
+ 'siteName' : ptool.getProperty('title'),
+ 'resetPasswordUrl' : '%s/password_reset_form/%s' % (utool(), uuid)}
+ body = self.password_reset_mail(options)
+ message = self.echange_mail_template(From=sender,
+ To=to,
+ Subject=subject,
+ ContentType = 'text/plain',
+ charset = 'UTF-8',
+ body=body)
+ mailhost.send(message)
+ return
+
+ return _('Unknown user name. Please retry.')
security.declarePrivate('clearExpiredPasswordResetRequests')
def clearExpiredPasswordResetRequests(self):
security.declarePublic('resetPassword')
- def resetPassword(self, userid, uuid, password, confirm) :
+ def resetPassword(self, uuid, password, confirm) :
record = self._passwordResetRequests.get(uuid)
if not record :
- return _('Invalid reset password request.')
-
- recUserid, expiration = record
-
- if recUserid != userid :
- return _('Invalid userid.')
+ return None, _('Invalid reset password request.')
+ userid, expiration = record
+ now = DateTime()
if expiration < now :
self.clearExpiredPasswordResetRequests()
- return _('Your reset password request has expired. You can ask a new one.')
+ return None, _('Your reset password request has expired. You can ask a new one.')
msg = self.testPasswordValidity(password, confirm=confirm)
if not msg : # None if everything ok. Err message otherwise.
if member :
member.setSecurityProfile(password=password)
del self._passwordResetRequests[uuid]
- return _('Password successfully resetted.')
+ return userid, _('Password successfully updated.')
else :
- return _('"%s" username not found.') % userid
+ return None, _('"%s" username not found.') % userid
InitializeClass(RegistrationTool)
\ No newline at end of file