vendor/CMF/1.6.3/CMFCore

annotate MembershipTool.py @ 0:587011552858

import CMF 1.6.3
author bdelbosc
date Mon, 23 Apr 2007 13:58:01 +0000
parents
children
rev   line source
bdelbosc@0 1 ##############################################################################
bdelbosc@0 2 #
bdelbosc@0 3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
bdelbosc@0 4 #
bdelbosc@0 5 # This software is subject to the provisions of the Zope Public License,
bdelbosc@0 6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
bdelbosc@0 7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
bdelbosc@0 8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
bdelbosc@0 9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
bdelbosc@0 10 # FOR A PARTICULAR PURPOSE.
bdelbosc@0 11 #
bdelbosc@0 12 ##############################################################################
bdelbosc@0 13 """ Basic membership tool.
bdelbosc@0 14
bdelbosc@0 15 $Id$
bdelbosc@0 16 """
bdelbosc@0 17
bdelbosc@0 18 import logging
bdelbosc@0 19 from AccessControl import ClassSecurityInfo
bdelbosc@0 20 from AccessControl.User import nobody
bdelbosc@0 21 from Acquisition import aq_base
bdelbosc@0 22 from Acquisition import aq_inner
bdelbosc@0 23 from Acquisition import aq_parent
bdelbosc@0 24 from Globals import DTMLFile
bdelbosc@0 25 from Globals import InitializeClass
bdelbosc@0 26 from Globals import MessageDialog
bdelbosc@0 27 from Globals import PersistentMapping
bdelbosc@0 28 from OFS.Folder import Folder
bdelbosc@0 29 from ZODB.POSException import ConflictError
bdelbosc@0 30
bdelbosc@0 31 from ActionProviderBase import ActionProviderBase
bdelbosc@0 32 from exceptions import AccessControl_Unauthorized
bdelbosc@0 33 from exceptions import BadRequest
bdelbosc@0 34 from interfaces.portal_membership \
bdelbosc@0 35 import portal_membership as IMembershipTool
bdelbosc@0 36 from permissions import AccessContentsInformation
bdelbosc@0 37 from permissions import ChangeLocalRoles
bdelbosc@0 38 from permissions import ListPortalMembers
bdelbosc@0 39 from permissions import ManagePortal
bdelbosc@0 40 from permissions import ManageUsers
bdelbosc@0 41 from permissions import SetOwnPassword
bdelbosc@0 42 from permissions import View
bdelbosc@0 43 from utils import _checkPermission
bdelbosc@0 44 from utils import _dtmldir
bdelbosc@0 45 from utils import _getAuthenticatedUser
bdelbosc@0 46 from utils import getToolByName
bdelbosc@0 47 from utils import UniqueObject
bdelbosc@0 48
bdelbosc@0 49
bdelbosc@0 50 logger = logging.getLogger('CMFCore.MembershipTool')
bdelbosc@0 51
bdelbosc@0 52
bdelbosc@0 53 class MembershipTool(UniqueObject, Folder, ActionProviderBase):
bdelbosc@0 54 """ This tool accesses member data through an acl_users object.
bdelbosc@0 55
bdelbosc@0 56 It can be replaced with something that accesses member data in a
bdelbosc@0 57 different way.
bdelbosc@0 58 """
bdelbosc@0 59
bdelbosc@0 60 __implements__ = (IMembershipTool, ActionProviderBase.__implements__)
bdelbosc@0 61
bdelbosc@0 62 id = 'portal_membership'
bdelbosc@0 63 meta_type = 'CMF Membership Tool'
bdelbosc@0 64 _actions = ()
bdelbosc@0 65
bdelbosc@0 66 memberareaCreationFlag = 1
bdelbosc@0 67
bdelbosc@0 68 security = ClassSecurityInfo()
bdelbosc@0 69
bdelbosc@0 70 manage_options=( ({ 'label' : 'Configuration'
bdelbosc@0 71 , 'action' : 'manage_mapRoles'
bdelbosc@0 72 },) +
bdelbosc@0 73 ActionProviderBase.manage_options +
bdelbosc@0 74 ( { 'label' : 'Overview'
bdelbosc@0 75 , 'action' : 'manage_overview'
bdelbosc@0 76 },
bdelbosc@0 77 ) + Folder.manage_options)
bdelbosc@0 78
bdelbosc@0 79 #
bdelbosc@0 80 # ZMI methods
bdelbosc@0 81 #
bdelbosc@0 82 security.declareProtected(ManagePortal, 'manage_overview')
bdelbosc@0 83 manage_overview = DTMLFile( 'explainMembershipTool', _dtmldir )
bdelbosc@0 84
bdelbosc@0 85 #
bdelbosc@0 86 # 'portal_membership' interface methods
bdelbosc@0 87 #
bdelbosc@0 88 security.declareProtected(ManagePortal, 'manage_mapRoles')
bdelbosc@0 89 manage_mapRoles = DTMLFile('membershipRolemapping', _dtmldir )
bdelbosc@0 90
bdelbosc@0 91 security.declareProtected(SetOwnPassword, 'setPassword')
bdelbosc@0 92 def setPassword(self, password, domains=None):
bdelbosc@0 93 '''Allows the authenticated member to set his/her own password.
bdelbosc@0 94 '''
bdelbosc@0 95 registration = getToolByName(self, 'portal_registration', None)
bdelbosc@0 96 if not self.isAnonymousUser():
bdelbosc@0 97 member = self.getAuthenticatedMember()
bdelbosc@0 98 if registration:
bdelbosc@0 99 failMessage = registration.testPasswordValidity(password)
bdelbosc@0 100 if failMessage is not None:
bdelbosc@0 101 raise BadRequest(failMessage)
bdelbosc@0 102 member.setSecurityProfile(password=password, domains=domains)
bdelbosc@0 103 else:
bdelbosc@0 104 raise BadRequest('Not logged in.')
bdelbosc@0 105
bdelbosc@0 106 security.declarePublic('getAuthenticatedMember')
bdelbosc@0 107 def getAuthenticatedMember(self):
bdelbosc@0 108 '''
bdelbosc@0 109 Returns the currently authenticated member object
bdelbosc@0 110 or the Anonymous User. Never returns None.
bdelbosc@0 111 '''
bdelbosc@0 112 u = _getAuthenticatedUser(self)
bdelbosc@0 113 if u is None:
bdelbosc@0 114 u = nobody
bdelbosc@0 115 return self.wrapUser(u)
bdelbosc@0 116
bdelbosc@0 117 security.declarePrivate('wrapUser')
bdelbosc@0 118 def wrapUser(self, u, wrap_anon=0):
bdelbosc@0 119 """ Set up the correct acquisition wrappers for a user object.
bdelbosc@0 120
bdelbosc@0 121 Provides an opportunity for a portal_memberdata tool to retrieve and
bdelbosc@0 122 store member data independently of the user object.
bdelbosc@0 123 """
bdelbosc@0 124 b = getattr(u, 'aq_base', None)
bdelbosc@0 125 if b is None:
bdelbosc@0 126 # u isn't wrapped at all. Wrap it in self.acl_users.
bdelbosc@0 127 b = u
bdelbosc@0 128 u = u.__of__(self.acl_users)
bdelbosc@0 129 if (b is nobody and not wrap_anon) or hasattr(b, 'getMemberId'):
bdelbosc@0 130 # This user is either not recognized by acl_users or it is
bdelbosc@0 131 # already registered with something that implements the
bdelbosc@0 132 # member data tool at least partially.
bdelbosc@0 133 return u
bdelbosc@0 134
bdelbosc@0 135 # Apply any role mapping if we have it
bdelbosc@0 136 if hasattr(self, 'role_map'):
bdelbosc@0 137 for portal_role in self.role_map.keys():
bdelbosc@0 138 if (self.role_map.get(portal_role) in u.roles and
bdelbosc@0 139 portal_role not in u.roles):
bdelbosc@0 140 u.roles.append(portal_role)
bdelbosc@0 141
bdelbosc@0 142 mdtool = getToolByName(self, 'portal_memberdata', None)
bdelbosc@0 143 if mdtool is not None:
bdelbosc@0 144 try:
bdelbosc@0 145 u = mdtool.wrapUser(u)
bdelbosc@0 146 except ConflictError:
bdelbosc@0 147 raise
bdelbosc@0 148 except:
bdelbosc@0 149 logger.error("Error during wrapUser", exc_info=True)
bdelbosc@0 150 return u
bdelbosc@0 151
bdelbosc@0 152 security.declareProtected(ManagePortal, 'getPortalRoles')
bdelbosc@0 153 def getPortalRoles(self):
bdelbosc@0 154 """
bdelbosc@0 155 Return all local roles defined by the portal itself,
bdelbosc@0 156 which means roles that are useful and understood
bdelbosc@0 157 by the portal object
bdelbosc@0 158 """
bdelbosc@0 159 parent = self.aq_inner.aq_parent
bdelbosc@0 160 roles = list( parent.userdefined_roles() )
bdelbosc@0 161
bdelbosc@0 162 # This is *not* a local role in the portal but used by it
bdelbosc@0 163 roles.append('Manager')
bdelbosc@0 164 roles.append('Owner')
bdelbosc@0 165
bdelbosc@0 166 return roles
bdelbosc@0 167
bdelbosc@0 168 security.declareProtected(ManagePortal, 'setRoleMapping')
bdelbosc@0 169 def setRoleMapping(self, portal_role, userfolder_role):
bdelbosc@0 170 """
bdelbosc@0 171 set the mapping of roles between roles understood by
bdelbosc@0 172 the portal and roles coming from outside user sources
bdelbosc@0 173 """
bdelbosc@0 174 if not hasattr(self, 'role_map'): self.role_map = PersistentMapping()
bdelbosc@0 175
bdelbosc@0 176 if len(userfolder_role) < 1:
bdelbosc@0 177 del self.role_map[portal_role]
bdelbosc@0 178 else:
bdelbosc@0 179 self.role_map[portal_role] = userfolder_role
bdelbosc@0 180
bdelbosc@0 181 return MessageDialog(
bdelbosc@0 182 title ='Mapping updated',
bdelbosc@0 183 message='The Role mappings have been updated',
bdelbosc@0 184 action ='manage_mapRoles')
bdelbosc@0 185
bdelbosc@0 186 security.declareProtected(ManagePortal, 'getMappedRole')
bdelbosc@0 187 def getMappedRole(self, portal_role):
bdelbosc@0 188 """
bdelbosc@0 189 returns a role name if the portal role is mapped to
bdelbosc@0 190 something else or an empty string if it is not
bdelbosc@0 191 """
bdelbosc@0 192 if hasattr(self, 'role_map'):
bdelbosc@0 193 return self.role_map.get(portal_role, '')
bdelbosc@0 194 else:
bdelbosc@0 195 return ''
bdelbosc@0 196
bdelbosc@0 197 security.declarePublic('getMembersFolder')
bdelbosc@0 198 def getMembersFolder(self):
bdelbosc@0 199 """ Get the members folder object.
bdelbosc@0 200 """
bdelbosc@0 201 parent = aq_parent( aq_inner(self) )
bdelbosc@0 202 members = getattr(parent, 'Members', None)
bdelbosc@0 203 return members
bdelbosc@0 204
bdelbosc@0 205 security.declareProtected(ManagePortal, 'getMemberareaCreationFlag')
bdelbosc@0 206 def getMemberareaCreationFlag(self):
bdelbosc@0 207 """
bdelbosc@0 208 Returns the flag indicating whether the membership tool
bdelbosc@0 209 will create a member area if an authenticated user from
bdelbosc@0 210 an underlying user folder logs in first without going
bdelbosc@0 211 through the join process
bdelbosc@0 212 """
bdelbosc@0 213 return self.memberareaCreationFlag
bdelbosc@0 214
bdelbosc@0 215 security.declareProtected(ManagePortal, 'setMemberareaCreationFlag')
bdelbosc@0 216 def setMemberareaCreationFlag(self):
bdelbosc@0 217 """
bdelbosc@0 218 sets the flag indicating whether the membership tool
bdelbosc@0 219 will create a member area if an authenticated user from
bdelbosc@0 220 an underlying user folder logs in first without going
bdelbosc@0 221 through the join process
bdelbosc@0 222 """
bdelbosc@0 223 if not hasattr(self, 'memberareaCreationFlag'):
bdelbosc@0 224 self.memberareaCreationFlag = 0
bdelbosc@0 225
bdelbosc@0 226 if self.memberareaCreationFlag == 0:
bdelbosc@0 227 self.memberareaCreationFlag = 1
bdelbosc@0 228 else:
bdelbosc@0 229 self.memberareaCreationFlag = 0
bdelbosc@0 230
bdelbosc@0 231 return MessageDialog(
bdelbosc@0 232 title ='Member area creation flag changed',
bdelbosc@0 233 message='Member area creation flag has been updated',
bdelbosc@0 234 action ='manage_mapRoles')
bdelbosc@0 235
bdelbosc@0 236 security.declarePublic('createMemberArea')
bdelbosc@0 237 def createMemberArea(self, member_id=''):
bdelbosc@0 238 """ Create a member area for 'member_id' or authenticated user.
bdelbosc@0 239 """
bdelbosc@0 240 if not self.getMemberareaCreationFlag():
bdelbosc@0 241 return None
bdelbosc@0 242 members = self.getMembersFolder()
bdelbosc@0 243 if not members:
bdelbosc@0 244 return None
bdelbosc@0 245 if self.isAnonymousUser():
bdelbosc@0 246 return None
bdelbosc@0 247 # Note: We can't use getAuthenticatedMember() and getMemberById()
bdelbosc@0 248 # because they might be wrapped by MemberDataTool.
bdelbosc@0 249 user = _getAuthenticatedUser(self)
bdelbosc@0 250 user_id = user.getId()
bdelbosc@0 251 if member_id in ('', user_id):
bdelbosc@0 252 member = user
bdelbosc@0 253 member_id = user_id
bdelbosc@0 254 else:
bdelbosc@0 255 if _checkPermission(ManageUsers, self):
bdelbosc@0 256 member = self.acl_users.getUserById(member_id, None)
bdelbosc@0 257 if member:
bdelbosc@0 258 member = member.__of__(self.acl_users)
bdelbosc@0 259 else:
bdelbosc@0 260 raise ValueError('Member %s does not exist' % member_id)
bdelbosc@0 261 else:
bdelbosc@0 262 return None
bdelbosc@0 263 if hasattr( aq_base(members), member_id ):
bdelbosc@0 264 return None
bdelbosc@0 265 else:
bdelbosc@0 266 f_title = "%s's Home" % member_id
bdelbosc@0 267 members.manage_addPortalFolder( id=member_id, title=f_title )
bdelbosc@0 268 f=getattr(members, member_id)
bdelbosc@0 269
bdelbosc@0 270 f.manage_permission(View,
bdelbosc@0 271 ['Owner','Manager','Reviewer'], 0)
bdelbosc@0 272 f.manage_permission(AccessContentsInformation,
bdelbosc@0 273 ['Owner','Manager','Reviewer'], 0)
bdelbosc@0 274
bdelbosc@0 275 # Grant Ownership and Owner role to Member
bdelbosc@0 276 f.changeOwnership(member)
bdelbosc@0 277 f.__ac_local_roles__ = None
bdelbosc@0 278 f.manage_setLocalRoles(member_id, ['Owner'])
bdelbosc@0 279 return f
bdelbosc@0 280
bdelbosc@0 281 security.declarePublic('createMemberarea')
bdelbosc@0 282 createMemberarea = createMemberArea
bdelbosc@0 283
bdelbosc@0 284 security.declareProtected(ManageUsers, 'deleteMemberArea')
bdelbosc@0 285 def deleteMemberArea(self, member_id):
bdelbosc@0 286 """ Delete member area of member specified by member_id.
bdelbosc@0 287 """
bdelbosc@0 288 members = self.getMembersFolder()
bdelbosc@0 289 if not members:
bdelbosc@0 290 return 0
bdelbosc@0 291 if hasattr( aq_base(members), member_id ):
bdelbosc@0 292 members.manage_delObjects(member_id)
bdelbosc@0 293 return 1
bdelbosc@0 294 else:
bdelbosc@0 295 return 0
bdelbosc@0 296
bdelbosc@0 297 security.declarePublic('isAnonymousUser')
bdelbosc@0 298 def isAnonymousUser(self):
bdelbosc@0 299 '''
bdelbosc@0 300 Returns 1 if the user is not logged in.
bdelbosc@0 301 '''
bdelbosc@0 302 u = _getAuthenticatedUser(self)
bdelbosc@0 303 if u is None or u.getUserName() == 'Anonymous User':
bdelbosc@0 304 return 1
bdelbosc@0 305 return 0
bdelbosc@0 306
bdelbosc@0 307 security.declarePublic('checkPermission')
bdelbosc@0 308 def checkPermission(self, permissionName, object, subobjectName=None):
bdelbosc@0 309 '''
bdelbosc@0 310 Checks whether the current user has the given permission on
bdelbosc@0 311 the given object or subobject.
bdelbosc@0 312 '''
bdelbosc@0 313 if subobjectName is not None:
bdelbosc@0 314 object = getattr(object, subobjectName)
bdelbosc@0 315 return _checkPermission(permissionName, object)
bdelbosc@0 316
bdelbosc@0 317 security.declarePublic('credentialsChanged')
bdelbosc@0 318 def credentialsChanged(self, password):
bdelbosc@0 319 '''
bdelbosc@0 320 Notifies the authentication mechanism that this user has changed
bdelbosc@0 321 passwords. This can be used to update the authentication cookie.
bdelbosc@0 322 Note that this call should *not* cause any change at all to user
bdelbosc@0 323 databases.
bdelbosc@0 324 '''
bdelbosc@0 325 if not self.isAnonymousUser():
bdelbosc@0 326 acl_users = self.acl_users
bdelbosc@0 327 user = _getAuthenticatedUser(self)
bdelbosc@0 328 name = user.getUserName()
bdelbosc@0 329 # this really does need to be the user name, and not the user id,
bdelbosc@0 330 # because we're dealing with authentication credentials
bdelbosc@0 331 if hasattr(acl_users.aq_base, 'credentialsChanged'):
bdelbosc@0 332 # Use an interface provided by LoginManager.
bdelbosc@0 333 acl_users.credentialsChanged(user, name, password)
bdelbosc@0 334 else:
bdelbosc@0 335 req = self.REQUEST
bdelbosc@0 336 p = getattr(req, '_credentials_changed_path', None)
bdelbosc@0 337 if p is not None:
bdelbosc@0 338 # Use an interface provided by CookieCrumbler.
bdelbosc@0 339 change = self.restrictedTraverse(p)
bdelbosc@0 340 change(user, name, password)
bdelbosc@0 341
bdelbosc@0 342 security.declareProtected(ManageUsers, 'getMemberById')
bdelbosc@0 343 def getMemberById(self, id):
bdelbosc@0 344 '''
bdelbosc@0 345 Returns the given member.
bdelbosc@0 346 '''
bdelbosc@0 347 user = self._huntUser(id, self)
bdelbosc@0 348 if user is not None:
bdelbosc@0 349 user = self.wrapUser(user)
bdelbosc@0 350 return user
bdelbosc@0 351
bdelbosc@0 352 def _huntUser(self, username, context):
bdelbosc@0 353 """Find user in the hierarchy starting from bottom level 'start'.
bdelbosc@0 354 """
bdelbosc@0 355 uf = context.acl_users
bdelbosc@0 356 while uf is not None:
bdelbosc@0 357 user = uf.getUserById(username)
bdelbosc@0 358 if user is not None:
bdelbosc@0 359 return user
bdelbosc@0 360 container = aq_parent(aq_inner(uf))
bdelbosc@0 361 parent = aq_parent(aq_inner(container))
bdelbosc@0 362 uf = getattr(parent, 'acl_users', None)
bdelbosc@0 363 return None
bdelbosc@0 364
bdelbosc@0 365 def __getPUS(self):
bdelbosc@0 366 # Gets something we can call getUsers() and getUserNames() on.
bdelbosc@0 367 acl_users = self.acl_users
bdelbosc@0 368 if hasattr(acl_users, 'getUsers'):
bdelbosc@0 369 return acl_users
bdelbosc@0 370 else:
bdelbosc@0 371 # This hack works around the absence of getUsers() in LoginManager.
bdelbosc@0 372 # Gets the PersistentUserSource object that stores our users
bdelbosc@0 373 for us in acl_users.UserSourcesGroup.objectValues():
bdelbosc@0 374 if us.meta_type == 'Persistent User Source':
bdelbosc@0 375 return us.__of__(acl_users)
bdelbosc@0 376
bdelbosc@0 377 security.declareProtected(ManageUsers, 'listMemberIds')
bdelbosc@0 378 def listMemberIds(self):
bdelbosc@0 379 '''Lists the ids of all members. This may eventually be
bdelbosc@0 380 replaced with a set of methods for querying pieces of the
bdelbosc@0 381 list rather than the entire list at once.
bdelbosc@0 382 '''
bdelbosc@0 383 user_folder = self.__getPUS()
bdelbosc@0 384 return [ x.getId() for x in user_folder.getUsers() ]
bdelbosc@0 385
bdelbosc@0 386 security.declareProtected(ManageUsers, 'listMembers')
bdelbosc@0 387 def listMembers(self):
bdelbosc@0 388 '''Gets the list of all members.
bdelbosc@0 389 '''
bdelbosc@0 390 return map(self.wrapUser, self.__getPUS().getUsers())
bdelbosc@0 391
bdelbosc@0 392 security.declareProtected(ListPortalMembers, 'searchMembers')
bdelbosc@0 393 def searchMembers( self, search_param, search_term ):
bdelbosc@0 394 """ Search the membership """
bdelbosc@0 395 md = getToolByName( self, 'portal_memberdata' )
bdelbosc@0 396
bdelbosc@0 397 return md.searchMemberData( search_param, search_term )
bdelbosc@0 398
bdelbosc@0 399 security.declareProtected(View, 'getCandidateLocalRoles')
bdelbosc@0 400 def getCandidateLocalRoles(self, obj):
bdelbosc@0 401 """ What local roles can I assign?
bdelbosc@0 402 """
bdelbosc@0 403 member = self.getAuthenticatedMember()
bdelbosc@0 404 member_roles = member.getRolesInContext(obj)
bdelbosc@0 405 if _checkPermission(ManageUsers, obj):
bdelbosc@0 406 local_roles = self.getPortalRoles()
bdelbosc@0 407 if 'Manager' not in member_roles:
bdelbosc@0 408 local_roles.remove('Manager')
bdelbosc@0 409 else:
bdelbosc@0 410 local_roles = [ role for role in member_roles
bdelbosc@0 411 if role not in ('Member', 'Authenticated') ]
bdelbosc@0 412 local_roles.sort()
bdelbosc@0 413 return tuple(local_roles)
bdelbosc@0 414
bdelbosc@0 415 security.declareProtected(View, 'setLocalRoles')
bdelbosc@0 416 def setLocalRoles(self, obj, member_ids, member_role, reindex=1):
bdelbosc@0 417 """ Add local roles on an item.
bdelbosc@0 418 """
bdelbosc@0 419 if ( _checkPermission(ChangeLocalRoles, obj)
bdelbosc@0 420 and member_role in self.getCandidateLocalRoles(obj) ):
bdelbosc@0 421 for member_id in member_ids:
bdelbosc@0 422 roles = list(obj.get_local_roles_for_userid( userid=member_id ))
bdelbosc@0 423
bdelbosc@0 424 if member_role not in roles:
bdelbosc@0 425 roles.append( member_role )
bdelbosc@0 426 obj.manage_setLocalRoles( member_id, roles )
bdelbosc@0 427
bdelbosc@0 428 if reindex:
bdelbosc@0 429 # It is assumed that all objects have the method
bdelbosc@0 430 # reindexObjectSecurity, which is in CMFCatalogAware and
bdelbosc@0 431 # thus PortalContent and PortalFolder.
bdelbosc@0 432 obj.reindexObjectSecurity()
bdelbosc@0 433
bdelbosc@0 434 security.declareProtected(View, 'deleteLocalRoles')
bdelbosc@0 435 def deleteLocalRoles(self, obj, member_ids, reindex=1, recursive=0):
bdelbosc@0 436 """ Delete local roles of specified members.
bdelbosc@0 437 """
bdelbosc@0 438 if _checkPermission(ChangeLocalRoles, obj):
bdelbosc@0 439 for member_id in member_ids:
bdelbosc@0 440 if obj.get_local_roles_for_userid(userid=member_id):
bdelbosc@0 441 obj.manage_delLocalRoles(userids=member_ids)
bdelbosc@0 442 break
bdelbosc@0 443
bdelbosc@0 444 if recursive and hasattr( aq_base(obj), 'contentValues' ):
bdelbosc@0 445 for subobj in obj.contentValues():
bdelbosc@0 446 self.deleteLocalRoles(subobj, member_ids, 0, 1)
bdelbosc@0 447
bdelbosc@0 448 if reindex:
bdelbosc@0 449 # reindexObjectSecurity is always recursive
bdelbosc@0 450 obj.reindexObjectSecurity()
bdelbosc@0 451
bdelbosc@0 452 security.declarePrivate('addMember')
bdelbosc@0 453 def addMember(self, id, password, roles, domains, properties=None):
bdelbosc@0 454 '''Adds a new member to the user folder. Security checks will have
bdelbosc@0 455 already been performed. Called by portal_registration.
bdelbosc@0 456 '''
bdelbosc@0 457 acl_users = self.acl_users
bdelbosc@0 458 if hasattr(acl_users, '_doAddUser'):
bdelbosc@0 459 acl_users._doAddUser(id, password, roles, domains)
bdelbosc@0 460 else:
bdelbosc@0 461 # The acl_users folder is a LoginManager. Search for a UserSource
bdelbosc@0 462 # with the needed support.
bdelbosc@0 463 for source in acl_users.UserSourcesGroup.objectValues():
bdelbosc@0 464 if hasattr(source, 'addUser'):
bdelbosc@0 465 source.__of__(self).addUser(id, password, roles, domains)
bdelbosc@0 466 raise "Can't add Member", "No supported UserSources"
bdelbosc@0 467
bdelbosc@0 468 if properties is not None:
bdelbosc@0 469 member = self.getMemberById(id)
bdelbosc@0 470 member.setMemberProperties(properties)
bdelbosc@0 471
bdelbosc@0 472 security.declareProtected(ManageUsers, 'deleteMembers')
bdelbosc@0 473 def deleteMembers(self, member_ids, delete_memberareas=1,
bdelbosc@0 474 delete_localroles=1):
bdelbosc@0 475 """ Delete members specified by member_ids.
bdelbosc@0 476 """
bdelbosc@0 477
bdelbosc@0 478 # Delete members in acl_users.
bdelbosc@0 479 acl_users = self.acl_users
bdelbosc@0 480 if _checkPermission(ManageUsers, acl_users):
bdelbosc@0 481 if isinstance(member_ids, basestring):
bdelbosc@0 482 member_ids = (member_ids,)
bdelbosc@0 483 member_ids = list(member_ids)
bdelbosc@0 484 for member_id in member_ids[:]:
bdelbosc@0 485 if not acl_users.getUserById(member_id, None):
bdelbosc@0 486 member_ids.remove(member_id)
bdelbosc@0 487 try:
bdelbosc@0 488 acl_users.userFolderDelUsers(member_ids)
bdelbosc@0 489 except (NotImplementedError, 'NotImplemented'):
bdelbosc@0 490 raise NotImplementedError('The underlying User Folder '
bdelbosc@0 491 'doesn\'t support deleting members.')
bdelbosc@0 492 else:
bdelbosc@0 493 raise AccessControl_Unauthorized('You need the \'Manage users\' '
bdelbosc@0 494 'permission for the underlying User Folder.')
bdelbosc@0 495
bdelbosc@0 496 # Delete member data in portal_memberdata.
bdelbosc@0 497 mdtool = getToolByName(self, 'portal_memberdata', None)
bdelbosc@0 498 if mdtool is not None:
bdelbosc@0 499 for member_id in member_ids:
bdelbosc@0 500 mdtool.deleteMemberData(member_id)
bdelbosc@0 501
bdelbosc@0 502 # Delete members' home folders including all content items.
bdelbosc@0 503 if delete_memberareas:
bdelbosc@0 504 for member_id in member_ids:
bdelbosc@0 505 self.deleteMemberArea(member_id)
bdelbosc@0 506
bdelbosc@0 507 # Delete members' local roles.
bdelbosc@0 508 if delete_localroles:
bdelbosc@0 509 utool = getToolByName(self, 'portal_url', None)
bdelbosc@0 510 self.deleteLocalRoles( utool.getPortalObject(), member_ids,
bdelbosc@0 511 reindex=1, recursive=1 )
bdelbosc@0 512
bdelbosc@0 513 return tuple(member_ids)
bdelbosc@0 514
bdelbosc@0 515 security.declarePublic('getHomeFolder')
bdelbosc@0 516 def getHomeFolder(self, id=None, verifyPermission=0):
bdelbosc@0 517 """Returns a member's home folder object or None.
bdelbosc@0 518 Set verifyPermission to 1 to return None when the user
bdelbosc@0 519 doesn't have the View permission on the folder.
bdelbosc@0 520 """
bdelbosc@0 521 return None
bdelbosc@0 522
bdelbosc@0 523 security.declarePublic('getHomeUrl')
bdelbosc@0 524 def getHomeUrl(self, id=None, verifyPermission=0):
bdelbosc@0 525 """Returns the URL to a member's home folder or None.
bdelbosc@0 526 Set verifyPermission to 1 to return None when the user
bdelbosc@0 527 doesn't have the View permission on the folder.
bdelbosc@0 528 """
bdelbosc@0 529 return None
bdelbosc@0 530
bdelbosc@0 531 InitializeClass(MembershipTool)