X-Git-Url: https://scm.cri.ensmp.fr/git/Plinn.git/blobdiff_plain/3c4367d8e03450e9a73e61f4247145d2b6c86a33..959d888c17d1403d2eeecc19bc4b5e2c8d1debf6:/MembershipTool.py diff --git a/MembershipTool.py b/MembershipTool.py deleted file mode 100755 index 3b3da9a..0000000 --- a/MembershipTool.py +++ /dev/null @@ -1,431 +0,0 @@ -# -*- coding: utf-8 -*- -####################################################################################### -# Plinn - http://plinn.org # -# Copyright (C) 2005-2007 Benoît PIN # -# # -# 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. # -####################################################################################### -""" Plinn portal_membership - - - -""" - -from AccessControl import ClassSecurityInfo, getSecurityManager -from AccessControl.unauthorized import Unauthorized -from AccessControl.SpecialUsers import nobody -from AccessControl.Permission import Permission -from Acquisition import aq_base, aq_inner -from Globals import InitializeClass, MessageDialog -from Products.PageTemplates.PageTemplateFile import PageTemplateFile - -from Products.CMFDefault.MembershipTool import MembershipTool as BaseTool -from Products.CMFCore.permissions import View, ListPortalMembers, ManagePortal, SetOwnPassword, ChangePermissions -from permissions import RemoveMember, SetLocalRoles, CheckMemberPermission -from utils import _checkMemberPermission -from Products.CMFCore.utils import _checkPermission, _getAuthenticatedUser -from Products.CMFCore.utils import getUtilityByInterfaceName -from utils import formatFullName, translate -from Products.CMFDefault.utils import decode -from Products.CMFDefault.Document import addDocument - -from sets import Set -from types import TupleType - - -from time import time -from logging import getLogger -console = getLogger('Plinn.MembershipTool') - - -class MembershipTool( BaseTool ): - """ Implement 'portal_membership' interface using "stock" policies. - """ - - - meta_type = 'Plinn Membership Tool' - - manage_options=( ({ 'label' : 'Configuration' - , 'action' : 'manage_mapRoles' - },) + BaseTool.manage_options[1:]) - - security = ClassSecurityInfo() - - security.declareProtected(ManagePortal, 'manage_mapRoles') - manage_mapRoles = PageTemplateFile('www/configureMembershipTool', globals(), - __name__='manage_mapRoles') - - # - # 'portal_membership' interface methods - # - - # change security settings for inherited methods - security.declareProtected(ListPortalMembers, 'getMemberById') - - - memberareaPortalType = 'Huge Plinn Folder' - - -# security.declareProtected(SetOwnPassword, 'setPassword') -# def setPassword(self, password, domains=None): -# '''Allows the authenticated member to set his/her own password. -# ''' -# user_folder = self.__getPUS() -# if user_folder.meta_type == 'Group User Folder' : -# registration = getToolByName(self, 'portal_registration', None) -# if not self.isAnonymousUser(): -# member = self.getAuthenticatedMember() -# if registration: -# failMessage = registration.testPasswordValidity(password) -# if failMessage is not None: -# raise 'Bad Request', failMessage -# member.setSecurityProfile(password=password, domains=domains) -# member.changePassword(password) -# else: -# raise 'Bad Request', 'Not logged in.' -# -# else : -# BaseTool.setPassword(self, password, domains=None) - - - - security.declareProtected(ListPortalMembers, 'listMemberIds') - def listMemberIds(self): - '''Lists the ids of all members. This may eventually be - replaced with a set of methods for querying pieces of the - list rather than the entire list at once. - ''' - user_folder = self.__getPUS() - if user_folder.meta_type == 'Group User Folder' : - return user_folder.getPureUserNames() - else : - return [ x.getId() for x in user_folder.getUsers() ] - - - security.declareProtected(CheckMemberPermission, 'checkMemberPermission') - def checkMemberPermission(self, userid, permissionName, object, subobjectName=None): - ''' - Checks whether the current user has the given permission on - the given object or subobject. - ''' - if subobjectName is not None: - object = getattr(object, subobjectName) - - return _checkMemberPermission(userid, permissionName, object) - - security.declareProtected(ListPortalMembers, 'listMembers') - def listMembers(self): - '''Gets the list of all members. - ''' - user_folder = self.__getPUS() - if user_folder.meta_type == 'Group User Folder' : - return map(self.wrapUser, user_folder.getPureUsers()) - else : - return map(self.wrapUser, user_folder.getUsers()) - - - security.declareProtected(View, 'getCandidateLocalRoles') - def getCandidateLocalRoles(self, obj) : - """ What local roles can I assign? - """ - member = self.getAuthenticatedMember() - valid_roles = obj.valid_roles() - if 'Manager' in member.getRoles(): - local_roles = [r for r in valid_roles if r != 'Anonymous'] - else: - sm = getSecurityManager() - allPermissions = self.ac_inherited_permissions(1) - - # construct a dictionary of permissions indexed by role - # and get permissions of user in obj context - memberPermissions = Set() - rolesMappings = {} - for role in valid_roles : - rolesMappings[role] = Set() - - for p in allPermissions: - name, value = p[:2] - - p=Permission(name,value,obj) - rolesOfPerm = p.getRoles() - - for role in rolesOfPerm : - try : rolesMappings[role].add(name) - except KeyError : - trName = p._p - if hasattr(obj, trName): - l = list(getattr(obj, trName)) - l.remove(role) - setattr(obj, trName, tuple(l)) - msg = '%s role has been removed for %s permission on %s ' % (role, name, obj.absolute_url()) - #LOG('portal_membership', WARNING, msg) - - parent = obj.aq_inner.aq_parent - while type(rolesOfPerm) != TupleType : - p=Permission(name, value, parent) - rolesOfPerm = p.getRoles() - for role in rolesOfPerm : - try : rolesMappings[role].add(name) - except KeyError : pass - try : parent = parent.aq_inner.aq_parent - except AttributeError : break - - - if sm.checkPermission(name, obj) : - memberPermissions.add(name) - - local_roles = [] - for role in valid_roles : - if rolesMappings[role] and rolesMappings[role].issubset(memberPermissions) : - local_roles.append(role) - - local_roles = [ role for role in local_roles if role not in ('Shared', 'Authenticated', 'Member', 'Anonymous') ] - local_roles.sort() - return tuple(local_roles) - - - security.declareProtected(View, 'setLocalRoles') - def setLocalRoles( self, obj, member_ids, role, remove=0, reindex=1 ): - """ Set local roles on an item """ - if role not in self.getCandidateLocalRoles(obj) : - raise Unauthorized, "You are not allowed to manage %s role" % role - - if self.checkPermission(SetLocalRoles, obj) : - if not remove : - for member_id in member_ids : - # current roles for user id in obj - roles = list(obj.get_local_roles_for_userid( userid=member_id )) - if role not in roles : - roles.append(role) - obj.manage_setLocalRoles( member_id, roles) - else : - for member_id in member_ids : - # current roles for user id in obj - roles = list(obj.get_local_roles_for_userid( userid=member_id )) - try : roles.remove(role) - except ValueError : pass - else : - if len(roles) >= 1 : - obj.manage_setLocalRoles( member_id, roles) - else : - obj.manage_delLocalRoles( userids=[member_id] ) - - else : - raise Unauthorized - - if reindex: - # It is assumed that all objects have the method - # reindexObjectSecurity, which is in CMFCatalogAware and - # thus PortalContent and PortalFolder. - obj.reindexObjectSecurity() - - - security.declarePublic('getMemberFullNameById') - def getMemberFullNameById(self, userid, nameBefore = 1) : - """ Return the best formated representation of user fullname. """ - - memberFullName = '' - if userid and userid != 'No owner' : - # No owner is a possible value returned by DefaultDublinCoreImpl.Creator - member = self.getMemberById(userid) - if not member : - return userid - memberFullName = member.getMemberFullName(nameBefore=nameBefore) - - return memberFullName - - security.declareProtected(ListPortalMembers, 'getMembers') - def getMembers(self, users) : - """ Return wraped users """ - members = [] - for user in users : - members.append(self.getMemberById(user)) - - members = filter(None, members) - members.sort( lambda m0, m1 : cmp(m0.getMemberSortableFormat(), m1.getMemberSortableFormat()) ) - return members - - - security.declareProtected(ListPortalMembers, 'getOtherMembers') - def getOtherMembers(self, users) : - """ Return members who are not in users list""" - allMemberIds = self.listMemberIds() - otherMemberIds = [ userId for userId in allMemberIds if userId not in users ] - return self.getMembers(otherMemberIds) - - - - security.declareProtected(ListPortalMembers, 'getMembersMetadata') - def getMembersMetadata(self, users) : - """ return metadata from portal_catalog """ - userDict = {} - for u in users : userDict[u] = True - ctool = getUtilityByInterfaceName('Products.CMFCore.interfaces.ICatalogTool') - memberBrains = ctool(portal_type='Member Data', sort_on='getMemberSortableFormat') - memberList = [] - complementList = [] - - if users : - for mb in memberBrains : - metadata = {'id' : mb.getId, 'fullname' : mb.getMemberFullName} - if userDict.has_key(mb.getId) : - memberList.append(metadata) - else : - complementList.append(metadata) - else : - complementList = [{'id' : mb.getId, 'fullname' : mb.getMemberFullName} for mb in memberBrains] - - return {'memberList' : memberList, 'complementList' : complementList} - - - - security.declareProtected(RemoveMember, 'removeMembers') - def removeMembers(self, memberIds = []) : - """ remove member - """ - # TODO : remove member document ? - mdtool = getUtilityByInterfaceName('Products.CMFCore.interfaces.IMemberDataTool') - for m in self.getMembers(memberIds) : - m.manage_beforeDelete() - mdtool.deleteMemberData(m.getId()) - - self.aq_inner.acl_users.deleteUsers(users = memberIds) - - - - security.declareProtected(ManagePortal, 'setMemberAreaPortalType') - def setMemberAreaPortalType(self, member_folder_portal_type): - """ Set member area portal type to construct.""" - ttool = getUtilityByInterfaceName('Products.CMFCore.interfaces.ITypesTool') - if member_folder_portal_type not in ttool.objectIds() : - raise ValueError, "Unknown portal type : %s" % str(member_folder_portal_type) - - self.memberareaPortalType = member_folder_portal_type - return MessageDialog(title ='Type updated', - message='The member area type have been updated', - action ='manage_mapRoles') - - def getMemberAreaPortalType(self) : - return self.memberareaPortalType - - - def getHomeFolder(self, id=None, verifyPermission=0): - """ Return a member's home folder object, or None. - """ - if id is None: - member = self.getAuthenticatedMember() - if not hasattr(member, 'getMemberId'): - return None - id = member.getMemberId() - members = self.getMembersFolder() - if members is not None: - if not hasattr(members, id) and getattr(self, 'memberareaCreationFlag', 0) != 0 : - self.createMemberArea(id) - try: - folder = members._getOb(id) - if verifyPermission and not _checkPermission(View, folder): - # Don't return the folder if the user can't get to it. - return None - return folder - except (AttributeError, TypeError, KeyError): - pass - return None - - security.declarePublic('createMemberArea') - def createMemberArea(self, member_id=''): - """ Create a member area for 'member_id' or authenticated user. - """ - if not self.getMemberareaCreationFlag(): - return None - members = self.getMembersFolder() - if not members: - return None - if self.isAnonymousUser(): - return None - # Note: We can't use getAuthenticatedMember() and getMemberById() - # because they might be wrapped by MemberDataTool. - user = _getAuthenticatedUser(self) - user_id = user.getId() - if member_id in ('', user_id): - member = user - member_id = user_id - else: - if _checkPermission(ManageUsers, self): - member = self.acl_users.getUserById(member_id, None) - if member: - member = member.__of__(self.acl_users) - else: - raise ValueError, 'Member %s does not exist' % member_id - else: - return None - - if hasattr( aq_base(members), member_id ): - return None - - ttool = getUtilityByInterfaceName('Products.CMFCore.interfaces.ITypesTool') - info = getattr(ttool, self.memberareaPortalType) - - memberFullName = self.getMemberFullNameById(member_id, nameBefore = 0) - f = info._constructInstance( members, member_id, title=memberFullName ) - - # Grant Ownership and Owner role to Member - f.changeOwnership(user) - f.__ac_local_roles__ = None - f.manage_setLocalRoles(member_id, ['Owner']) - - f.reindexObjectSecurity() - return f - - - security.declareProtected(ListPortalMembers, 'looseSearchMembers') - def looseSearchMembers(self, searchString) : - """ """ - - words = searchString.strip().split() - words = [word.lower() for word in words] - - mdtool = getUtilityByInterfaceName('Products.CMFCore.interfaces.IMemberDataTool') - mdProperties = mdtool.propertyIds() - searchableProperties = [ p['id'] for p in mdtool.propertyMap() if p['type'] == 'string' ] + ['id'] - try : searchableProperties.remove('portal_skin') - except ValueError : pass - - match = [] - for m in self.listMembers() : - allWordsMatch = False - for word in words : - for p in searchableProperties : - if str(m.getProperty(p, '')).lower().find(word) != -1 : - allWordsMatch = True - break - else : - allWordsMatch = False - - if not allWordsMatch : - break - else : - match.append(m) - - return match - - def __getPUS(self): - # CMFCore.MembershipTool.MembershipTool tests 'getUsers' method but : - # "enumeration" methods ('getUserNames', 'getUsers') are *not* - # part of the contract! See IEnumerableUserFolder. - # (from PluggableAuthService.interfaces.authservice #233) - return self.acl_users - - -InitializeClass(MembershipTool)