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:
parent
fdd7f8637b
commit
87f46f0d28
14 changed files with 406 additions and 176 deletions
10
concept.py
10
concept.py
|
@ -165,16 +165,6 @@ class Concept(Contained, Persistent):
|
|||
pi.relations.append(rel)
|
||||
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
|
||||
|
||||
def getClients(self, relationships=None):
|
||||
|
|
|
@ -25,7 +25,7 @@ $Id$
|
|||
from zope.interface import Interface, Attribute
|
||||
from zope import interface, component, schema
|
||||
|
||||
from loops.interfaces import IConceptSchema
|
||||
from loops.interfaces import IConceptSchema, ILoopsAdapter
|
||||
from loops.util import _
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ class IExternalSourceInfo(Interface):
|
|||
|
||||
# external collections
|
||||
|
||||
class IExternalCollection(IConceptSchema):
|
||||
class IExternalCollection(IConceptSchema, ILoopsAdapter):
|
||||
""" A concept representing a collection of resources that may be
|
||||
actively retrieved from an external system using the parameters
|
||||
given.
|
||||
|
|
|
@ -104,12 +104,8 @@ class IConcept(IConceptSchema, ILoopsObject, IPotentialTarget):
|
|||
source="loops.conceptTypeSource",
|
||||
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 '
|
||||
'workspace-related information, e.g. children grants.')
|
||||
'workspace-related information.')
|
||||
|
||||
def getType():
|
||||
""" Return a concept that provides the object's type.
|
||||
|
|
|
@ -34,6 +34,7 @@ from cybertools.organize.interfaces import IPerson as IBasePerson
|
|||
from cybertools.organize.interfaces import ITask
|
||||
from loops.interfaces import IConceptSchema
|
||||
from loops.organize.util import getPrincipalFolder
|
||||
from loops.interfaces import ILoopsAdapter
|
||||
from loops import util
|
||||
from loops.util import _
|
||||
|
||||
|
@ -87,7 +88,7 @@ class LoginName(schema.TextLine):
|
|||
mapping=dict(userId=userId)))
|
||||
|
||||
|
||||
class IPerson(IConceptSchema, IBasePerson):
|
||||
class IPerson(IConceptSchema, IBasePerson, ILoopsAdapter):
|
||||
""" Resembles a human being with a name (first and last name),
|
||||
a birth date, and a set of addresses. This interface only
|
||||
lists fields used in addition to those provided by the
|
||||
|
@ -101,7 +102,7 @@ class IPerson(IConceptSchema, IBasePerson):
|
|||
required=False,)
|
||||
|
||||
|
||||
class IAddress(IConceptSchema, IBaseAddress):
|
||||
class IAddress(IConceptSchema, IBaseAddress, ILoopsAdapter):
|
||||
""" See cybertools.organize.
|
||||
"""
|
||||
|
||||
|
@ -158,7 +159,7 @@ class IMemberRegistrationManager(Interface):
|
|||
|
||||
# task
|
||||
|
||||
class ITask(IConceptSchema, ITask):
|
||||
class ITask(IConceptSchema, ITask, ILoopsAdapter):
|
||||
|
||||
pass
|
||||
|
||||
|
|
|
@ -23,18 +23,150 @@ $Id$
|
|||
"""
|
||||
|
||||
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.interface import implements
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
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.perm import PermissionView
|
||||
from loops.security.interfaces import ISecuritySetter
|
||||
|
||||
|
||||
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):
|
||||
""" View for managing workspace information.
|
||||
"""
|
||||
|
@ -49,3 +181,9 @@ class ManageWorkspaceView(PermissionView):
|
|||
@Lazy
|
||||
def permission_macros(self):
|
||||
return permission_template.macros
|
||||
|
||||
@Lazy
|
||||
def adapted(self):
|
||||
return adapted(getParent(self.context))
|
||||
|
||||
|
||||
|
|
|
@ -23,9 +23,11 @@ $Id$
|
|||
"""
|
||||
|
||||
from persistent import Persistent
|
||||
from persistent.list import PersistentList
|
||||
from zope import component
|
||||
from zope.annotation.interfaces import IAttributeAnnotatable
|
||||
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 IRolePermissionManager
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
|
@ -39,7 +41,7 @@ from zope.traversing.interfaces import IPhysicallyLocatable
|
|||
from loops.common import adapted
|
||||
from loops.interfaces import ILoopsObject, IConcept
|
||||
from loops.interfaces import IAssignmentEvent, IDeassignmentEvent
|
||||
from loops.security.interfaces import ISecuritySetter
|
||||
from loops.security.interfaces import ISecuritySetter, IWorkspaceInformation
|
||||
|
||||
|
||||
allRolesExceptOwner = (
|
||||
|
@ -81,7 +83,20 @@ def getCurrentPrincipal():
|
|||
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):
|
||||
prm = IPrincipalRoleManager(obj)
|
||||
|
@ -149,12 +164,16 @@ class WorkspaceInformation(Persistent):
|
|||
children and resources of the context (=parent) object.
|
||||
"""
|
||||
|
||||
implements(IPhysicallyLocatable)
|
||||
implements(IPhysicallyLocatable, IWorkspaceInformation)
|
||||
|
||||
__name__ = u'workspace_information'
|
||||
|
||||
propagatePrincipalRoles = False
|
||||
propagateRolePermissions = 'workspace'
|
||||
|
||||
def __init__(self, parent):
|
||||
self.__parent__ = parent
|
||||
self.workspaceGroups = PersistentList()
|
||||
|
||||
def getName(self):
|
||||
return self.__name__
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
<zope:class class="loops.security.common.WorkspaceInformation">
|
||||
<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:adapter
|
||||
|
@ -24,6 +27,9 @@
|
|||
factory="zope.app.securitypolicy.rolepermission.AnnotationRolePermissionManager"
|
||||
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.grantAcquiredSecurity" />
|
||||
<zope:subscriber handler="loops.security.common.revokeAcquiredSecurity" />
|
||||
|
@ -33,9 +39,17 @@
|
|||
name="permissions.html"
|
||||
permission="zope.Security"
|
||||
template="manage_permissionform.pt"
|
||||
class="loops.security.perm.PermissionView"
|
||||
class="loops.security.browser.PermissionView"
|
||||
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
|
||||
for="loops.interfaces.IConcept"
|
||||
name="manage_workspace.html"
|
||||
|
|
85
security/granting.pt
Normal file
85
security/granting.pt
Normal 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=""/>
|
||||
|
||||
|
||||
|
||||
<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> </td>
|
||||
<td i18n:translate=""><strong>Allow</strong> </td>
|
||||
<td i18n:translate=""><strong>Unset</strong> </td>
|
||||
<td i18n:translate=""><strong>Deny</strong> </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> </td>
|
||||
<td i18n:translate=""><strong>Allow</strong> </td>
|
||||
<td i18n:translate=""><strong>Unset</strong> </td>
|
||||
<td i18n:translate=""><strong>Deny</strong> </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>
|
|
@ -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
|
||||
# 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).
|
||||
"""
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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?')
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
|
||||
<body>
|
||||
<div metal:fill-slot="body">
|
||||
<h2 i18n:translate="">Assign Permissions to Roles</h2>
|
||||
<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"
|
||||
tal:define="permId view/permissionId;
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
<div metal:fill-slot="body" i18n:domain="zope">
|
||||
<h2 i18n:translate="">Assign Permissions to Roles for Children of this Object</h2>
|
||||
<p tal:define="status view/update"
|
||||
tal:condition="status"
|
||||
tal:content="status" i18n:translate=""/><br />
|
||||
tal:content="status" i18n:translate=""/>
|
||||
|
||||
<metal:permissions use-macro="view/permission_macros/permission_form" />
|
||||
|
||||
|
|
139
security/perm.py
139
security/perm.py
|
@ -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))
|
||||
|
|
@ -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
|
||||
# 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$
|
||||
"""
|
||||
|
||||
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.component import adapts
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
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
|
||||
|
||||
|
||||
|
@ -45,8 +52,95 @@ class BaseSecuritySetter(object):
|
|||
def setDefaultPrincipalRoles(self):
|
||||
pass
|
||||
|
||||
def setAcquiredRolePermissions(self, relation, revert=False):
|
||||
def acquireRolePermissions(self):
|
||||
pass
|
||||
|
||||
def setAcquiredPrincipalRoles(self, relation, revert=False):
|
||||
def setAcquiredRolePermissions(self, relation, revert=False, updated=None):
|
||||
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()
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ from zope.dublincore.interfaces import IZopeDublinCore
|
|||
from zope.interface import Interface, implements
|
||||
from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserView
|
||||
from zope.security.checker import Checker, defineChecker
|
||||
from zope.security.management import setSecurityPolicy
|
||||
|
||||
from cybertools.browser.controller import Controller
|
||||
from cybertools.catalog.keyword import KeywordIndex
|
||||
|
@ -71,9 +72,9 @@ from loops.schema.factory import ResourceSchemaFactory, FileSchemaFactory, \
|
|||
NoteSchemaFactory
|
||||
from loops.schema.field import RelationSetFieldInstance
|
||||
from loops.security.common import grantAcquiredSecurity, revokeAcquiredSecurity
|
||||
from zope.security.management import setSecurityPolicy
|
||||
from loops.security.policy import LoopsSecurityPolicy
|
||||
from loops.security.setter import BaseSecuritySetter
|
||||
from loops.security.setter import ConceptSecuritySetter, ResourceSecuritySetter
|
||||
from loops.setup import SetupManager, addObject
|
||||
from loops.type import LoopsType, ConceptType, ResourceType, TypeConcept
|
||||
from loops.view import Node, NodeAdapter
|
||||
|
@ -135,6 +136,8 @@ class TestSite(object):
|
|||
component.provideHandler(grantAcquiredSecurity)
|
||||
component.provideHandler(revokeAcquiredSecurity)
|
||||
component.provideAdapter(BaseSecuritySetter)
|
||||
component.provideAdapter(ConceptSecuritySetter)
|
||||
component.provideAdapter(ResourceSecuritySetter)
|
||||
component.provideAdapter(LoopsOptions)
|
||||
component.provideAdapter(QueryOptions)
|
||||
component.provideAdapter(TypeOptions)
|
||||
|
|
Loading…
Add table
Reference in a new issue