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