1 # -*- coding: utf-8 -*-
2 #######################################################################################
3 # Plinn - http://plinn.org #
4 # Copyright (C) 2005-2007 Benoît PIN <benoit.pin@ensmp.fr> #
6 # This program is free software; you can redistribute it and/or #
7 # modify it under the terms of the GNU General Public License #
8 # as published by the Free Software Foundation; either version 2 #
9 # of the License, or (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program; if not, write to the Free Software #
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
19 #######################################################################################
20 """ Plinn registration tool: implements 3 modes to register members :
21 anonymous, manager, reviewed.
27 from Globals
import InitializeClass
, PersistentMapping
28 from Products
.PageTemplates
.PageTemplateFile
import PageTemplateFile
29 from Products
.CMFDefault
.RegistrationTool
import RegistrationTool
as BaseRegistrationTool
30 from AccessControl
import ClassSecurityInfo
, ModuleSecurityInfo
31 from AccessControl
.Permission
import Permission
32 from Products
.CMFCore
.permissions
import ManagePortal
, AddPortalMember
33 from Products
.CMFCore
.exceptions
import AccessControl_Unauthorized
34 from Products
.CMFCore
.utils
import getToolByName
35 from Products
.GroupUserFolder
.GroupsToolPermissions
import ManageGroups
36 from types
import TupleType
, ListType
38 security
= ModuleSecurityInfo('Products.Plinn.RegistrationTool')
39 MODE_ANONYMOUS
= 'anonymous'
40 security
.declarePublic('MODE_ANONYMOUS')
42 MODE_MANAGER
= 'manager'
43 security
.declarePublic('MODE_MANAGER')
45 MODE_REVIEWED
= 'reviewed'
46 security
.declarePublic('MODE_REVIEWED')
48 MODES
= [MODE_ANONYMOUS
, MODE_MANAGER
, MODE_REVIEWED
]
49 security
.declarePublic('MODES')
51 DEFAULT_MEMBER_GROUP
= 'members'
52 security
.declarePublic('DEFAULT_MEMBER_GROUP')
56 class RegistrationTool(BaseRegistrationTool
) :
58 """ Create and modify users by making calls to portal_membership.
61 meta_type
= "Plinn Registration Tool"
63 manage_options
= ({'label' : 'Registration mode', 'action' : 'manage_regmode'}, ) + \
64 BaseRegistrationTool
.manage_options
66 security
= ClassSecurityInfo()
68 security
.declareProtected( ManagePortal
, 'manage_regmode' )
69 manage_regmode
= PageTemplateFile('www/configureRegistrationTool', globals(),
70 __name__
='manage_regmode')
73 self
._mode
= MODE_ANONYMOUS
76 security
.declareProtected(ManagePortal
, 'configureTool')
77 def configureTool(self
, registration_mode
, chain
, REQUEST
=None) :
80 if registration_mode
not in MODES
:
81 raise ValueError, "Unknown mode: " + registration_mode
83 self
._mode
= registration_mode
84 self
._updatePortalRoleMappingForMode
(registration_mode
)
86 wtool
= getToolByName(self
, 'portal_workflow')
88 if registration_mode
== MODE_REVIEWED
:
89 if not hasattr(wtool
, '_chains_by_type') :
90 wtool
._chains
_by
_type
= PersistentMapping()
94 if chain
== '(Default)' :
95 try : del wtool
._chains
_by
_type
['Member Data']
96 except KeyError : pass
99 for wfid
in chain
.replace(',', ' ').split(' ') :
101 if not wtool
.getWorkflowById(wfid
) :
102 raise ValueError, '"%s" is not a workflow ID.' % wfid
105 wtool
._chains
_by
_type
['Member Data'] = tuple(wfids
)
106 self
._chain
= ', '.join(wfids
)
108 wtool
._chains
_by
_type
['Member Data'] = tuple()
111 REQUEST
.RESPONSE
.redirect(self
.absolute_url() + '/manage_regmode?manage_tabs_message=Saved changes.')
113 def _updatePortalRoleMappingForMode(self
, mode
) :
115 urlTool
= getToolByName(self
, 'portal_url')
116 portal
= urlTool
.getPortalObject()
118 if mode
in [MODE_ANONYMOUS
, MODE_REVIEWED
] :
119 portal
.manage_permission(AddPortalMember
, roles
= ['Anonymous', 'Manager'], acquire
=1)
120 elif mode
== MODE_MANAGER
:
121 portal
.manage_permission(AddPortalMember
, roles
= ['Manager', 'UserManager'], acquire
=0)
123 security
.declarePublic('getMode')
125 # """ return current mode """
128 security
.declarePublic('getWfId')
129 def getWfChain(self
) :
130 # """ return current workflow id """
133 security
.declarePublic('roleMappingMismatch')
134 def roleMappingMismatch(self
) :
135 # """ test if the role mapping is correct for the currrent mode """
138 urlTool
= getToolByName(self
, 'portal_url')
139 portal
= urlTool
.getPortalObject()
141 def rolesOfAddPortalMemberPerm() :
142 p
=Permission(AddPortalMember
, [], portal
)
145 if mode
in [MODE_ANONYMOUS
, MODE_REVIEWED
] :
146 if 'Anonymous' in rolesOfAddPortalMemberPerm() : return False
148 elif mode
== MODE_MANAGER
:
149 roles
= rolesOfAddPortalMemberPerm()
150 if 'Manager' in roles
or 'UserManager' in roles
and len(roles
) == 1 and type(roles
) == TupleType
:
155 security
.declareProtected(AddPortalMember
, 'addMember')
156 def addMember(self
, id, password
, roles
=(), groups
=(DEFAULT_MEMBER_GROUP
,), domains
='', properties
=None) :
157 """ Idem CMFCore but without default role """
158 BaseRegistrationTool
.addMember(self
, id, password
, roles
=roles
,
159 domains
=domains
, properties
=properties
)
161 if self
.getMode() in [MODE_ANONYMOUS
, MODE_MANAGER
] :
162 gtool
= getToolByName(self
, 'portal_groups')
163 mtool
= getToolByName(self
, 'portal_membership')
164 utool
= getToolByName(self
, 'portal_url')
165 portal
= utool
.getPortalObject()
166 isGrpManager
= mtool
.checkPermission(ManageGroups
, portal
) ## TODO : CMF2.1 compat
167 aclu
= self
.aq_inner
.acl_users
170 g
= gtool
.getGroupById(gid
)
171 if not isGrpManager
:
172 if gid
!= DEFAULT_MEMBER_GROUP
:
173 raise AccessControl_Unauthorized
, 'You are not allowed to join arbitrary group.'
177 aclu
.changeUser(aclu
.getGroupPrefix() +gid
, roles
=['Member', ])
178 g
= gtool
.getGroupById(gid
)
182 def afterAdd(self
, member
, id, password
, properties
):
183 """ notify member creation """
184 member
.notifyWorkflowCreated()
187 InitializeClass(RegistrationTool
)