propagation of role permission settings from workspaces basically working

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3623 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-11-10 18:19:49 +00:00
parent fdd7f8637b
commit 87f46f0d28
14 changed files with 406 additions and 176 deletions

View file

@ -165,16 +165,6 @@ class Concept(Contained, Persistent):
pi.relations.append(rel) pi.relations.append(rel)
return result return result
@property
def isWorkspace(self):
ct = self.conceptType
if ct != self.getConceptManager().getTypeConcept():
from loops.config.base import DummyOptions
options = component.queryAdapter(adapted(self), IOptions) or DummyOptions()
if options('security.isWorkspace'):
return True
return IOptions(adapted(ct))('security.isWorkspace')
# concept relations # concept relations
def getClients(self, relationships=None): def getClients(self, relationships=None):

View file

@ -25,7 +25,7 @@ $Id$
from zope.interface import Interface, Attribute from zope.interface import Interface, Attribute
from zope import interface, component, schema from zope import interface, component, schema
from loops.interfaces import IConceptSchema from loops.interfaces import IConceptSchema, ILoopsAdapter
from loops.util import _ from loops.util import _
@ -41,7 +41,7 @@ class IExternalSourceInfo(Interface):
# external collections # external collections
class IExternalCollection(IConceptSchema): class IExternalCollection(IConceptSchema, ILoopsAdapter):
""" A concept representing a collection of resources that may be """ A concept representing a collection of resources that may be
actively retrieved from an external system using the parameters actively retrieved from an external system using the parameters
given. given.

View file

@ -104,12 +104,8 @@ class IConcept(IConceptSchema, ILoopsObject, IPotentialTarget):
source="loops.conceptTypeSource", source="loops.conceptTypeSource",
required=True) required=True)
isWorkspace = Attribute('Marks a concept as responsible for providing '
'special permission settings (children grants) '
'for its sub-objects (children or resources).')
workspaceInformation = Attribute('An object with additional ' workspaceInformation = Attribute('An object with additional '
'workspace-related information, e.g. children grants.') 'workspace-related information.')
def getType(): def getType():
""" Return a concept that provides the object's type. """ Return a concept that provides the object's type.

View file

@ -34,6 +34,7 @@ from cybertools.organize.interfaces import IPerson as IBasePerson
from cybertools.organize.interfaces import ITask from cybertools.organize.interfaces import ITask
from loops.interfaces import IConceptSchema from loops.interfaces import IConceptSchema
from loops.organize.util import getPrincipalFolder from loops.organize.util import getPrincipalFolder
from loops.interfaces import ILoopsAdapter
from loops import util from loops import util
from loops.util import _ from loops.util import _
@ -87,7 +88,7 @@ class LoginName(schema.TextLine):
mapping=dict(userId=userId))) mapping=dict(userId=userId)))
class IPerson(IConceptSchema, IBasePerson): class IPerson(IConceptSchema, IBasePerson, ILoopsAdapter):
""" Resembles a human being with a name (first and last name), """ Resembles a human being with a name (first and last name),
a birth date, and a set of addresses. This interface only a birth date, and a set of addresses. This interface only
lists fields used in addition to those provided by the lists fields used in addition to those provided by the
@ -101,7 +102,7 @@ class IPerson(IConceptSchema, IBasePerson):
required=False,) required=False,)
class IAddress(IConceptSchema, IBaseAddress): class IAddress(IConceptSchema, IBaseAddress, ILoopsAdapter):
""" See cybertools.organize. """ See cybertools.organize.
""" """
@ -158,7 +159,7 @@ class IMemberRegistrationManager(Interface):
# task # task
class ITask(IConceptSchema, ITask): class ITask(IConceptSchema, ITask, ILoopsAdapter):
pass pass

View file

@ -23,18 +23,150 @@ $Id$
""" """
from zope.app.pagetemplate import ViewPageTemplateFile from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.security.interfaces import IPermission
from zope.app.securitypolicy.browser import granting
from zope.app.securitypolicy.browser.rolepermissionview import RolePermissionView
from zope.app.securitypolicy.interfaces import IPrincipalRoleManager, \
IRolePermissionMap
from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager, \
IPrincipalPermissionMap
from zope.app.securitypolicy.zopepolicy import SettingAsBoolean
from zope import component from zope import component
from zope.interface import implements from zope.interface import implements
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from zope.traversing.api import getParent, getParents
from loops.common import adapted
from loops.security.common import WorkspaceInformation from loops.security.common import WorkspaceInformation
from loops.security.perm import PermissionView from loops.security.interfaces import ISecuritySetter
permission_template = ViewPageTemplateFile('manage_permissionform.pt') permission_template = ViewPageTemplateFile('manage_permissionform.pt')
class Granting(granting.Granting):
def status(self):
value = super(Granting, self).status()
if value:
setter = ISecuritySetter(adapted(self.context), None)
if setter is not None:
setter.propagatePrincipalRoles()
return value
class PermissionView(object):
""" View for permission editing.
"""
def __init__(self, context, request):
self.context = context
# make sure the real view (delegate) updates our context when
# talking about the context's parent:
self.__parent__ = context
self.request = request
self.delegate = RolePermissionView()
self.delegate.context = self
self.delegate.request = request
self.permissionId = request.get('permission_to_manage') or 'zope.View'
def pagetip(self):
return self.delegate.pagetip()
def roles(self):
return self.delegate.roles()
def permissions(self):
return self.delegate.permissions()
def availableSettings(self, noacquire=False):
return self.delegate.availableSettings(noacquire)
def permissionRoles(self):
return self.delegate.permissionRoles()
def permissionForID(self, pid):
return self.delegate.permissionForID(pid)
@Lazy
def permission(self):
return self.permissionForID(self.permissionId)
def roleForID(self, rid):
return self.delegate.roleForID(rid)
def update(self, testing=None):
value = self.delegate.update(testing)
if value:
setter = ISecuritySetter(self.adapted, None)
if setter is not None:
setter.propagateRolePermissions()
return value
@Lazy
def adapted(self):
return adapted(self.context)
def getAcquiredPermissionSetting(self, role, perm):
for obj in getParents(self.context):
rpm = IRolePermissionMap(obj, None)
if rpm is not None:
setting = rpm.getSetting(perm, role)
setting = SettingAsBoolean[setting]
if setting is not None:
return setting and '+' or '-'
return ''
def listUsersForRole(self, rid):
result = ''
direct = IPrincipalRoleManager(self.context).getPrincipalsForRole(rid)
if direct:
result = '<strong>' + self.renderEntry(direct) + '</strong>'
acquired = []
for obj in getParents(self.context):
prm = IPrincipalRoleManager(obj, None)
if prm is not None:
entry = prm.getPrincipalsForRole(rid)
if entry:
acquired.append(self.renderEntry(entry))
if acquired:
if result:
result += '<br />'
result += '<br />'.join(acquired)
return result
def renderEntry(self, entry):
result = []
for e in entry:
value = SettingAsBoolean[e[1]]
value = (value is False and '-') or (value and '+') or ''
result.append(value + e[0])
return ', '.join(result)
def getPrincipalPermissions(self):
result = ''
ppm = IPrincipalPermissionMap(self.context)
direct = ppm.getPrincipalsForPermission(self.permissionId)
if direct:
result = '<strong>' + self.renderEntry(direct) + '</strong>'
acquired = []
for obj in getParents(self.context):
ppm = IPrincipalPermissionMap(obj, None)
if ppm is not None:
entry = ppm.getPrincipalsForPermission(self.permissionId)
if entry:
acquired.append(self.renderEntry(entry))
if acquired:
if result:
result += '<br />'
result += '<br />'.join(acquired)
return result
def getPermissions(self):
return sorted(name for name, perm in component.getUtilitiesFor(IPermission))
class ManageWorkspaceView(PermissionView): class ManageWorkspaceView(PermissionView):
""" View for managing workspace information. """ View for managing workspace information.
""" """
@ -49,3 +181,9 @@ class ManageWorkspaceView(PermissionView):
@Lazy @Lazy
def permission_macros(self): def permission_macros(self):
return permission_template.macros return permission_template.macros
@Lazy
def adapted(self):
return adapted(getParent(self.context))

View file

@ -23,9 +23,11 @@ $Id$
""" """
from persistent import Persistent from persistent import Persistent
from persistent.list import PersistentList
from zope import component from zope import component
from zope.annotation.interfaces import IAttributeAnnotatable from zope.annotation.interfaces import IAttributeAnnotatable
from zope.app.container.interfaces import IObjectAddedEvent from zope.app.container.interfaces import IObjectAddedEvent
from zope.app.security.settings import Allow, Deny, Unset
from zope.app.securitypolicy.interfaces import IPrincipalRoleManager from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
from zope.app.securitypolicy.interfaces import IRolePermissionManager from zope.app.securitypolicy.interfaces import IRolePermissionManager
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
@ -39,7 +41,7 @@ from zope.traversing.interfaces import IPhysicallyLocatable
from loops.common import adapted from loops.common import adapted
from loops.interfaces import ILoopsObject, IConcept from loops.interfaces import ILoopsObject, IConcept
from loops.interfaces import IAssignmentEvent, IDeassignmentEvent from loops.interfaces import IAssignmentEvent, IDeassignmentEvent
from loops.security.interfaces import ISecuritySetter from loops.security.interfaces import ISecuritySetter, IWorkspaceInformation
allRolesExceptOwner = ( allRolesExceptOwner = (
@ -81,7 +83,20 @@ def getCurrentPrincipal():
return None return None
# functions for setting security properties # functions for checking and setting security properties
def overrides(s1, s2):
settings = [Allow, Deny, Unset]
return settings.index(s1) < settings.index(s2)
def setRolePermission(rpm, p, r, setting):
if setting == Allow:
rpm.grantPermissionToRole(p, r)
elif setting == Deny:
rpm.denyPermissionToRole(p, r)
else:
rpm.unsetPermissionFromRole(p, r)
def assignOwner(obj, principalId): def assignOwner(obj, principalId):
prm = IPrincipalRoleManager(obj) prm = IPrincipalRoleManager(obj)
@ -149,12 +164,16 @@ class WorkspaceInformation(Persistent):
children and resources of the context (=parent) object. children and resources of the context (=parent) object.
""" """
implements(IPhysicallyLocatable) implements(IPhysicallyLocatable, IWorkspaceInformation)
__name__ = u'workspace_information' __name__ = u'workspace_information'
propagatePrincipalRoles = False
propagateRolePermissions = 'workspace'
def __init__(self, parent): def __init__(self, parent):
self.__parent__ = parent self.__parent__ = parent
self.workspaceGroups = PersistentList()
def getName(self): def getName(self):
return self.__name__ return self.__name__

View file

@ -9,6 +9,9 @@
<zope:class class="loops.security.common.WorkspaceInformation"> <zope:class class="loops.security.common.WorkspaceInformation">
<implements interface="zope.annotation.interfaces.IAttributeAnnotatable" /> <implements interface="zope.annotation.interfaces.IAttributeAnnotatable" />
<allow interface="loops.security.interfaces.IWorkspaceInformation" />
<require set_schema="loops.security.interfaces.IWorkspaceInformation"
permission="zope.Security"/>
</zope:class> </zope:class>
<zope:adapter <zope:adapter
@ -24,6 +27,9 @@
factory="zope.app.securitypolicy.rolepermission.AnnotationRolePermissionManager" factory="zope.app.securitypolicy.rolepermission.AnnotationRolePermissionManager"
trusted="true" /> trusted="true" />
<zope:adapter factory="loops.security.setter.ConceptSecuritySetter" />
<zope:adapter factory="loops.security.setter.ResourceSecuritySetter" />
<zope:subscriber handler="loops.security.common.setDefaultSecurity" /> <zope:subscriber handler="loops.security.common.setDefaultSecurity" />
<zope:subscriber handler="loops.security.common.grantAcquiredSecurity" /> <zope:subscriber handler="loops.security.common.grantAcquiredSecurity" />
<zope:subscriber handler="loops.security.common.revokeAcquiredSecurity" /> <zope:subscriber handler="loops.security.common.revokeAcquiredSecurity" />
@ -33,9 +39,17 @@
name="permissions.html" name="permissions.html"
permission="zope.Security" permission="zope.Security"
template="manage_permissionform.pt" template="manage_permissionform.pt"
class="loops.security.perm.PermissionView" class="loops.security.browser.PermissionView"
menu="zmi_actions" title="Edit Permissions" /> menu="zmi_actions" title="Edit Permissions" />
<browser:page
for="loops.interfaces.IConcept"
name="grant.html"
permission="zope.Security"
template="granting.pt"
class="loops.security.browser.Granting"
menu="zmi_actions" title="Grant" />
<browser:page <browser:page
for="loops.interfaces.IConcept" for="loops.interfaces.IConcept"
name="manage_workspace.html" name="manage_workspace.html"

85
security/granting.pt Normal file
View file

@ -0,0 +1,85 @@
<html metal:use-macro="context/@@standard_macros/view"
i18n:domain="zope">
<body>
<div metal:fill-slot="body" i18n:domain="zope">
<h2 i18n:translate="">Granting Roles and Permissions to Principals</h2>
<p tal:define="status view/status"
tal:condition="status"
tal:content="status" i18n:translate=""/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<form action="" method="POST">
<div tal:content="structure view/principal_widget">...</div>
<div tal:condition="view/principal">
<h2 i18n:translate="">Grants for the selected principal</h2>
<input type="submit" name="GRANT_SUBMIT" value="Change"
i18n:attributes="value grant-submit" />
<table width="100%" border="0">
<tr>
<td valign="top">
<table class="matrix">
<tr>
<td i18n:translate=""><strong>Roles</strong>&nbsp;</td>
<td i18n:translate=""><strong>Allow</strong>&nbsp;</td>
<td i18n:translate=""><strong>Unset</strong>&nbsp;</td>
<td i18n:translate=""><strong>Deny</strong>&nbsp;</td>
</tr>
<tr tal:repeat="widget view/roles">
<td valign="top" nowrap>
<div class="label">
<label for="field.name" title="The widget's hint"
tal:attributes="for widget/name; title widget/hint"
tal:content="widget/label"
i18n:translate="">The Label</label>
</div>
</td>
<tal:block tal:content="structure widget">
roles widget
</tal:block>
</tr>
<tr>
<td colspan="2"><a href="#top" i18n:translate="">^ top</a></td>
</tr>
</table>
</td>
<td valign="top">
<table class="matrix">
<tr>
<td i18n:translate=""><strong>Permissions</strong>&nbsp;</td>
<td i18n:translate=""><strong>Allow</strong>&nbsp;</td>
<td i18n:translate=""><strong>Unset</strong>&nbsp;</td>
<td i18n:translate=""><strong>Deny</strong>&nbsp;</td>
</tr>
<tr tal:repeat="widget view/permissions">
<td valign="top" nowrap>
<div class="label">
<label for="field.name" title="The widget's hint"
tal:attributes="for widget/name; title widget/hint"
tal:content="widget/label"
i18n:translate="">The Label</label>
</div>
</td>
<tal:block tal:content="structure widget">
permission widget
</tal:block>
</tr>
<tr>
<td colspan="2"><a href="#top" i18n:translate="">^ top</a></td>
</tr>
</table>
</td>
</tr>
</table>
<input type="submit" name="GRANT_SUBMIT" value="Change"
i18n:attributes="value grant-submit" />
</div>
</form>
</div>
</body>
</html>

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # Copyright (c) 2009 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -40,15 +40,46 @@ class ISecuritySetter(Interface):
(e.g. the user that created the object). (e.g. the user that created the object).
""" """
def setAcquiredRolePermissions(relation, revert=False): def acquireRolePermissions():
""" Check (immediate) parents's settings and set role permission
assignments on the context object accordingly.
"""
def setAcquiredRolePermissions(relation, revert=False, updated=None):
""" Grant role permissions on children/resources for the relation given. """ Grant role permissions on children/resources for the relation given.
If the ``revert`` argument is true unset the corresponding settings. If the ``revert`` argument is true unset the corresponding settings.
Do not update objects in the ``updated`` collection if present.
""" """
def setAcquiredPrincipalRoles(relation, revert=False): def setAcquiredPrincipalRoles(relation, revert=False, updated=None):
""" Assign roles on children/resources for the relation given. """ Assign roles on children/resources for the relation given.
If the ``revert`` argument is true unset the corresponding settings. If the ``revert`` argument is true unset the corresponding settings.
Do not update objects in the ``updated`` collection if present.
""" """
def propagateRolePermissions(updated=None):
""" Update role permissions on all sub-objects according to the
current setting of the context object.
Ignore objects in the ``updated`` collection if present.
"""
def propagatePrincipalRoles(updated=None):
""" Update roles on all sub-objects according to the
current setting of the context object.
Ignore objects in the ``updated`` collection if present.
"""
class IWorkspaceInformation(Interface):
""" Additional information belonging to a concept that controls
security-related stuff for sub-objects.
"""
propagatePrincipalRoles = Attribute('Should acquired principal roles be '
'propagated to children?')
propagateRolePermissions = Attribute('Which role permissions should be '
'propagated to children?')

View file

@ -3,10 +3,9 @@
<body> <body>
<div metal:fill-slot="body"> <div metal:fill-slot="body">
<h2 i18n:translate="">Assign Permissions to Roles</h2>
<p tal:define="status view/update" <p tal:define="status view/update"
tal:condition="status" tal:content="status" i18n:translate="" />
tal:content="status"
i18n:translate="" />
<div metal:define-macro="permission_form" <div metal:define-macro="permission_form"
tal:define="permId view/permissionId; tal:define="permId view/permissionId;

View file

@ -4,8 +4,7 @@
<div metal:fill-slot="body" i18n:domain="zope"> <div metal:fill-slot="body" i18n:domain="zope">
<h2 i18n:translate="">Assign Permissions to Roles for Children of this Object</h2> <h2 i18n:translate="">Assign Permissions to Roles for Children of this Object</h2>
<p tal:define="status view/update" <p tal:define="status view/update"
tal:condition="status" tal:content="status" i18n:translate=""/>
tal:content="status" i18n:translate=""/><br />
<metal:permissions use-macro="view/permission_macros/permission_form" /> <metal:permissions use-macro="view/permission_macros/permission_form" />

View file

@ -1,139 +0,0 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Authentication view.
$Id$
"""
from zope import component
from zope.interface import implements
from zope.cachedescriptors.property import Lazy
from zope.app.security.interfaces import IPermission
from zope.app.securitypolicy.browser.granting import Granting
from zope.app.securitypolicy.browser.rolepermissionview import RolePermissionView
from zope.app.securitypolicy.interfaces import IPrincipalRoleManager, IRolePermissionMap
from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager, \
IPrincipalPermissionMap
from zope.app.securitypolicy.zopepolicy import SettingAsBoolean
from zope.security.proxy import removeSecurityProxy
from zope.traversing.api import getParents
class PermissionView(object):
""" View for permission editing.
"""
def __init__(self, context, request):
self.context = context
# make sure the real view (delegate) updates our context when
# talking about the context's parent:
self.__parent__ = context
self.request = request
self.delegate = RolePermissionView()
self.delegate.context = self
self.delegate.request = request
self.permissionId = request.get('permission_to_manage') or 'zope.View'
def pagetip(self):
return self.delegate.pagetip()
def roles(self):
return self.delegate.roles()
def permissions(self):
return self.delegate.permissions()
def availableSettings(self, noacquire=False):
return self.delegate.availableSettings(noacquire)
def permissionRoles(self):
return self.delegate.permissionRoles()
def permissionForID(self, pid):
return self.delegate.permissionForID(pid)
@Lazy
def permission(self):
return self.permissionForID(self.permissionId)
def roleForID(self, rid):
return self.delegate.roleForID(rid)
def update(self, testing=None):
return self.delegate.update(testing)
def getAcquiredPermissionSetting(self, role, perm):
for obj in getParents(self.context):
rpm = IRolePermissionMap(obj, None)
if rpm is not None:
setting = rpm.getSetting(perm, role)
setting = SettingAsBoolean[setting]
if setting is not None:
return setting and '+' or '-'
return ''
def listUsersForRole(self, rid):
result = ''
direct = IPrincipalRoleManager(self.context).getPrincipalsForRole(rid)
if direct:
result = '<strong>' + self.renderEntry(direct) + '</strong>'
acquired = []
for obj in getParents(self.context):
prm = IPrincipalRoleManager(obj, None)
if prm is not None:
entry = prm.getPrincipalsForRole(rid)
if entry:
acquired.append(self.renderEntry(entry))
if acquired:
if result:
result += '<br />'
result += '<br />'.join(acquired)
return result
def renderEntry(self, entry):
result = []
for e in entry:
value = SettingAsBoolean[e[1]]
value = (value is False and '-') or (value and '+') or ''
result.append(value + e[0])
return ', '.join(result)
def getPrincipalPermissions(self):
result = ''
ppm = IPrincipalPermissionMap(self.context)
direct = ppm.getPrincipalsForPermission(self.permissionId)
if direct:
result = '<strong>' + self.renderEntry(direct) + '</strong>'
acquired = []
for obj in getParents(self.context):
ppm = IPrincipalPermissionMap(obj, None)
if ppm is not None:
entry = ppm.getPrincipalsForPermission(self.permissionId)
if entry:
acquired.append(self.renderEntry(entry))
if acquired:
if result:
result += '<br />'
result += '<br />'.join(acquired)
return result
def getPermissions(self):
return sorted(name for name, perm in component.getUtilitiesFor(IPermission))

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # Copyright (c) 2009 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -23,11 +23,18 @@ methods for setting role permissions and other security-related stuff.
$Id$ $Id$
""" """
from zope.app.security.settings import Allow, Deny, Unset
from zope.app.securitypolicy.interfaces import IRolePermissionMap
from zope.app.securitypolicy.interfaces import IRolePermissionManager
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.interface import implements, Interface from zope.interface import implements, Interface
from zope.security.proxy import isinstance
from loops.common import adapted, AdapterBase
from loops.security.common import overrides, setRolePermission
from loops.interfaces import IConceptSchema, IBaseResourceSchema, ILoopsAdapter
from loops.security.interfaces import ISecuritySetter from loops.security.interfaces import ISecuritySetter
@ -45,8 +52,95 @@ class BaseSecuritySetter(object):
def setDefaultPrincipalRoles(self): def setDefaultPrincipalRoles(self):
pass pass
def setAcquiredRolePermissions(self, relation, revert=False): def acquireRolePermissions(self):
pass pass
def setAcquiredPrincipalRoles(self, relation, revert=False): def setAcquiredRolePermissions(self, relation, revert=False, updated=None):
pass pass
def setAcquiredPrincipalRoles(self, relation, revert=False, updated=None):
pass
def propagateRolePermissions(self, updated=None):
pass
def propagatePrincipalRoles(self, updated=None):
pass
class LoopsObjectSecuritySetter(BaseSecuritySetter):
@Lazy
def baseObject(self):
obj = self.context
if isinstance(obj, AdapterBase):
obj = obj.context
return obj
def acquireRolePermissions(self):
obj = self.baseObject
if isinstance(obj, AdapterBase):
obj = obj.context
settings = {}
for p in self.parents:
if p == obj:
continue
secProvider = p
wi = p.workspaceInformation
if wi:
if wi.propagateRolePermissions == 'none':
continue
if wi.propagateRolePermissions == 'workspace':
secProvider = wi
rpm = IRolePermissionMap(secProvider)
for p, r, s in rpm.getRolesAndPermissions():
current = settings.get((p, r))
if current is None or overrides(s, current):
settings[(p, r)] = s
rpm = IRolePermissionManager(obj)
for p, r, s in rpm.getRolesAndPermissions():
# clear previous settings
setRolePermission(rpm, p, r, Unset)
for (p, r), s in settings.items():
setRolePermission(rpm, p, r, s)
class ConceptSecuritySetter(LoopsObjectSecuritySetter):
adapts(IConceptSchema)
def setAcquiredRolePermissions(self, relation, revert=False, updated=None):
if updated and relation.second in updated:
return
setter = ISecuritySetter(adapted(relation.second), None)
if setter is not None:
setter.acquireRolePermissions()
setter.propagateRolePermissions(updated)
def setAcquiredPrincipalRoles(self, relation, revert=False, updated=None):
pass
def propagateRolePermissions(self, updated=None):
if updated is None:
updated = set()
obj = self.baseObject
updated.add(obj)
for r in obj.getChildRelations():
self.setAcquiredRolePermissions(r, updated=updated)
def propagatePrincipalRoles(self, updated=None):
pass
@Lazy
def parents(self):
return self.baseObject.getParents()
class ResourceSecuritySetter(LoopsObjectSecuritySetter):
adapts(IBaseResourceSchema)
@Lazy
def parents(self):
return self.baseObject.getConcepts()

View file

@ -26,6 +26,7 @@ from zope.dublincore.interfaces import IZopeDublinCore
from zope.interface import Interface, implements from zope.interface import Interface, implements
from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserView from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserView
from zope.security.checker import Checker, defineChecker from zope.security.checker import Checker, defineChecker
from zope.security.management import setSecurityPolicy
from cybertools.browser.controller import Controller from cybertools.browser.controller import Controller
from cybertools.catalog.keyword import KeywordIndex from cybertools.catalog.keyword import KeywordIndex
@ -71,9 +72,9 @@ from loops.schema.factory import ResourceSchemaFactory, FileSchemaFactory, \
NoteSchemaFactory NoteSchemaFactory
from loops.schema.field import RelationSetFieldInstance from loops.schema.field import RelationSetFieldInstance
from loops.security.common import grantAcquiredSecurity, revokeAcquiredSecurity from loops.security.common import grantAcquiredSecurity, revokeAcquiredSecurity
from zope.security.management import setSecurityPolicy
from loops.security.policy import LoopsSecurityPolicy from loops.security.policy import LoopsSecurityPolicy
from loops.security.setter import BaseSecuritySetter from loops.security.setter import BaseSecuritySetter
from loops.security.setter import ConceptSecuritySetter, ResourceSecuritySetter
from loops.setup import SetupManager, addObject from loops.setup import SetupManager, addObject
from loops.type import LoopsType, ConceptType, ResourceType, TypeConcept from loops.type import LoopsType, ConceptType, ResourceType, TypeConcept
from loops.view import Node, NodeAdapter from loops.view import Node, NodeAdapter
@ -135,6 +136,8 @@ class TestSite(object):
component.provideHandler(grantAcquiredSecurity) component.provideHandler(grantAcquiredSecurity)
component.provideHandler(revokeAcquiredSecurity) component.provideHandler(revokeAcquiredSecurity)
component.provideAdapter(BaseSecuritySetter) component.provideAdapter(BaseSecuritySetter)
component.provideAdapter(ConceptSecuritySetter)
component.provideAdapter(ResourceSecuritySetter)
component.provideAdapter(LoopsOptions) component.provideAdapter(LoopsOptions)
component.provideAdapter(QueryOptions) component.provideAdapter(QueryOptions)
component.provideAdapter(TypeOptions) component.provideAdapter(TypeOptions)