Déplacement pour eggification.
[Plinn.git] / Products / Plinn / GroupDataTool.py
diff --git a/Products/Plinn/GroupDataTool.py b/Products/Plinn/GroupDataTool.py
new file mode 100755 (executable)
index 0000000..92617a3
--- /dev/null
@@ -0,0 +1,202 @@
+# -*- 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.   #
+#######################################################################################
+"""
+
+
+"""
+
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+from Acquisition import aq_inner, aq_parent, aq_base
+
+from Products.GroupUserFolder.GroupDataTool import GroupDataTool as BaseTool
+from Products.GroupUserFolder.GroupDataTool import GroupData as BaseGroupData
+from Products.GroupUserFolder.GroupsToolPermissions import ManageGroups, ViewGroups
+from Products.CMFCore.utils import getToolByName
+from ZPublisher.Converters import type_converters
+
+from GroupsTool import CACHE_ROOT_GROUPS, CACHE_GROUPS_OF_GROUP, CACHE_USER_NAMES_OF_GROUP
+
+try:
+       from Products.CMFCore.MemberDataTool import CleanupTemp
+       _have_cleanup_temp = 1
+except:
+       _have_cleanup_temp = None
+
+
+class GroupDataTool(BaseTool) :
+       """ Group Data Tool """
+       
+       meta_type = 'Plinn Group Data Tool'
+       
+       security = ClassSecurityInfo()
+       
+       security.declarePrivate('wrapGroup')
+       def wrapGroup(self, g):
+               """Returns an object implementing the GroupData interface"""
+               id = g.getId()
+               members = self._members
+               if not members.has_key(id):
+                       # Get a temporary member that might be
+                       # registered later via registerMemberData().
+                       temps = self._v_temps
+                       if temps is not None and temps.has_key(id):
+                               portal_group = temps[id]
+                       else:
+                               base = aq_base(self)
+                               portal_group = GroupData(base, id)
+                               if temps is None:
+                                       self._v_temps = {id:portal_group}
+                                       if hasattr(self, 'REQUEST'):
+                                               # No REQUEST during tests.
+                                               # XXX jcc => CleanupTemp doesn't seem to work on Plone 1.0.3.
+                                               # Have to find a way to pass around...
+                                               if _have_cleanup_temp:
+                                                       self.REQUEST._hold(CleanupTemp(self))
+                               else:
+                                       temps[id] = portal_group
+               else:
+                       portal_group = members[id]
+               # Return a wrapper with self as containment and
+               # the user as context.
+               return portal_group.__of__(self).__of__(g)
+
+class GroupData(BaseGroupData) :
+       """      """
+       
+       security = ClassSecurityInfo()
+       
+       security.declareProtected(ViewGroups, 'getGroups')
+       security.declareProtected(ManageGroups, 'setGroupProperties')
+       def setGroupProperties(self, mapping):
+               '''Sets the properties of the group.
+               '''
+               # Sets the properties given in the MemberDataTool.
+               tool = self.getTool()
+               self = self.aq_inner.aq_self
+               for id in tool.propertyIds():
+                       if mapping.has_key(id):
+                               if not self.__class__.__dict__.has_key(id):
+                                       value = mapping[id]
+                                       if type(value)==type(''):
+                                               proptype = tool.getPropertyType(id) or 'string'
+                                               if type_converters.has_key(proptype):
+                                                       value = type_converters[proptype](value)
+                                       setattr(self, id, value)
+               # Hopefully we can later make notifyModified() implicit.
+               self.notifyModified()
+       
+       security.declareProtected(ManageGroups, 'removeMember')
+       def removeMember(self, id):
+               """ Remove the member with the provided id from the group """
+               
+               user = self.acl_users.getUser(id)
+               
+               groups = list(user.getGroups(no_recurse=1))
+               prefix = self.acl_users.getGroupPrefix()
+               try : groups.remove(prefix + self.getGroupName())
+               except ValueError : return # the user (id) is an implicit member of this group (self)
+               
+               roles_no_recurse = tuple(filter(lambda x: x not in ('Authenticated', 'Shared'), user.getUserRoles()))
+               
+               if user.isGroup() :
+                       self.acl_users._doChangeGroup(id, roles_no_recurse, groups = groups)
+               else :
+                       self.acl_users._doChangeUser(id,
+                                                                                None,
+                                                                                roles_no_recurse,
+                                                                                user.getDomains(),
+                                                                                groups=tuple(groups))
+               
+               gtool = getToolByName(self, "portal_groups")
+               if gtool.ZCacheable_isCachingEnabled() :
+                       # humm... there's a bug on Cacheable / RamCacheManger
+                       #gtool.ZCacheable_invalidate(view_name=CACHE_USER_NAMES_OF_GROUP)
+                       gtool.ZCacheable_set(None, view_name=CACHE_USER_NAMES_OF_GROUP, keywords={'no_recurse' : 0})
+                       gtool.ZCacheable_set(None, view_name=CACHE_USER_NAMES_OF_GROUP, keywords={'no_recurse' : 1})
+
+       
+
+       security.declareProtected(ManageGroups, 'addMember')
+       def addMember(self, id):
+               """ Add the existing member with the given id to the group"""
+               aclu = self.aq_inner.acl_users
+               user = aclu.getUser(id)
+               prefix = aclu.getGroupPrefix()
+               
+               userRoles = tuple(filter(lambda x: x not in ('Authenticated', 'Shared'), user.getUserRoles()))
+               groups = user.getGroups(no_recurse = 1)
+               groups += (self.id, )
+               
+               aclu.changeUser(user.id, groups = groups, roles = userRoles)
+               gtool = getToolByName(self, 'portal_groups')
+               if gtool.ZCacheable_isCachingEnabled() :
+                       # humm... there's a bug on Cacheable / RamCacheManger
+                       #gtool.ZCacheable_invalidate(view_name=CACHE_USER_NAMES_OF_GROUP)
+                       gtool.ZCacheable_set(None, view_name=CACHE_USER_NAMES_OF_GROUP, keywords={'no_recurse' : 0})
+                       gtool.ZCacheable_set(None, view_name=CACHE_USER_NAMES_OF_GROUP, keywords={'no_recurse' : 1})
+
+
+
+       security.declareProtected(ManageGroups, 'removeGroup')
+       def removeGroup(self, id) :
+               """ Remove the existing group with the given id to the group"""
+               aclu = self.aq_inner.acl_users
+               groupPrefix = aclu.getGroupPrefix()
+               group = aclu.getGroup(id)
+               
+               # get group roles
+               groupRoles = tuple(filter(lambda x: x not in ('Authenticated', 'Shared'), group.getUserRoles()))
+               superGroupIds = list(group.getGroups(no_recurse = 1))
+               superGroupIds.remove(self.id)
+               
+               aclu.changeUser(groupPrefix + group.id, groups = superGroupIds, roles = groupRoles)
+
+               gtool = getToolByName(self, "portal_groups")
+               if gtool.ZCacheable_isCachingEnabled() :
+                       gtool.ZCacheable_set(None, view_name=CACHE_GROUPS_OF_GROUP)
+                       if not superGroupIds :
+                               gtool.ZCacheable_set(None, view_name=CACHE_ROOT_GROUPS)
+
+
+       security.declareProtected(ManageGroups, 'addGroup')
+       def addGroup(self, id) :
+               """ Add the existing group with the given id to the group"""
+               aclu = self.aq_inner.acl_users
+               groupPrefix = aclu.getGroupPrefix()
+               group = aclu.getGroup(id)
+               
+               # get group roles
+               groupRoles = tuple(filter(lambda x: x not in ('Authenticated', 'Shared'), group.getUserRoles()))
+               superGroupIds = list(group.getGroups(no_recurse = 1))
+               newSuperGroupIds = superGroupIds[:]
+               newSuperGroupIds.append(self.id)
+               
+               aclu.changeUser(groupPrefix + group.id, groups = newSuperGroupIds, roles = groupRoles)
+               
+               gtool = getToolByName(self, "portal_groups")
+               if gtool.ZCacheable_isCachingEnabled() :
+                       gtool.ZCacheable_set(None, view_name=CACHE_GROUPS_OF_GROUP)
+                       if not superGroupIds :
+                               gtool.ZCacheable_set(None, view_name=CACHE_ROOT_GROUPS)
+                               
+
+
+InitializeClass(GroupDataTool)