+# -*- coding: utf-8 -*-
+#######################################################################################
+# Plinn - http://plinn.org #
+# Copyright (C) 2005-2007 Benoît PIN <benoit.pin@ensmp.fr> #
+# #
+# This program is free software; you can redistribute it and/or #
+# modify it under the terms of the GNU General Public License #
+# as published by the Free Software Foundation; either version 2 #
+# of the License, or (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the Free Software #
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
+#######################################################################################
+""" Workflow aware MemberData to provide reviewed member registration.
+
+
+
+"""
+from AccessControl.interfaces import IUser
+from Products.CMFCore.interfaces import IMemberDataTool
+from Globals import InitializeClass
+from Acquisition import aq_inner, aq_parent, aq_base
+from AccessControl import ClassSecurityInfo
+from OFS.SimpleItem import SimpleItem
+from Products.CMFCore.MemberDataTool import MemberDataTool as BaseTool
+from Products.CMFCore.MemberDataTool import MemberData as BaseData
+from Products.CMFCore.MemberDataTool import MemberAdapter as BaseMemberAdapter
+from zope.component import adapts
+from zope.component import getUtility
+from zope.interface import implements
+from Products.CMFCore.interfaces import IMember
+from Products.CMFCore.interfaces import IRegistrationTool
+# from Products.CMFCore.MemberDataTool import CleanupTemp
+#from Products.CMFCore.utils import getToolByName
+from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
+from Products.CMFCore.DynamicType import DynamicType
+from Products.CMFCore.exceptions import BadRequest
+from utils import formatFullName
+from permissions import SetMemberProperties, SetMemberPassword
+
+
+class MemberDataTool (BaseTool):
+ """ This tool wraps user objects, making them act as Member objects.
+ """
+
+ meta_type = 'Plinn Member Data Tool'
+## __implements__ = (IMemberDataTool, ActionProviderBase.__implements__)
+
+ security = ClassSecurityInfo()
+
+ def __init__(self):
+ BaseTool.__init__(self)
+ # Create the default properties.
+ self._setProperty('name', '', 'string')
+ self._setProperty('given_name', '', 'string')
+ self._setProperty('wysiwyg_editor', 'FCK', 'string')
+ self._setProperty('photo_width', 800, 'int')
+
+ def wrapUser(self, u) :
+ wu = super(MemberDataTool, self).wrapUser(u)
+ return wu.__of__(self).__of__(u)
+
+
+ def __bobo_traverse__(self, REQUEST, name):
+ if hasattr(self,name):
+ return getattr(self,name)
+ else:
+ if self._members.has_key(name) :
+ return self.wrapUser(self.acl_users.getUser(name))
+
+InitializeClass(MemberDataTool)
+
+
+class MemberAdapter(BaseMemberAdapter, SimpleItem, DynamicType, CMFCatalogAware):
+
+ """Member data adapter.
+ """
+
+ adapts(IUser, IMemberDataTool)
+ implements(IMember)
+
+ portal_type = 'Member Data'
+
+ security = ClassSecurityInfo()
+
+ def __init__(self, user, tool):
+ super(MemberAdapter, self).__init__(user, tool)
+ self.id = self.getId()
+
+ security.declarePublic('getMemberFullName')
+ def getMemberFullName(self, nameBefore=1) :
+ """ Return the best full name representation """
+ memberName = self.getProperty('name', default='')
+ memberGivenName = self.getProperty('given_name', default='')
+ memberId = self.getId()
+ return formatFullName(memberName, memberGivenName, memberId, nameBefore=nameBefore)
+
+ def getMemberSortableFormat(self) :
+ """ Return a specific format of full name for alphabetical sorting """
+ return self.getMemberFullName(nameBefore = 1).lower()
+
+ # security overload
+ security.declareProtected(SetMemberProperties, 'setMemberProperties')
+ def setMemberProperties(self, mapping):
+ super(MemberAdapter, self).setMemberProperties(mapping)
+ self.reindexObject()
+
+ security.declareProtected(SetMemberPassword, 'setMemberPassword')
+ def setMemberPassword(self, password, domains=None) :
+ """ set member password """
+
+ registration = getUtility(IRegistrationTool)
+ failMessage = registration.testPasswordValidity(password)
+ if failMessage is not None :
+ raise BadRequest(failMessage)
+
+ self.setSecurityProfile(password=password, domains=domains)
+
+ security.declarePrivate('setSecurityProfile')
+ def setSecurityProfile(self, password=None, roles=None, domains=None):
+ """Set the user's basic security profile"""
+ u = self.getUser()
+ # This is really hackish. The Zope User API needs methods
+ # for performing these functions.
+ if password is not None:
+ u.setPassword(password)
+ if roles is not None:
+ u.setRoles(roles)
+ if domains is not None:
+ u.setDomains(domains)
+
+ security.declarePrivate('manage_beforeDelete')
+ def manage_beforeDelete(self) :
+ """ uncatalog object """
+ self.unindexObject()
+
+ def _setPortalTypeName(self, pt) :
+ """ Static Dynamic Type ;-) """
+ pass
+
+ # user object interface
+ # overloads to make methods not publishable
+
+ def getUserName(self):
+ return super(MemberAdapter, self).getUserName()
+
+ def getId(self):
+ return super(MemberAdapter, self).getId()
+
+ def getRoles(self):
+ return self._user.aq_inner.getRoles()
+ # return super(MemberAdapter, self).getRoles()
+
+ def getRolesInContext(self, object):
+ return super(MemberAdapter, self).getRolesInContext(object)
+
+ def getDomains(self):
+ return super(MemberAdapter, self).getDomains()
+
+ def has_role(self, roles, object=None):
+ return super(MemberAdapter, self).has_role(roles, object=None)
+
+InitializeClass(MemberAdapter)
+
+
+class MemberData (BaseData, DynamicType, CMFCatalogAware):
+
+## __implements__ = IMemberData
+
+ portal_type = 'Member Data'
+
+ security = ClassSecurityInfo()
+# migré
+# security.declareProtected(SetMemberPassword, 'setMemberPassword')
+# def setMemberPassword(self, password, domains=None) :
+# """ set member password """
+#
+# registration = getToolByName(self, 'portal_registration', None)
+# if registration:
+# failMessage = registration.testPasswordValidity(password)
+# if failMessage is not None:
+# raise 'Bad Request', failMessage
+#
+# user_folder = self.acl_users
+# self.setSecurityProfile(password=password, domains=domains)
+# if user_folder.meta_type == 'Group User Folder' :
+# self.changePassword(password)
+
+
+#migré
+ #XXX restore the previous implementation for GRUF 2 I'll remove that later...
+# security.declarePrivate('setSecurityProfile')
+# def setSecurityProfile(self, password=None, roles=None, domains=None):
+# """Set the user's basic security profile"""
+# u = self.getUser()
+# # This is really hackish. The Zope User API needs methods
+# # for performing these functions.
+# if password is not None:
+# u.__ = password
+# if roles is not None:
+# u.roles = roles
+# if domains is not None:
+# u.domains = domains
+
+# migré
+# def getMemberFullName(self, nameBefore=1) :
+# """ Return the best full name representation """
+# memberName = self.getProperty('name', default='')
+# memberGivenName = self.getProperty('given_name', default='')
+# memberId = self.getProperty('id', default='')
+# return formatFullName(memberName, memberGivenName, memberId, nameBefore=nameBefore)
+
+# migré
+# def getMemberSortableFormat(self) :
+# """ Return a specific format of full name for alphabetical sorting """
+# return self.getMemberFullName(nameBefore = 1).lower()
+
+
+# migré
+# ## overload default security declaration
+# security.declareProtected(SetMemberProperties, 'setMemberProperties')
+# def setMemberProperties(self, mapping):
+# BaseData.setMemberProperties(self, mapping)
+# self.reindexObject()
+
+# migré
+# security.declarePrivate('manage_beforeDelete')
+# def manage_beforeDelete(self) :
+# """ uncatalog object """
+# self.unindexObject()
+
+# migré
+# def _setPortalTypeName(self, pt) :
+# """ Static Dynamic Type ;-) """
+# pass
+
+# migré
+# # user object interface
+# # overloads to make methods not publishable
+#
+# def getUserName(self):
+# return BaseData.getUserName(self)
+#
+# def getId(self):
+# return BaseData.getId(self)
+#
+# def getRoles(self):
+# return BaseData.getRoles(self)
+#
+# def getRolesInContext(self, object):
+# return BaseData.getRolesInContext(self, object)
+#
+# def getDomains(self):
+# return BaseData.getDomains(self)
+#
+# def has_role(self, roles, object=None):
+# return BaseData.has_role(self, roles, object=None)
+
+
+
+InitializeClass(MemberData)