1 # -*- coding: utf-8 -*-
2 #######################################################################################
3 # Plinn - http://plinn.org #
4 # Copyright (C) 2005-2007 Benoît PIN <benoit.pin@ensmp.fr> #
6 # This program is free software; you can redistribute it and/or #
7 # modify it under the terms of the GNU General Public License #
8 # as published by the Free Software Foundation; either version 2 #
9 # of the License, or (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program; if not, write to the Free Software #
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
19 #######################################################################################
25 from Globals
import InitializeClass
26 from AccessControl
import ClassSecurityInfo
27 from Acquisition
import aq_inner
, aq_parent
, aq_base
29 from Products
.GroupUserFolder
.GroupDataTool
import GroupDataTool
as BaseTool
30 from Products
.GroupUserFolder
.GroupDataTool
import GroupData
as BaseGroupData
31 from Products
.GroupUserFolder
.GroupsToolPermissions
import ManageGroups
, ViewGroups
32 from Products
.CMFCore
.utils
import getToolByName
33 from ZPublisher
.Converters
import type_converters
35 from GroupsTool
import CACHE_ROOT_GROUPS
, CACHE_GROUPS_OF_GROUP
, CACHE_USER_NAMES_OF_GROUP
38 from Products
.CMFCore
.MemberDataTool
import CleanupTemp
39 _have_cleanup_temp
= 1
41 _have_cleanup_temp
= None
44 class GroupDataTool(BaseTool
) :
45 """ Group Data Tool """
47 meta_type
= 'Plinn Group Data Tool'
49 security
= ClassSecurityInfo()
51 security
.declarePrivate('wrapGroup')
52 def wrapGroup(self
, g
):
53 """Returns an object implementing the GroupData interface"""
55 members
= self
._members
56 if not members
.has_key(id):
57 # Get a temporary member that might be
58 # registered later via registerMemberData().
60 if temps
is not None and temps
.has_key(id):
61 portal_group
= temps
[id]
64 portal_group
= GroupData(base
, id)
66 self
._v
_temps
= {id:portal_group
}
67 if hasattr(self
, 'REQUEST'):
68 # No REQUEST during tests.
69 # XXX jcc => CleanupTemp doesn't seem to work on Plone 1.0.3.
70 # Have to find a way to pass around...
71 if _have_cleanup_temp
:
72 self
.REQUEST
._hold
(CleanupTemp(self
))
74 temps
[id] = portal_group
76 portal_group
= members
[id]
77 # Return a wrapper with self as containment and
78 # the user as context.
79 return portal_group
.__of
__(self
).__of
__(g
)
81 class GroupData(BaseGroupData
) :
84 security
= ClassSecurityInfo()
86 security
.declareProtected(ViewGroups
, 'getGroups')
87 security
.declareProtected(ManageGroups
, 'setGroupProperties')
88 def setGroupProperties(self
, mapping
):
89 '''Sets the properties of the group.
91 # Sets the properties given in the MemberDataTool.
93 self
= self
.aq_inner
.aq_self
94 for id in tool
.propertyIds():
95 if mapping
.has_key(id):
96 if not self
.__class
__.__dict
__.has_key(id):
98 if type(value
)==type(''):
99 proptype
= tool
.getPropertyType(id) or 'string'
100 if type_converters
.has_key(proptype
):
101 value
= type_converters
[proptype
](value
)
102 setattr(self
, id, value
)
103 # Hopefully we can later make notifyModified() implicit.
104 self
.notifyModified()
106 security
.declareProtected(ManageGroups
, 'removeMember')
107 def removeMember(self
, id):
108 """ Remove the member with the provided id from the group """
110 user
= self
.acl_users
.getUser(id)
112 groups
= list(user
.getGroups(no_recurse
=1))
113 prefix
= self
.acl_users
.getGroupPrefix()
114 try : groups
.remove(prefix
+ self
.getGroupName())
115 except ValueError : return # the user (id) is an implicit member of this group (self)
117 roles_no_recurse
= tuple(filter(lambda x
: x
not in ('Authenticated', 'Shared'), user
.getUserRoles()))
120 self
.acl_users
._doChangeGroup
(id, roles_no_recurse
, groups
= groups
)
122 self
.acl_users
._doChangeUser
(id,
126 groups
=tuple(groups
))
128 gtool
= getToolByName(self
, "portal_groups")
129 if gtool
.ZCacheable_isCachingEnabled() :
130 # humm... there's a bug on Cacheable / RamCacheManger
131 #gtool.ZCacheable_invalidate(view_name=CACHE_USER_NAMES_OF_GROUP)
132 gtool
.ZCacheable_set(None, view_name
=CACHE_USER_NAMES_OF_GROUP
, keywords
={'no_recurse' : 0})
133 gtool
.ZCacheable_set(None, view_name
=CACHE_USER_NAMES_OF_GROUP
, keywords
={'no_recurse' : 1})
137 security
.declareProtected(ManageGroups
, 'addMember')
138 def addMember(self
, id):
139 """ Add the existing member with the given id to the group"""
140 aclu
= self
.aq_inner
.acl_users
141 user
= aclu
.getUser(id)
142 prefix
= aclu
.getGroupPrefix()
144 userRoles
= tuple(filter(lambda x
: x
not in ('Authenticated', 'Shared'), user
.getUserRoles()))
145 groups
= user
.getGroups(no_recurse
= 1)
146 groups
+= (self
.id, )
148 aclu
.changeUser(user
.id, groups
= groups
, roles
= userRoles
)
149 gtool
= getToolByName(self
, 'portal_groups')
150 if gtool
.ZCacheable_isCachingEnabled() :
151 # humm... there's a bug on Cacheable / RamCacheManger
152 #gtool.ZCacheable_invalidate(view_name=CACHE_USER_NAMES_OF_GROUP)
153 gtool
.ZCacheable_set(None, view_name
=CACHE_USER_NAMES_OF_GROUP
, keywords
={'no_recurse' : 0})
154 gtool
.ZCacheable_set(None, view_name
=CACHE_USER_NAMES_OF_GROUP
, keywords
={'no_recurse' : 1})
158 security
.declareProtected(ManageGroups
, 'removeGroup')
159 def removeGroup(self
, id) :
160 """ Remove the existing group with the given id to the group"""
161 aclu
= self
.aq_inner
.acl_users
162 groupPrefix
= aclu
.getGroupPrefix()
163 group
= aclu
.getGroup(id)
166 groupRoles
= tuple(filter(lambda x
: x
not in ('Authenticated', 'Shared'), group
.getUserRoles()))
167 superGroupIds
= list(group
.getGroups(no_recurse
= 1))
168 superGroupIds
.remove(self
.id)
170 aclu
.changeUser(groupPrefix
+ group
.id, groups
= superGroupIds
, roles
= groupRoles
)
172 gtool
= getToolByName(self
, "portal_groups")
173 if gtool
.ZCacheable_isCachingEnabled() :
174 gtool
.ZCacheable_set(None, view_name
=CACHE_GROUPS_OF_GROUP
)
175 if not superGroupIds
:
176 gtool
.ZCacheable_set(None, view_name
=CACHE_ROOT_GROUPS
)
179 security
.declareProtected(ManageGroups
, 'addGroup')
180 def addGroup(self
, id) :
181 """ Add the existing group with the given id to the group"""
182 aclu
= self
.aq_inner
.acl_users
183 groupPrefix
= aclu
.getGroupPrefix()
184 group
= aclu
.getGroup(id)
187 groupRoles
= tuple(filter(lambda x
: x
not in ('Authenticated', 'Shared'), group
.getUserRoles()))
188 superGroupIds
= list(group
.getGroups(no_recurse
= 1))
189 newSuperGroupIds
= superGroupIds
[:]
190 newSuperGroupIds
.append(self
.id)
192 aclu
.changeUser(groupPrefix
+ group
.id, groups
= newSuperGroupIds
, roles
= groupRoles
)
194 gtool
= getToolByName(self
, "portal_groups")
195 if gtool
.ZCacheable_isCachingEnabled() :
196 gtool
.ZCacheable_set(None, view_name
=CACHE_GROUPS_OF_GROUP
)
197 if not superGroupIds
:
198 gtool
.ZCacheable_set(None, view_name
=CACHE_ROOT_GROUPS
)
202 InitializeClass(GroupDataTool
)