Copie depuis le svn du cri à l'état :
[Plinn.git] / MemberDataTool.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 """ Workflow aware MemberData to provide reviewed member registration.
21
22 $Id: MemberDataTool.py 1316 2008-07-29 15:37:23Z pin $
23 $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/MemberDataTool.py $
24 """
25
26 from Globals import InitializeClass
27 from Acquisition import aq_inner, aq_parent, aq_base
28 from AccessControl import ClassSecurityInfo
29 from Products.CMFCore.MemberDataTool import MemberDataTool as BaseTool
30 from Products.CMFCore.MemberDataTool import MemberData as BaseData
31 from Products.CMFCore.MemberDataTool import CleanupTemp
32 from Products.CMFCore.utils import getToolByName
33 from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
34 from Products.CMFCore.DynamicType import DynamicType
35 from utils import formatFullName
36 from permissions import SetMemberProperties, SetMemberPassword
37
38
39 class MemberDataTool (BaseTool):
40 """ This tool wraps user objects, making them act as Member objects.
41 """
42
43 meta_type = 'Plinn Member Data Tool'
44 ## __implements__ = (IMemberDataTool, ActionProviderBase.__implements__)
45
46 security = ClassSecurityInfo()
47
48 def __init__(self):
49 BaseTool.__init__(self)
50 # Create the default properties.
51 self._setProperty('name', '', 'string')
52 self._setProperty('given_name', '', 'string')
53 self._setProperty('wysiwyg_editor', 'FCK', 'string')
54 self._setProperty('photo_width', 800, 'int')
55
56 security.declarePrivate('wrapUser')
57 def wrapUser(self, u):
58 '''
59 If possible, returns the Member object that corresponds
60 to the given User object.
61 '''
62 id = u.getId()
63 members = self._members
64 if not id in members:
65 base = aq_base(self)
66 members[id] = MemberData(base, id)
67 # Return a wrapper with self as containment and
68 # the user as context.
69 return members[id].__of__(self).__of__(u)
70
71 # security.declarePrivate('wrapUser')
72 # def wrapUser(self, u):
73 # """
74 # If possible, returns the Member object that corresponds
75 # to the given User object.
76 # """
77 # id = u.getId()
78 # members = self._members
79 # if not members.has_key(id):
80 # # Get a temporary member that might be
81 # # registered later via registerMemberData().
82 # temps = self._v_temps
83 # if temps is not None and temps.has_key(id):
84 # m = temps[id]
85 # else:
86 # base = aq_base(self)
87 # m = MemberData(base, id)
88 # if temps is None:
89 # self._v_temps = {id:m}
90 # if hasattr(self, 'REQUEST'):
91 # # No REQUEST during tests.
92 # self.REQUEST._hold(CleanupTemp(self))
93 # else:
94 # temps[id] = m
95 # else:
96 # m = members[id]
97 # # Return a wrapper with self as containment and
98 # # the user as context.
99 # return m.__of__(self).__of__(u)
100
101
102 def __bobo_traverse__(self, REQUEST, name):
103 if hasattr(self,name):
104 return getattr(self,name)
105 else:
106 if self._members.has_key(name) :
107 return self.wrapUser(self.acl_users.getUser(name))
108
109 InitializeClass(MemberDataTool)
110
111
112 class MemberData (BaseData, DynamicType, CMFCatalogAware):
113
114 ## __implements__ = IMemberData
115
116 portal_type = 'Member Data'
117
118 security = ClassSecurityInfo()
119
120 security.declareProtected(SetMemberPassword, 'setMemberPassword')
121 def setMemberPassword(self, password, domains=None) :
122 """ set member password """
123
124 registration = getToolByName(self, 'portal_registration', None)
125 if registration:
126 failMessage = registration.testPasswordValidity(password)
127 if failMessage is not None:
128 raise 'Bad Request', failMessage
129
130 user_folder = self.acl_users
131 self.setSecurityProfile(password=password, domains=domains)
132 if user_folder.meta_type == 'Group User Folder' :
133 self.changePassword(password)
134
135
136 #XXX restore the previous implementation for GRUF 2 I'll remove that later...
137 security.declarePrivate('setSecurityProfile')
138 def setSecurityProfile(self, password=None, roles=None, domains=None):
139 """Set the user's basic security profile"""
140 u = self.getUser()
141 # This is really hackish. The Zope User API needs methods
142 # for performing these functions.
143 if password is not None:
144 u.__ = password
145 if roles is not None:
146 u.roles = roles
147 if domains is not None:
148 u.domains = domains
149
150
151 def getMemberFullName(self, nameBefore=1) :
152 """ Return the best full name representation """
153 memberName = self.getProperty('name', default='')
154 memberGivenName = self.getProperty('given_name', default='')
155 memberId = self.getProperty('id', default='')
156 return formatFullName(memberName, memberGivenName, memberId, nameBefore=nameBefore)
157
158 def getMemberSortableFormat(self) :
159 """ Return a specific format of full name for alphabetical sorting """
160 return self.getMemberFullName(nameBefore = 1).lower()
161
162
163 ## overload default security declaration
164 security.declareProtected(SetMemberProperties, 'setMemberProperties')
165 def setMemberProperties(self, mapping):
166 BaseData.setMemberProperties(self, mapping)
167 self.reindexObject()
168
169 security.declarePrivate('manage_beforeDelete')
170 def manage_beforeDelete(self) :
171 """ uncatalog object """
172 self.unindexObject()
173
174 def _setPortalTypeName(self, pt) :
175 """ Static Dynamic Type ;-) """
176 pass
177
178 # user object interface
179 # overloads to make methods not publishable
180
181 def getUserName(self):
182 return BaseData.getUserName(self)
183
184 def getId(self):
185 return BaseData.getId(self)
186
187 def getRoles(self):
188 return BaseData.getRoles(self)
189
190 def getRolesInContext(self, object):
191 return BaseData.getRolesInContext(self, object)
192
193 def getDomains(self):
194 return BaseData.getDomains(self)
195
196 def has_role(self, roles, object=None):
197 return BaseData.has_role(self, roles, object=None)
198
199
200
201 InitializeClass(MemberData)