X-Git-Url: https://scm.cri.ensmp.fr/git/GroupUserFolder.git/blobdiff_plain/e9d14b6b5cc9cd4775c60cb340b5c4c787536fc3:/GroupsTool.py..3e1ba4932c34812cf2f6f3569b0f0dbea97b7a0b:/Products/GroupUserFolder/static/gitweb.js diff --git a/GroupsTool.py b/GroupsTool.py deleted file mode 100644 index e76caa1..0000000 --- a/GroupsTool.py +++ /dev/null @@ -1,495 +0,0 @@ -# -*- coding: utf-8 -*- -## GroupUserFolder -## Copyright (C)2006 Ingeniweb - -## 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; see the file COPYING. If not, write to the -## Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -## Copyright (c) 2003 The Connexions Project, All Rights Reserved -## initially written by J Cameron Cooper, 11 June 2003 -## concept with Brent Hendricks, George Runyan -""" -Basic usergroup tool. -""" -__version__ = "$Revision$" -# $Source: $ -# $Id: GroupsTool.py 50142 2007-09-25 13:13:12Z wichert $ -__docformat__ = 'restructuredtext' - -from Products.CMFCore.utils import UniqueObject -from Products.CMFCore.utils import getToolByName -from Products.CMFCore.utils import _checkPermission -from OFS.SimpleItem import SimpleItem -from Globals import InitializeClass, DTMLFile, MessageDialog -from Acquisition import aq_base -from AccessControl.User import nobody -from AccessControl import ClassSecurityInfo -from ZODB.POSException import ConflictError -# BBB CMF < 1.5 -try: - from Products.CMFCore.permissions import ManagePortal - from Products.CMFCore.permissions import View - from Products.CMFCore.permissions import ViewManagementScreens -except ImportError: - from Products.CMFCore.CMFCorePermissions import ManagePortal - from Products.CMFCore.CMFCorePermissions import View - from Products.CMFCore.CMFCorePermissions import ViewManagementScreens - -from Products.GroupUserFolder import postonly -from GroupsToolPermissions import AddGroups -from GroupsToolPermissions import ManageGroups -from GroupsToolPermissions import DeleteGroups -from GroupsToolPermissions import ViewGroups -from GroupsToolPermissions import SetGroupOwnership -from Products.CMFCore.ActionProviderBase import ActionProviderBase -from interfaces.portal_groups import portal_groups as IGroupsTool -from global_symbols import * - -# Optional feature-preview support -import PloneFeaturePreview - -class GroupsTool (UniqueObject, SimpleItem, ActionProviderBase, ): - """ This tool accesses group data through a GRUF acl_users object. - - It can be replaced with something that groups member data in a - different way. - """ - # Show implementation only if IGroupsTool is defined - # The latter will work only with Plone 1.1 => hence, the if - if hasattr(ActionProviderBase, '__implements__'): - __implements__ = (IGroupsTool, ActionProviderBase.__implements__) - - id = 'portal_groups' - meta_type = 'CMF Groups Tool' - _actions = () - - security = ClassSecurityInfo() - - groupworkspaces_id = "groups" - groupworkspaces_title = "Groups" - groupWorkspacesCreationFlag = 1 - groupWorkspaceType = "Folder" - groupWorkspaceContainerType = "Folder" - - manage_options=( - ( { 'label' : 'Configure' - , 'action' : 'manage_config' - }, - ) + ActionProviderBase.manage_options + - ( { 'label' : 'Overview' - , 'action' : 'manage_overview' - }, - ) + SimpleItem.manage_options) - - # # - # ZMI methods # - # # - security.declareProtected(ViewManagementScreens, 'manage_overview') - manage_overview = DTMLFile('dtml/explainGroupsTool', globals()) # unlike MembershipTool - security.declareProtected(ViewManagementScreens, 'manage_config') - manage_config = DTMLFile('dtml/configureGroupsTool', globals()) - - security.declareProtected(ManagePortal, 'manage_setGroupWorkspacesFolder') - def manage_setGroupWorkspacesFolder(self, id='groups', title='Groups', REQUEST=None): - """ZMI method for workspace container name set.""" - self.setGroupWorkspacesFolder(id, title) - return self.manage_config(manage_tabs_message="Workspaces folder name set to %s" % id) - - security.declareProtected(ManagePortal, 'manage_setGroupWorkspaceType') - def manage_setGroupWorkspaceType(self, type='Folder', REQUEST=None): - """ZMI method for workspace type set.""" - self.setGroupWorkspaceType(type) - return self.manage_config(manage_tabs_message="Group Workspaces type set to %s" % type) - - security.declareProtected(ManagePortal, 'manage_setGroupWorkspaceContainerType') - def manage_setGroupWorkspaceContainerType(self, type='Folder', REQUEST=None): - """ZMI method for workspace type set.""" - self.setGroupWorkspaceContainerType(type) - return self.manage_config(manage_tabs_message="Group Workspaces container type set to %s" % type) - - security.declareProtected(ViewGroups, 'getGroupById') - def getGroupById(self, id): - """ - Returns the portal_groupdata-ish object for a group corresponding to this id. - """ - if id==None: - return None - g = self.acl_users.getGroupByName(id, None) - if g is not None: - g = self.wrapGroup(g) - return g - - security.declareProtected(ViewGroups, 'getGroupsByUserId') - def getGroupsByUserId(self, userid): - """Return a list of the groups the user corresponding to 'userid' belongs to.""" - #log("getGroupsByUserId(%s)" % userid) - user = self.acl_users.getUser(userid) - #log("user '%s' is in groups %s" % (userid, user.getGroups())) - if user: - groups = user.getGroups() or [] - else: - groups = [] - return [self.getGroupById(elt) for elt in groups] - - security.declareProtected(ViewGroups, 'listGroups') - def listGroups(self): - """Return a list of the available portal_groupdata-ish objects.""" - return [ self.wrapGroup(elt) for elt in self.acl_users.getGroups() ] - - security.declareProtected(ViewGroups, 'listGroupIds') - def listGroupIds(self): - """Return a list of the available groups' ids as entered (without group prefixes).""" - return self.acl_users.getGroupNames() - - security.declareProtected(ViewGroups, 'listGroupNames') - def listGroupNames(self): - """Return a list of the available groups' ids as entered (without group prefixes).""" - return self.acl_users.getGroupNames() - - security.declarePublic("isGroup") - def isGroup(self, u): - """Test if a user/group object is a group or not. - You must pass an object you get earlier with wrapUser() or wrapGroup() - """ - base = aq_base(u) - if hasattr(base, "isGroup") and base.isGroup(): - return 1 - return 0 - - security.declareProtected(View, 'searchForGroups') - def searchForGroups(self, REQUEST = {}, **kw): - """Return a list of groups meeting certain conditions. """ - # arguments need to be better refined? - if REQUEST: - dict = REQUEST - else: - dict = kw - - name = dict.get('name', None) - email = dict.get('email', None) - roles = dict.get('roles', None) - title = dict.get('title', None) - title_or_name = dict.get('title_or_name', None) - - last_login_time = dict.get('last_login_time', None) - #is_manager = self.checkPermission('Manage portal', self) - - if name: - name = name.strip().lower() - if not name: - name = None - if email: - email = email.strip().lower() - if not email: - email = None - if title: - title = title.strip().lower() - if title_or_name: - title_or_name = title_or_name.strip().lower() - if not title: - title = None - - res = [] - portal = self.portal_url.getPortalObject() - for g in portal.portal_groups.listGroups(): - #if not (g.listed or is_manager): - # continue - if name: - if (g.getGroupName().lower().find(name) == -1) and (g.getGroupId().lower().find(name) == -1): - continue - if email: - if g.email.lower().find(email) == -1: - continue - if roles: - group_roles = g.getRoles() - found = 0 - for r in roles: - if r in group_roles: - found = 1 - break - if not found: - continue - if title: - if g.title.lower().find(title) == -1: - continue - if title_or_name: - # first search for title - if g.title.lower().find(title_or_name) == -1: - # not found, now search for name - if (g.getGroupName().lower().find(title_or_name) == -1) and (g.getGroupId().lower().find(title_or_name) == -1): - continue - - if last_login_time: - if g.last_login_time < last_login_time: - continue - res.append(g) - - return res - - security.declareProtected(AddGroups, 'addGroup') - def addGroup(self, id, roles = [], groups = [], REQUEST=None, *args, **kw): - """Create a group, and a group workspace if the toggle is on, with the supplied id, roles, and domains. - - Underlying user folder must support adding users via the usual Zope API. - Passwords for groups ARE irrelevant in GRUF.""" - if id in self.listGroupIds(): - raise ValueError, "Group '%s' already exists." % (id, ) - self.acl_users.userFolderAddGroup(id, roles = roles, groups = groups ) - self.createGrouparea(id) - self.getGroupById(id).setProperties(**kw) - addGroup = postonly(addGroup) - - security.declareProtected(ManageGroups, 'editGroup') - def editGroup(self, id, roles = None, groups = None, REQUEST=None, *args, **kw): - """Edit the given group with the supplied password, roles, and domains. - - Underlying user folder must support editing users via the usual Zope API. - Passwords for groups seem to be currently irrelevant in GRUF.""" - self.acl_users.userFolderEditGroup(id, roles = roles, groups = groups, ) - self.getGroupById(id).setProperties(**kw) - editGroup = postonly(editGroup) - - security.declareProtected(DeleteGroups, 'removeGroups') - def removeGroups(self, ids, keep_workspaces=0, REQUEST=None): - """Remove the group in the provided list (if possible). - - Will by default remove this group's GroupWorkspace if it exists. You may - turn this off by specifying keep_workspaces=true. - Underlying user folder must support removing users via the usual Zope API.""" - for gid in ids: - gdata = self.getGroupById(gid) - gusers = gdata.getGroupMembers() - for guser in gusers: - gdata.removeMember(guser.id) - - self.acl_users.userFolderDelGroups(ids) - gwf = self.getGroupWorkspacesFolder() - if not gwf: # _robert_ - return - if not keep_workspaces: - for id in ids: - if hasattr(aq_base(gwf), id): - gwf._delObject(id) - removeGroups = postonly(removeGroups) - - security.declareProtected(SetGroupOwnership, 'setGroupOwnership') - def setGroupOwnership(self, group, object, REQUEST=None): - """Make the object 'object' owned by group 'group' (a portal_groupdata-ish object). - - For GRUF this is easy. Others may have to re-implement.""" - user = group.getGroup() - if user is None: - raise ValueError, "Invalid group: '%s'." % (group, ) - object.changeOwnership(user) - object.manage_setLocalRoles(user.getId(), ['Owner']) - setGroupOwnership = postonly(setGroupOwnership) - - security.declareProtected(ManagePortal, 'setGroupWorkspacesFolder') - def setGroupWorkspacesFolder(self, id="", title=""): - """ Set the location of the Group Workspaces folder by id. - - The Group Workspaces Folder contains all the group workspaces, just like the - Members folder contains all the member folders. - - If anyone really cares, we can probably make the id work as a path as well, - but for the moment it's only an id for a folder in the portal root, just like the - corresponding MembershipTool functionality. """ - self.groupworkspaces_id = id.strip() - self.groupworkspaces_title = title - - security.declareProtected(ManagePortal, 'getGroupWorkspacesFolderId') - def getGroupWorkspacesFolderId(self): - """ Get the Group Workspaces folder object's id. - - The Group Workspaces Folder contains all the group workspaces, just like the - Members folder contains all the member folders. """ - return self.groupworkspaces_id - - security.declareProtected(ManagePortal, 'getGroupWorkspacesFolderTitle') - def getGroupWorkspacesFolderTitle(self): - """ Get the Group Workspaces folder object's title. - """ - return self.groupworkspaces_title - - security.declarePublic('getGroupWorkspacesFolder') - def getGroupWorkspacesFolder(self): - """ Get the Group Workspaces folder object. - - The Group Workspaces Folder contains all the group workspaces, just like the - Members folder contains all the member folders. """ - parent = self.aq_inner.aq_parent - folder = getattr(parent, self.getGroupWorkspacesFolderId(), None) - return folder - - security.declareProtected(ManagePortal, 'toggleGroupWorkspacesCreation') - def toggleGroupWorkspacesCreation(self, REQUEST=None): - """ Toggles the flag for creation of a GroupWorkspaces folder upon creation of the group. """ - if not hasattr(self, 'groupWorkspacesCreationFlag'): - self.groupWorkspacesCreationFlag = 0 - - self.groupWorkspacesCreationFlag = not self.groupWorkspacesCreationFlag - - m = self.groupWorkspacesCreationFlag and 'turned on' or 'turned off' - - return self.manage_config(manage_tabs_message="Workspaces creation %s" % m) - - security.declareProtected(ManagePortal, 'getGroupWorkspacesCreationFlag') - def getGroupWorkspacesCreationFlag(self): - """Return the (boolean) flag indicating whether the Groups Tool will create a group workspace - upon the creation of the group (if one doesn't exist already). """ - return self.groupWorkspacesCreationFlag - - security.declareProtected(AddGroups, 'createGrouparea') - def createGrouparea(self, id): - """Create a space in the portal for the given group, much like member home - folders.""" - parent = self.aq_inner.aq_parent - workspaces = self.getGroupWorkspacesFolder() - pt = getToolByName( self, 'portal_types' ) - - if id and self.getGroupWorkspacesCreationFlag(): - if workspaces is None: - # add GroupWorkspaces folder - pt.constructContent( - type_name = self.getGroupWorkspaceContainerType(), - container = parent, - id = self.getGroupWorkspacesFolderId(), - ) - workspaces = self.getGroupWorkspacesFolder() - workspaces.setTitle(self.getGroupWorkspacesFolderTitle()) - workspaces.setDescription("Container for " + self.getGroupWorkspacesFolderId()) - # how about ownership? - - # this stuff like MembershipTool... - portal_catalog = getToolByName( self, 'portal_catalog' ) - portal_catalog.unindexObject(workspaces) # unindex GroupWorkspaces folder - workspaces._setProperty('right_slots', (), 'lines') - - if workspaces is not None and not hasattr(workspaces.aq_base, id): - # add workspace to GroupWorkspaces folder - pt.constructContent( - type_name = self.getGroupWorkspaceType(), - container = workspaces, - id = id, - ) - space = self.getGroupareaFolder(id) - space.setTitle("%s workspace" % id) - space.setDescription("Container for objects shared by this group") - - if hasattr(space, 'setInitialGroup'): - # GroupSpaces can have their own policies regarding the group - # that they are created for. - user = self.getGroupById(id).getGroup() - if user is not None: - space.setInitialGroup(user) - else: - space.manage_delLocalRoles(space.users_with_local_role('Owner')) - self.setGroupOwnership(self.getGroupById(id), space) - - # Hook to allow doing other things after grouparea creation. - notify_script = getattr(workspaces, 'notifyGroupAreaCreated', None) - if notify_script is not None: - notify_script() - - # Re-indexation - portal_catalog = getToolByName( self, 'portal_catalog' ) - portal_catalog.reindexObject(space) - - security.declareProtected(ManagePortal, 'getGroupWorkspaceType') - def getGroupWorkspaceType(self): - """Return the Type (as in TypesTool) to make the GroupWorkspace.""" - return self.groupWorkspaceType - - security.declareProtected(ManagePortal, 'setGroupWorkspaceType') - def setGroupWorkspaceType(self, type): - """Set the Type (as in TypesTool) to make the GroupWorkspace.""" - self.groupWorkspaceType = type - - security.declareProtected(ManagePortal, 'getGroupWorkspaceContainerType') - def getGroupWorkspaceContainerType(self): - """Return the Type (as in TypesTool) to make the GroupWorkspace.""" - return self.groupWorkspaceContainerType - - security.declareProtected(ManagePortal, 'setGroupWorkspaceContainerType') - def setGroupWorkspaceContainerType(self, type): - """Set the Type (as in TypesTool) to make the GroupWorkspace.""" - self.groupWorkspaceContainerType = type - - security.declarePublic('getGroupareaFolder') - def getGroupareaFolder(self, id=None, verifyPermission=0): - """Returns the object of the group's work area.""" - if id is None: - group = self.getAuthenticatedMember() - if not hasattr(member, 'getGroupId'): - return None - id = group.getGroupId() - workspaces = self.getGroupWorkspacesFolder() - if workspaces: - try: - folder = workspaces[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 KeyError: pass - return None - - security.declarePublic('getGroupareaURL') - def getGroupareaURL(self, id=None, verifyPermission=0): - """Returns the full URL to the group's work area.""" - ga = self.getGroupareaFolder(id, verifyPermission) - if ga is not None: - return ga.absolute_url() - else: - return None - - security.declarePrivate('wrapGroup') - def wrapGroup(self, g, wrap_anon=0): - ''' Sets up the correct acquisition wrappers for a group - object and provides an opportunity for a portal_memberdata - tool to retrieve and store member data independently of - the user object. - ''' - b = getattr(g, 'aq_base', None) - if b is None: - # u isn't wrapped at all. Wrap it in self.acl_users. - b = g - g = g.__of__(self.acl_users) - if (b is nobody and not wrap_anon) or hasattr(b, 'getMemberId'): - # This user is either not recognized by acl_users or it is - # already registered with something that implements the - # member data tool at least partially. - return g - - parent = self.aq_inner.aq_parent - base = getattr(parent, 'aq_base', None) - if hasattr(base, 'portal_groupdata'): - # Get portal_groupdata to do the wrapping. - Log(LOG_DEBUG, "parent", parent) - gd = getToolByName(parent, 'portal_groupdata') - Log(LOG_DEBUG, "group data", gd) - try: - #log("wrapping group %s" % g) - portal_group = gd.wrapGroup(g) - return portal_group - except ConflictError: - raise - except: - import logging - logger = logging.getLogger('GroupUserFolder.GroupsTool') - logger.exception('Error during wrapGroup') - # Failed. - return g - -InitializeClass(GroupsTool)