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.
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
44 class MemberDataTool (BaseTool
):
45 """ This tool wraps user objects, making them act as Member objects.
48 meta_type
= 'Plinn Member Data Tool'
49 ## __implements__ = (IMemberDataTool, ActionProviderBase.__implements__)
51 security
= ClassSecurityInfo()
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')
61 # security.declarePrivate('wrapUser')
62 # def wrapUser(self, u):
64 # If possible, returns the Member object that corresponds
65 # to the given User object.
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)
76 # security.declarePrivate('wrapUser')
77 # def wrapUser(self, u):
79 # If possible, returns the Member object that corresponds
80 # to the given User object.
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):
91 # base = aq_base(self)
92 # m = MemberData(base, id)
94 # self._v_temps = {id:m}
95 # if hasattr(self, 'REQUEST'):
96 # # No REQUEST during tests.
97 # self.REQUEST._hold(CleanupTemp(self))
102 # # Return a wrapper with self as containment and
103 # # the user as context.
104 # return m.__of__(self).__of__(u)
107 def __bobo_traverse__(self
, REQUEST
, name
):
108 if hasattr(self
,name
):
109 return getattr(self
,name
)
111 if self
._members
.has_key(name
) :
112 return self
.wrapUser(self
.acl_users
.getUser(name
))
114 InitializeClass(MemberDataTool
)
117 class MemberAdapter(BaseMemberAdapter
):
119 """Member data adapter.
122 adapts(IUser
, IMemberDataTool
)
125 security
= ClassSecurityInfo()
127 def __init__(self
, user
, tool
):
128 super(MemberAdapter
, self
).__init
__(user
, tool
)
129 self
.id = self
.getId()
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
)
140 InitializeClass(MemberAdapter
)
143 class MemberData (BaseData
, DynamicType
, CMFCatalogAware
):
145 ## __implements__ = IMemberData
147 portal_type
= 'Member Data'
149 security
= ClassSecurityInfo()
151 security
.declareProtected(SetMemberPassword
, 'setMemberPassword')
152 def setMemberPassword(self
, password
, domains
=None) :
153 """ set member password """
155 registration
= getToolByName(self
, 'portal_registration', None)
157 failMessage
= registration
.testPasswordValidity(password
)
158 if failMessage
is not None:
159 raise 'Bad Request', failMessage
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
)
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"""
172 # This is really hackish. The Zope User API needs methods
173 # for performing these functions.
174 if password
is not None:
176 if roles
is not None:
178 if domains
is not None:
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
)
189 def getMemberSortableFormat(self
) :
190 """ Return a specific format of full name for alphabetical sorting """
191 return self
.getMemberFullName(nameBefore
= 1).lower()
194 ## overload default security declaration
195 security
.declareProtected(SetMemberProperties
, 'setMemberProperties')
196 def setMemberProperties(self
, mapping
):
197 BaseData
.setMemberProperties(self
, mapping
)
200 security
.declarePrivate('manage_beforeDelete')
201 def manage_beforeDelete(self
) :
202 """ uncatalog object """
205 def _setPortalTypeName(self
, pt
) :
206 """ Static Dynamic Type ;-) """
209 # user object interface
210 # overloads to make methods not publishable
212 def getUserName(self
):
213 return BaseData
.getUserName(self
)
216 return BaseData
.getId(self
)
219 return BaseData
.getRoles(self
)
221 def getRolesInContext(self
, object):
222 return BaseData
.getRolesInContext(self
, object)
224 def getDomains(self
):
225 return BaseData
.getDomains(self
)
227 def has_role(self
, roles
, object=None):
228 return BaseData
.has_role(self
, roles
, object=None)
232 InitializeClass(MemberData
)