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 """ Workflow aware MemberData to provide reviewed member registration.
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
39 class MemberDataTool (BaseTool
):
40 """ This tool wraps user objects, making them act as Member objects.
43 meta_type
= 'Plinn Member Data Tool'
44 ## __implements__ = (IMemberDataTool, ActionProviderBase.__implements__)
46 security
= ClassSecurityInfo()
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')
56 security
.declarePrivate('wrapUser')
57 def wrapUser(self
, u
):
59 If possible, returns the Member object that corresponds
60 to the given User object.
63 members
= self
._members
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
)
71 # security.declarePrivate('wrapUser')
72 # def wrapUser(self, u):
74 # If possible, returns the Member object that corresponds
75 # to the given User object.
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):
86 # base = aq_base(self)
87 # m = MemberData(base, id)
89 # self._v_temps = {id:m}
90 # if hasattr(self, 'REQUEST'):
91 # # No REQUEST during tests.
92 # self.REQUEST._hold(CleanupTemp(self))
97 # # Return a wrapper with self as containment and
98 # # the user as context.
99 # return m.__of__(self).__of__(u)
102 def __bobo_traverse__(self
, REQUEST
, name
):
103 if hasattr(self
,name
):
104 return getattr(self
,name
)
106 if self
._members
.has_key(name
) :
107 return self
.wrapUser(self
.acl_users
.getUser(name
))
109 InitializeClass(MemberDataTool
)
112 class MemberData (BaseData
, DynamicType
, CMFCatalogAware
):
114 ## __implements__ = IMemberData
116 portal_type
= 'Member Data'
118 security
= ClassSecurityInfo()
120 security
.declareProtected(SetMemberPassword
, 'setMemberPassword')
121 def setMemberPassword(self
, password
, domains
=None) :
122 """ set member password """
124 registration
= getToolByName(self
, 'portal_registration', None)
126 failMessage
= registration
.testPasswordValidity(password
)
127 if failMessage
is not None:
128 raise 'Bad Request', failMessage
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
)
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"""
141 # This is really hackish. The Zope User API needs methods
142 # for performing these functions.
143 if password
is not None:
145 if roles
is not None:
147 if domains
is not None:
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
)
158 def getMemberSortableFormat(self
) :
159 """ Return a specific format of full name for alphabetical sorting """
160 return self
.getMemberFullName(nameBefore
= 1).lower()
163 ## overload default security declaration
164 security
.declareProtected(SetMemberProperties
, 'setMemberProperties')
165 def setMemberProperties(self
, mapping
):
166 BaseData
.setMemberProperties(self
, mapping
)
169 security
.declarePrivate('manage_beforeDelete')
170 def manage_beforeDelete(self
) :
171 """ uncatalog object """
174 def _setPortalTypeName(self
, pt
) :
175 """ Static Dynamic Type ;-) """
178 # user object interface
179 # overloads to make methods not publishable
181 def getUserName(self
):
182 return BaseData
.getUserName(self
)
185 return BaseData
.getId(self
)
188 return BaseData
.getRoles(self
)
190 def getRolesInContext(self
, object):
191 return BaseData
.getRolesInContext(self
, object)
193 def getDomains(self
):
194 return BaseData
.getDomains(self
)
196 def has_role(self
, roles
, object=None):
197 return BaseData
.has_role(self
, roles
, object=None)
201 InitializeClass(MemberData
)