Bugfix webdav. CF bug #1071431 sur launchpad.net.
[Plinn.git] / RegistrationTool.py
1 # -*- coding: utf-8 -*-
2 #######################################################################################
3 # Plinn - http://plinn.org #
4 # Copyright (C) 2005-2007 BenoƮt PIN <benoit.pin@ensmp.fr> #
5 # #
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. #
10 # #
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. #
15 # #
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.
22
23
24
25 """
26
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
37
38 security = ModuleSecurityInfo('Products.Plinn.RegistrationTool')
39 MODE_ANONYMOUS = 'anonymous'
40 security.declarePublic('MODE_ANONYMOUS')
41
42 MODE_MANAGER = 'manager'
43 security.declarePublic('MODE_MANAGER')
44
45 MODE_REVIEWED = 'reviewed'
46 security.declarePublic('MODE_REVIEWED')
47
48 MODES = [MODE_ANONYMOUS, MODE_MANAGER, MODE_REVIEWED]
49 security.declarePublic('MODES')
50
51 DEFAULT_MEMBER_GROUP = 'members'
52 security.declarePublic('DEFAULT_MEMBER_GROUP')
53
54
55
56 class RegistrationTool(BaseRegistrationTool) :
57
58 """ Create and modify users by making calls to portal_membership.
59 """
60
61 meta_type = "Plinn Registration Tool"
62
63 manage_options = ({'label' : 'Registration mode', 'action' : 'manage_regmode'}, ) + \
64 BaseRegistrationTool.manage_options
65
66 security = ClassSecurityInfo()
67
68 security.declareProtected( ManagePortal, 'manage_regmode' )
69 manage_regmode = PageTemplateFile('www/configureRegistrationTool', globals(),
70 __name__='manage_regmode')
71
72 def __init__(self) :
73 self._mode = MODE_ANONYMOUS
74 self._chain = ''
75
76 security.declareProtected(ManagePortal, 'configureTool')
77 def configureTool(self, registration_mode, chain, REQUEST=None) :
78 """ """
79
80 if registration_mode not in MODES :
81 raise ValueError, "Unknown mode: " + registration_mode
82 else :
83 self._mode = registration_mode
84 self._updatePortalRoleMappingForMode(registration_mode)
85
86 wtool = getToolByName(self, 'portal_workflow')
87
88 if registration_mode == MODE_REVIEWED :
89 if not hasattr(wtool, '_chains_by_type') :
90 wtool._chains_by_type = PersistentMapping()
91 wfids = []
92 chain = chain.strip()
93
94 if chain == '(Default)' :
95 try : del wtool._chains_by_type['Member Data']
96 except KeyError : pass
97 self._chain = chain
98 else :
99 for wfid in chain.replace(',', ' ').split(' ') :
100 if wfid :
101 if not wtool.getWorkflowById(wfid) :
102 raise ValueError, '"%s" is not a workflow ID.' % wfid
103 wfids.append(wfid)
104
105 wtool._chains_by_type['Member Data'] = tuple(wfids)
106 self._chain = ', '.join(wfids)
107 else :
108 wtool._chains_by_type['Member Data'] = tuple()
109
110 if REQUEST :
111 REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_regmode?manage_tabs_message=Saved changes.')
112
113 def _updatePortalRoleMappingForMode(self, mode) :
114
115 urlTool = getToolByName(self, 'portal_url')
116 portal = urlTool.getPortalObject()
117
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)
122
123 security.declarePublic('getMode')
124 def getMode(self) :
125 # """ return current mode """
126 return self._mode[:]
127
128 security.declarePublic('getWfId')
129 def getWfChain(self) :
130 # """ return current workflow id """
131 return self._chain
132
133 security.declarePublic('roleMappingMismatch')
134 def roleMappingMismatch(self) :
135 # """ test if the role mapping is correct for the currrent mode """
136
137 mode = self._mode
138 urlTool = getToolByName(self, 'portal_url')
139 portal = urlTool.getPortalObject()
140
141 def rolesOfAddPortalMemberPerm() :
142 p=Permission(AddPortalMember, [], portal)
143 return p.getRoles()
144
145 if mode in [MODE_ANONYMOUS, MODE_REVIEWED] :
146 if 'Anonymous' in rolesOfAddPortalMemberPerm() : return False
147
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 :
151 return False
152
153 return True
154
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)
160
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
168
169 for gid in groups:
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.'
174
175 if g is None :
176 gtool.addGroup(gid)
177 aclu.changeUser(aclu.getGroupPrefix() +gid, roles=['Member', ])
178 g = gtool.getGroupById(gid)
179 g.addMember(id)
180
181
182 def afterAdd(self, member, id, password, properties):
183 """ notify member creation """
184 member.notifyWorkflowCreated()
185 member.indexObject()
186
187 InitializeClass(RegistrationTool)