propagation of security settings (principal roles and role permissions) basically working
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3649 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
bea4f70ba3
commit
504092b268
11 changed files with 150 additions and 119 deletions
|
@ -60,7 +60,7 @@ from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
from loops.common import adapted
|
from loops.common import adapted
|
||||||
from loops.config.base import DummyOptions
|
from loops.config.base import DummyOptions
|
||||||
from loops.i18n.browser import I18NView
|
from loops.i18n.browser import I18NView
|
||||||
from loops.interfaces import IResource, IView, INode
|
from loops.interfaces import IResource, IView, INode, ITypeConcept
|
||||||
from loops.organize.tracking import access
|
from loops.organize.tracking import access
|
||||||
from loops.resource import Resource
|
from loops.resource import Resource
|
||||||
from loops.security.common import canAccessObject, canListObject, canWriteObject
|
from loops.security.common import canAccessObject, canListObject, canWriteObject
|
||||||
|
@ -413,6 +413,8 @@ class BaseView(GenericView, I18NView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def options(self):
|
def options(self):
|
||||||
|
if ITypeConcept.providedBy(self.adapted):
|
||||||
|
return DummyOptions()
|
||||||
return component.queryAdapter(self.adapted, IOptions) or DummyOptions()
|
return component.queryAdapter(self.adapted, IOptions) or DummyOptions()
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
<zope:class class="loops.compound.blog.post.BlogPost">
|
<zope:class class="loops.compound.blog.post.BlogPost">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="loops.compound.blog.interfaces.IBlogPost" />
|
interface="loops.compound.blog.interfaces.IBlogPost" />
|
||||||
|
<require permission="zope.View"
|
||||||
|
attributes="context" />
|
||||||
<require permission="zope.ManageContent"
|
<require permission="zope.ManageContent"
|
||||||
set_schema="loops.compound.blog.interfaces.IBlogPost" />
|
set_schema="loops.compound.blog.interfaces.IBlogPost" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
|
@ -43,24 +43,27 @@ class BlogPostSecuritySetter(BaseSecuritySetter):
|
||||||
def setDefaultPrincipalRoles(self):
|
def setDefaultPrincipalRoles(self):
|
||||||
assignOwner(self.context.context, self.principalId)
|
assignOwner(self.context.context, self.principalId)
|
||||||
|
|
||||||
def setAcquiredRolePermissions(self, relation, revert=False):
|
def setAcquiredSecurity(self, relation, revert=False):
|
||||||
if isAcquiring(relation.predicate):
|
#if self.isAcquiring(relation.predicate):
|
||||||
|
if relation.predicate in self.acquiringPredicates:
|
||||||
allowEditingForOwner(relation.second, revert=revert)
|
allowEditingForOwner(relation.second, revert=revert)
|
||||||
if self.context.private:
|
if self.context.private:
|
||||||
restrictView(relation.second, revert=revert)
|
restrictView(relation.second, revert=revert)
|
||||||
|
|
||||||
def setAcquiredPrincipalRoles(self, relation, revert=False):
|
|
||||||
if isAcquiring(relation.predicate):
|
|
||||||
if revert:
|
if revert:
|
||||||
removeOwner(relation.second, self.principalId)
|
removeOwner(relation.second, self.principalId)
|
||||||
else:
|
else:
|
||||||
assignOwner(relation.second, self.principalId)
|
assignOwner(relation.second, self.principalId)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def acquiringPredicates(self):
|
||||||
|
names = ('ispartof',)
|
||||||
|
return [self.conceptManager.get(n) for n in names]
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def principalId(self):
|
def principalId(self):
|
||||||
return getCurrentPrincipal().id
|
return getCurrentPrincipal().id
|
||||||
|
|
||||||
|
|
||||||
def isAcquiring(predicate):
|
def isAcquiring(predicate):
|
||||||
# TODO: use a predicate property for this.
|
# TODO: use a predicate option for this.
|
||||||
return getName(predicate) in ('ispartof',)
|
return getName(predicate) in ('ispartof',)
|
||||||
|
|
|
@ -271,11 +271,6 @@ class IBaseResource(ILoopsObject):
|
||||||
source="loops.resourceTypeSource",
|
source="loops.resourceTypeSource",
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
def getType():
|
|
||||||
""" Return a concept that provides the object's type, i.e. the
|
|
||||||
resourceType attribute.
|
|
||||||
"""
|
|
||||||
|
|
||||||
data = schema.Bytes(
|
data = schema.Bytes(
|
||||||
title=_(u'Data'),
|
title=_(u'Data'),
|
||||||
description=_(u'Resource raw data'),
|
description=_(u'Resource raw data'),
|
||||||
|
@ -290,6 +285,38 @@ class IBaseResource(ILoopsObject):
|
||||||
missing_value='',
|
missing_value='',
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
|
def getType():
|
||||||
|
""" Return a concept that provides the object's type, i.e. the
|
||||||
|
resourceType attribute.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getClients(relationships=None):
|
||||||
|
""" Return a sequence of objects that the resource is the target of.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getConcepts(predicates=None):
|
||||||
|
""" Return a tuple of concepts related to self as parent concepts,
|
||||||
|
optionally restricted to the predicates given.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getConceptRelations(predicates=None, concepts=None):
|
||||||
|
""" Return a sequence of relations to concepts assigned to self
|
||||||
|
as parent concepts, optionally restricted to the predicates given
|
||||||
|
or to a certain concept.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def assignConcept(concept, predicate):
|
||||||
|
""" Assign an existing concept to self using the predicate given.
|
||||||
|
The assigned concept will be a parent concept of self.
|
||||||
|
|
||||||
|
The predicate defaults to the concept manager's default predicate.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def deassignConcept(concept, predicates=None):
|
||||||
|
""" Remove the concept relations to the concept given from self,
|
||||||
|
optionally restricting them to the predicates given.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IBaseResourceSchema(Interface):
|
class IBaseResourceSchema(Interface):
|
||||||
""" New schema for resources; to be used by sub-interfaces that will
|
""" New schema for resources; to be used by sub-interfaces that will
|
||||||
|
@ -334,33 +361,6 @@ class IResource(ILoopsObject, IPotentialTarget):
|
||||||
available via a view or a concept.
|
available via a view or a concept.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def getClients(relationships=None):
|
|
||||||
""" Return a sequence of objects that the resource is the target of.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def getConcepts(predicates=None):
|
|
||||||
""" Return a tuple of concepts related to self as parent concepts,
|
|
||||||
optionally restricted to the predicates given.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def getConceptRelations(predicates=None, concepts=None):
|
|
||||||
""" Return a sequence of relations to concepts assigned to self
|
|
||||||
as parent concepts, optionally restricted to the predicates given
|
|
||||||
or to a certain concept.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def assignConcept(concept, predicate):
|
|
||||||
""" Assign an existing concept to self using the predicate given.
|
|
||||||
The assigned concept will be a parent concept of self.
|
|
||||||
|
|
||||||
The predicate defaults to the concept manager's default predicate.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def deassignConcept(concept, predicates=None):
|
|
||||||
""" Remove the concept relations to the concept given from self,
|
|
||||||
optionally restricting them to the predicates given.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class IDocumentSchema(IResourceSchema):
|
class IDocumentSchema(IResourceSchema):
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
name="register_user.html"
|
name="register_user.html"
|
||||||
class="loops.organize.browser.member.MemberRegistration"
|
class="loops.organize.browser.member.MemberRegistration"
|
||||||
permission="zope.Public" />
|
permission="zope.View" />
|
||||||
|
|
||||||
<browser:page
|
<browser:page
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
name="change_password.html"
|
name="change_password.html"
|
||||||
class="loops.organize.browser.member.PasswordChange"
|
class="loops.organize.browser.member.PasswordChange"
|
||||||
permission="zope.Public" />
|
permission="zope.View" />
|
||||||
|
|
||||||
<zope:adapter
|
<zope:adapter
|
||||||
name="task.html"
|
name="task.html"
|
||||||
|
|
|
@ -59,6 +59,11 @@ def getGroupsFolder(context=None, name='gloops'):
|
||||||
return getPrincipalFolder(authPluginId=name, ignoreErrors=True)
|
return getPrincipalFolder(authPluginId=name, ignoreErrors=True)
|
||||||
|
|
||||||
|
|
||||||
|
def getGroupId(group):
|
||||||
|
gf = group.__parent__
|
||||||
|
return ''.join((gf.__parent__.prefix, gf._groupid(group)))
|
||||||
|
|
||||||
|
|
||||||
def getInternalPrincipal(id, context=None, pau=None):
|
def getInternalPrincipal(id, context=None, pau=None):
|
||||||
if pau is None:
|
if pau is None:
|
||||||
pau = component.getUtility(IAuthentication, context=context)
|
pau = component.getUtility(IAuthentication, context=context)
|
||||||
|
|
|
@ -50,9 +50,8 @@ class Granting(granting.Granting):
|
||||||
def status(self):
|
def status(self):
|
||||||
value = super(Granting, self).status()
|
value = super(Granting, self).status()
|
||||||
if value:
|
if value:
|
||||||
setter = ISecuritySetter(adapted(self.context), None)
|
setter = ISecuritySetter(adapted(self.context))
|
||||||
if setter is not None:
|
setter.propagateSecurity()
|
||||||
setter.propagatePrincipalRoles()
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,9 +98,8 @@ class PermissionView(object):
|
||||||
def update(self, testing=None):
|
def update(self, testing=None):
|
||||||
value = self.delegate.update(testing)
|
value = self.delegate.update(testing)
|
||||||
if value:
|
if value:
|
||||||
setter = ISecuritySetter(self.adapted, None)
|
setter = ISecuritySetter(self.adapted)
|
||||||
if setter is not None:
|
setter.propagateSecurity()
|
||||||
setter.propagateRolePermissions()
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
|
|
@ -97,6 +97,14 @@ def setRolePermission(rpm, p, r, setting):
|
||||||
else:
|
else:
|
||||||
rpm.unsetPermissionFromRole(p, r)
|
rpm.unsetPermissionFromRole(p, r)
|
||||||
|
|
||||||
|
def setPrincipalRole(prm, r, p, setting):
|
||||||
|
if setting == Allow:
|
||||||
|
prm.assignRoleToPrincipal(r, p)
|
||||||
|
elif setting == Deny:
|
||||||
|
prm.removeRoleFromPrincipal(r, p)
|
||||||
|
else:
|
||||||
|
prm.unsetRoleForPrincipal(r, p)
|
||||||
|
|
||||||
|
|
||||||
def assignOwner(obj, principalId):
|
def assignOwner(obj, principalId):
|
||||||
prm = IPrincipalRoleManager(obj)
|
prm = IPrincipalRoleManager(obj)
|
||||||
|
@ -137,24 +145,21 @@ def restrictView(obj, roles=allRolesExceptOwnerAndMaster, revert=False):
|
||||||
def setDefaultSecurity(obj, event):
|
def setDefaultSecurity(obj, event):
|
||||||
aObj = adapted(obj)
|
aObj = adapted(obj)
|
||||||
setter = ISecuritySetter(aObj)
|
setter = ISecuritySetter(aObj)
|
||||||
setter.setDefaultRolePermissions()
|
setter.setDefaultSecurity()
|
||||||
setter.setDefaultPrincipalRoles()
|
|
||||||
|
|
||||||
|
|
||||||
@component.adapter(IConcept, IAssignmentEvent)
|
@component.adapter(IConcept, IAssignmentEvent)
|
||||||
def grantAcquiredSecurity(obj, event):
|
def grantAcquiredSecurity(obj, event):
|
||||||
aObj = adapted(obj)
|
aObj = adapted(obj)
|
||||||
setter = ISecuritySetter(aObj)
|
setter = ISecuritySetter(aObj)
|
||||||
setter.setAcquiredRolePermissions(event.relation)
|
setter.setAcquiredSecurity(event.relation)
|
||||||
setter.setAcquiredPrincipalRoles(event.relation)
|
|
||||||
|
|
||||||
|
|
||||||
@component.adapter(IConcept, IDeassignmentEvent)
|
@component.adapter(IConcept, IDeassignmentEvent)
|
||||||
def revokeAcquiredSecurity(obj, event):
|
def revokeAcquiredSecurity(obj, event):
|
||||||
aObj = adapted(obj)
|
aObj = adapted(obj)
|
||||||
setter = ISecuritySetter(aObj)
|
setter = ISecuritySetter(aObj)
|
||||||
setter.setAcquiredRolePermissions(event.relation, revert=True)
|
setter.setAcquiredSecurity(event.relation, revert=True)
|
||||||
setter.setAcquiredPrincipalRoles(event.relation, revert=True)
|
|
||||||
|
|
||||||
|
|
||||||
# helper stuff
|
# helper stuff
|
||||||
|
@ -168,12 +173,12 @@ class WorkspaceInformation(Persistent):
|
||||||
|
|
||||||
__name__ = u'workspace_information'
|
__name__ = u'workspace_information'
|
||||||
|
|
||||||
propagatePrincipalRoles = False
|
|
||||||
propagateRolePermissions = 'workspace'
|
propagateRolePermissions = 'workspace'
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.__parent__ = parent
|
self.__parent__ = parent
|
||||||
self.workspaceGroups = PersistentList()
|
self.workspaceGroupNames = PersistentList()
|
||||||
|
|
||||||
def getName(self):
|
def getName(self):
|
||||||
return self.__name__
|
return self.__name__
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,11 @@ from loops.util import _
|
||||||
|
|
||||||
class ISecuritySetter(Interface):
|
class ISecuritySetter(Interface):
|
||||||
|
|
||||||
|
def setDefaultSecurity():
|
||||||
|
""" Set some default role permission assignments (grants) on the
|
||||||
|
context object.
|
||||||
|
"""
|
||||||
|
|
||||||
def setDefaultRolePermissions():
|
def setDefaultRolePermissions():
|
||||||
""" Set some default role permission assignments (grants) on the
|
""" Set some default role permission assignments (grants) on the
|
||||||
context object.
|
context object.
|
||||||
|
@ -40,46 +45,31 @@ class ISecuritySetter(Interface):
|
||||||
(e.g. the user that created the object).
|
(e.g. the user that created the object).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def acquireRolePermissions():
|
def acquireRolePermissions(revert=False):
|
||||||
""" Check (immediate) parents's settings and set role permission
|
""" Check (immediate) parents's settings and set role permission
|
||||||
assignments on the context object accordingly.
|
assignments on the context object accordingly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setAcquiredRolePermissions(relation, revert=False, updated=None):
|
def setAcquiredSecurity(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.
|
Do not update objects in the ``updated`` collection if present.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setAcquiredPrincipalRoles(relation, revert=False, updated=None):
|
def propagateSecurity(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
|
""" Update role permissions on all sub-objects according to the
|
||||||
current setting of the context object.
|
current setting of the context object.
|
||||||
|
|
||||||
Ignore objects in the ``updated`` collection if present.
|
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):
|
class IWorkspaceInformation(Interface):
|
||||||
""" Additional information belonging to a concept that controls
|
""" Additional information belonging to a concept that controls
|
||||||
security-related stuff for sub-objects.
|
security-related stuff for sub-objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
propagatePrincipalRoles = Attribute('Should acquired principal roles be '
|
|
||||||
'propagated to children?')
|
|
||||||
propagateRolePermissions = Attribute('Which role permissions should be '
|
propagateRolePermissions = Attribute('Which role permissions should be '
|
||||||
'propagated to children?')
|
'propagated to children?')
|
||||||
|
|
||||||
|
|
|
@ -24,16 +24,18 @@ $Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.app.security.settings import Allow, Deny, Unset
|
from zope.app.security.settings import Allow, Deny, Unset
|
||||||
from zope.app.securitypolicy.interfaces import IRolePermissionMap
|
from zope.app.securitypolicy.interfaces import \
|
||||||
from zope.app.securitypolicy.interfaces import IRolePermissionManager
|
IRolePermissionMap, IRolePermissionManager, \
|
||||||
|
IPrincipalRoleMap, IPrincipalRoleManager
|
||||||
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 zope.security.proxy import isinstance
|
||||||
|
|
||||||
from loops.common import adapted, AdapterBase
|
from loops.common import adapted, AdapterBase, baseObject
|
||||||
from loops.security.common import overrides, setRolePermission
|
from loops.organize.util import getPrincipalFolder, getGroupsFolder, getGroupId
|
||||||
|
from loops.security.common import overrides, setRolePermission, setPrincipalRole
|
||||||
from loops.interfaces import IConceptSchema, IBaseResourceSchema, ILoopsAdapter
|
from loops.interfaces import IConceptSchema, IBaseResourceSchema, ILoopsAdapter
|
||||||
from loops.security.interfaces import ISecuritySetter
|
from loops.security.interfaces import ISecuritySetter
|
||||||
|
|
||||||
|
@ -46,25 +48,39 @@ class BaseSecuritySetter(object):
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def baseObject(self):
|
||||||
|
return baseObject(self.context)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def conceptManager(self):
|
||||||
|
return self.baseObject.getLoopsRoot().getConceptManager()
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def acquiringPredicates(self):
|
||||||
|
names = ('hasType', 'standard',)
|
||||||
|
return [self.conceptManager.get(n) for n in names]
|
||||||
|
|
||||||
def setDefaultRolePermissions(self):
|
def setDefaultRolePermissions(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def setDefaultPrincipalRoles(self):
|
def setDefaultPrincipalRoles(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def setDefaultSecurity(self):
|
||||||
|
self.setDefaultRolePermissions()
|
||||||
|
self.setDefaultPrincipalRoles()
|
||||||
|
|
||||||
|
def setAcquiredSecurity(self, relation, revert=False, updated=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def propagateSecurity(self, revert=False, updated=None):
|
||||||
|
pass
|
||||||
|
|
||||||
def acquireRolePermissions(self):
|
def acquireRolePermissions(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def setAcquiredRolePermissions(self, relation, revert=False, updated=None):
|
def copyPrincipalRoles(self, source, revert=False):
|
||||||
pass
|
|
||||||
|
|
||||||
def setAcquiredPrincipalRoles(self, relation, revert=False, updated=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def propagateRolePermissions(self, updated=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def propagatePrincipalRoles(self, updated=None):
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,17 +88,21 @@ class LoopsObjectSecuritySetter(BaseSecuritySetter):
|
||||||
|
|
||||||
parents = []
|
parents = []
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def baseObject(self):
|
|
||||||
obj = self.context
|
|
||||||
if isinstance(obj, AdapterBase):
|
|
||||||
obj = obj.context
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def rolePermissionManager(self):
|
def rolePermissionManager(self):
|
||||||
return IRolePermissionManager(self.baseObject)
|
return IRolePermissionManager(self.baseObject)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def principalRoleManager(self):
|
||||||
|
return IPrincipalRoleManager(self.baseObject)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def workspacePrincipals(self):
|
||||||
|
gFolder = getGroupsFolder(self.baseObject, 'gloops_ws')
|
||||||
|
if gFolder is None:
|
||||||
|
return []
|
||||||
|
return [getGroupId(g) for g in gFolder.values()]
|
||||||
|
|
||||||
def setDefaultRolePermissions(self):
|
def setDefaultRolePermissions(self):
|
||||||
rpm = self.rolePermissionManager
|
rpm = self.rolePermissionManager
|
||||||
for p, r, s in rpm.getRolesAndPermissions():
|
for p, r, s in rpm.getRolesAndPermissions():
|
||||||
|
@ -109,38 +129,44 @@ class LoopsObjectSecuritySetter(BaseSecuritySetter):
|
||||||
for (p, r), s in settings.items():
|
for (p, r), s in settings.items():
|
||||||
setRolePermission(self.rolePermissionManager, p, r, s)
|
setRolePermission(self.rolePermissionManager, p, r, s)
|
||||||
|
|
||||||
|
def copyPrincipalRoles(self, source, revert=False):
|
||||||
|
prm = IPrincipalRoleMap(baseObject(source.context))
|
||||||
|
for r, p, s in prm.getPrincipalsAndRoles():
|
||||||
|
if p in self.workspacePrincipals:
|
||||||
|
if revert:
|
||||||
|
setPrincipalRole(self.principalRoleManager, r, p, Unset)
|
||||||
|
else:
|
||||||
|
setPrincipalRole(self.principalRoleManager, r, p, s)
|
||||||
|
|
||||||
|
|
||||||
class ConceptSecuritySetter(LoopsObjectSecuritySetter):
|
class ConceptSecuritySetter(LoopsObjectSecuritySetter):
|
||||||
|
|
||||||
adapts(IConceptSchema)
|
adapts(IConceptSchema)
|
||||||
|
|
||||||
def setAcquiredRolePermissions(self, relation, revert=False, updated=None):
|
def setAcquiredSecurity(self, relation, revert=False, updated=None):
|
||||||
if updated and relation.second in updated:
|
if updated and relation.second in updated:
|
||||||
return
|
return
|
||||||
setter = ISecuritySetter(adapted(relation.second), None)
|
if relation.predicate not in self.acquiringPredicates:
|
||||||
if setter is not None:
|
return
|
||||||
setter.acquireRolePermissions()
|
setter = ISecuritySetter(adapted(relation.second))
|
||||||
setter.propagateRolePermissions(updated)
|
setter.setDefaultRolePermissions()
|
||||||
|
setter.acquireRolePermissions()
|
||||||
|
setter.copyPrincipalRoles(self, revert)
|
||||||
|
setter.propagateSecurity(revert, updated)
|
||||||
|
|
||||||
def setAcquiredPrincipalRoles(self, relation, revert=False, updated=None):
|
def propagateSecurity(self, revert=False, updated=None):
|
||||||
pass
|
|
||||||
|
|
||||||
def propagateRolePermissions(self, updated=None):
|
|
||||||
if updated is None:
|
if updated is None:
|
||||||
updated = set()
|
updated = set()
|
||||||
obj = self.baseObject
|
obj = self.baseObject
|
||||||
updated.add(obj)
|
updated.add(obj)
|
||||||
for r in obj.getChildRelations():
|
for r in obj.getChildRelations(self.acquiringPredicates):
|
||||||
self.setAcquiredRolePermissions(r, updated=updated)
|
self.setAcquiredSecurity(r, revert, updated)
|
||||||
for r in obj.getResourceRelations():
|
for r in obj.getResourceRelations(self.acquiringPredicates):
|
||||||
self.setAcquiredRolePermissions(r, updated=updated)
|
self.setAcquiredSecurity(r, revert, updated)
|
||||||
|
|
||||||
def propagatePrincipalRoles(self, updated=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def parents(self):
|
def parents(self):
|
||||||
return self.baseObject.getParents()
|
return self.baseObject.getParents(self.acquiringPredicates)
|
||||||
|
|
||||||
|
|
||||||
class ResourceSecuritySetter(LoopsObjectSecuritySetter):
|
class ResourceSecuritySetter(LoopsObjectSecuritySetter):
|
||||||
|
@ -149,5 +175,5 @@ class ResourceSecuritySetter(LoopsObjectSecuritySetter):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def parents(self):
|
def parents(self):
|
||||||
return self.baseObject.getConcepts()
|
return self.baseObject.getConcepts(self.acquiringPredicates)
|
||||||
|
|
||||||
|
|
|
@ -52,13 +52,13 @@ domain concept (if present, otherwise the top-level type concept):
|
||||||
['children', 'description', 'id', 'name', 'parents', 'resources',
|
['children', 'description', 'id', 'name', 'parents', 'resources',
|
||||||
'title', 'type', 'viewName']
|
'title', 'type', 'viewName']
|
||||||
>>> startObj['id'], startObj['name'], startObj['title'], startObj['type']
|
>>> startObj['id'], startObj['name'], startObj['title'], startObj['type']
|
||||||
('3', u'domain', u'Domain', '0')
|
('4', u'domain', u'Domain', '0')
|
||||||
|
|
||||||
There are a few standard objects we can retrieve directly:
|
There are a few standard objects we can retrieve directly:
|
||||||
|
|
||||||
>>> defaultPred = xrf.getDefaultPredicate()
|
>>> defaultPred = xrf.getDefaultPredicate()
|
||||||
>>> defaultPred['id'], defaultPred['name']
|
>>> defaultPred['id'], defaultPred['name']
|
||||||
('14', u'standard')
|
('3', u'standard')
|
||||||
>>> typePred = xrf.getTypePredicate()
|
>>> typePred = xrf.getTypePredicate()
|
||||||
>>> typePred['id'], typePred['name']
|
>>> typePred['id'], typePred['name']
|
||||||
('1', u'hasType')
|
('1', u'hasType')
|
||||||
|
@ -78,12 +78,12 @@ applied in an explicit assignment.
|
||||||
|
|
||||||
We can also retrieve a certain object by its id or its name:
|
We can also retrieve a certain object by its id or its name:
|
||||||
|
|
||||||
>>> obj2 = xrf.getObjectById('5')
|
>>> obj2 = xrf.getObjectById('4')
|
||||||
>>> obj2['id'], obj2['name']
|
>>> obj2['id'], obj2['name']
|
||||||
('5', u'note')
|
('4', u'domain')
|
||||||
>>> textdoc = xrf.getObjectByName(u'textdocument')
|
>>> textdoc = xrf.getObjectByName(u'textdocument')
|
||||||
>>> textdoc['id'], textdoc['name']
|
>>> textdoc['id'], textdoc['name']
|
||||||
('9', u'textdocument')
|
('10', u'textdocument')
|
||||||
|
|
||||||
All methods that retrieve one object also returns its children and parents:
|
All methods that retrieve one object also returns its children and parents:
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ We can also retrieve children and parents explicitely:
|
||||||
[u'customer', u'domain', u'file', u'note', u'person', u'predicate',
|
[u'customer', u'domain', u'file', u'note', u'person', u'predicate',
|
||||||
u'task', u'textdocument', u'topic', u'type']
|
u'task', u'textdocument', u'topic', u'type']
|
||||||
|
|
||||||
>>> pa = xrf.getParents('7')
|
>>> pa = xrf.getParents('6')
|
||||||
>>> len(pa)
|
>>> len(pa)
|
||||||
1
|
1
|
||||||
>>> pa[0]['name']
|
>>> pa[0]['name']
|
||||||
|
|
Loading…
Add table
Reference in a new issue