new role loops.Person for Person object and its children, with zope.View default permission; + security propagation fixes
This commit is contained in:
parent
6fad66ea34
commit
2cee73672b
9 changed files with 67 additions and 36 deletions
|
@ -42,7 +42,7 @@ TypeInterfaceSourceList.typeInterfaces += (ISimpleBlogPost, IBlogPost,)
|
|||
|
||||
class SimpleBlogPost(Compound):
|
||||
|
||||
implements(IBlogPost)
|
||||
implements(ISimpleBlogPost)
|
||||
|
||||
textContentType = 'text/html'
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
loops - Linked Objects for Organization and Processing Services
|
||||
===============================================================
|
||||
|
||||
($Id$)
|
||||
|
||||
Note: This packages depends on cybertools.organize.
|
||||
|
||||
Let's do some basic setup
|
||||
|
@ -267,9 +265,9 @@ Person objects that have a user assigned to them receive this user
|
|||
|
||||
>>> from zope.app.securitypolicy.interfaces import IPrincipalRoleMap
|
||||
>>> IPrincipalRoleMap(concepts['john']).getPrincipalsAndRoles()
|
||||
[('loops.Owner', 'users.john', PermissionSetting: Allow)]
|
||||
[('loops.Person', 'users.john', PermissionSetting: Allow)]
|
||||
>>> IPrincipalRoleMap(concepts['person.newuser']).getPrincipalsAndRoles()
|
||||
[('loops.Owner', u'loops.newuser', PermissionSetting: Allow)]
|
||||
[('loops.Person', u'loops.newuser', PermissionSetting: Allow)]
|
||||
|
||||
The person ``martha`` hasn't got a user id, so there is no role assigned
|
||||
to it.
|
||||
|
@ -307,9 +305,12 @@ Now we are ready to look for the real stuff - what John is allowed to do.
|
|||
True
|
||||
|
||||
Person objects that have an owner may be modified by this owner.
|
||||
(Changed in 2013-01-14: Owner not set automatically)
|
||||
|
||||
>>> canWrite(john, 'title')
|
||||
True
|
||||
False
|
||||
|
||||
was: True
|
||||
|
||||
So let's try with another user with another role setting.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2013 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
|
||||
|
@ -18,8 +18,6 @@
|
|||
|
||||
"""
|
||||
Adapters for IConcept providing interfaces from the cybertools.organize package.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from persistent.mapping import PersistentMapping
|
||||
|
@ -43,9 +41,11 @@ from loops.interfaces import IConcept
|
|||
from loops.organize.interfaces import IAddress, IPerson, IHasRole
|
||||
from loops.organize.interfaces import ANNOTATION_KEY
|
||||
from loops.predicate import RelationAdapter
|
||||
from loops.security.common import assignOwner, removeOwner, allowEditingForOwner
|
||||
from loops.type import TypeInterfaceSourceList
|
||||
from loops.predicate import PredicateInterfaceSourceList
|
||||
from loops.security.common import assignOwner, removeOwner, allowEditingForOwner
|
||||
from loops.security.common import assignPersonRole, removePersonRole
|
||||
from loops.security.interfaces import ISecuritySetter
|
||||
from loops.type import TypeInterfaceSourceList
|
||||
from loops import util
|
||||
|
||||
|
||||
|
@ -84,6 +84,7 @@ class Person(AdapterBase, BasePerson):
|
|||
def getUserId(self):
|
||||
return getattr(self.context, '_userId', None)
|
||||
def setUserId(self, userId):
|
||||
setter = ISecuritySetter(self)
|
||||
if userId:
|
||||
principal = self.getPrincipalForUserId(userId)
|
||||
if principal is None:
|
||||
|
@ -99,13 +100,16 @@ class Person(AdapterBase, BasePerson):
|
|||
if ann is None: # or not isinstance(ann, PersistentMapping):
|
||||
ann = pa[ANNOTATION_KEY] = PersistentMapping()
|
||||
ann[loopsId] = self.context
|
||||
assignOwner(self.context, userId)
|
||||
#assignOwner(self.context, userId)
|
||||
assignPersonRole(self.context, userId)
|
||||
oldUserId = self.userId
|
||||
if oldUserId and oldUserId != userId:
|
||||
self.removeReferenceFromPrincipal(oldUserId)
|
||||
removeOwner(self.context, oldUserId)
|
||||
removePersonRole(self.context, oldUserId)
|
||||
self.context._userId = userId
|
||||
allowEditingForOwner(self.context, revert=not userId)
|
||||
setter.propagateSecurity()
|
||||
allowEditingForOwner(self.context, revert=not userId) # why this?
|
||||
userId = property(getUserId, setUserId)
|
||||
|
||||
def removeReferenceFromPrincipal(self, userId):
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
loops - Linked Objects for Organization and Processing Services
|
||||
===============================================================
|
||||
|
||||
($Id$)
|
||||
|
||||
>>> from zope import component
|
||||
>>> from zope.traversing.api import getName
|
||||
|
||||
|
@ -183,6 +181,12 @@ Querying objects by state
|
|||
[<...>]
|
||||
|
||||
|
||||
Task States
|
||||
===========
|
||||
|
||||
>>> from loops.organize.stateful.task import taskStates, publishableTask
|
||||
|
||||
|
||||
Fin de partie
|
||||
=============
|
||||
|
||||
|
|
|
@ -69,37 +69,51 @@ def publishableTask():
|
|||
color='yellow',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Deny,
|
||||
('zope.View', 'loops.Member'): Deny,})),
|
||||
('zope.View', 'loops.Member'): Deny,
|
||||
('zope.View', 'loops.Person'): Deny,
|
||||
('zope.View', 'loops.Staff'): Deny,})),
|
||||
State('active', 'active', ('retract', 'finish', 'publish', 'cancel',),
|
||||
color='lightblue',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Deny,
|
||||
('zope.View', 'loops.Member'): Allow,})),
|
||||
('zope.View', 'loops.Member'): Deny,
|
||||
('zope.View', 'loops.Person'): Allow,
|
||||
('zope.View', 'loops.Staff'): Deny,})),
|
||||
State('active_published', 'active (published)',
|
||||
('retract', 'finish_published', 'retract', 'cancel',), color='blue',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Allow,
|
||||
('zope.View', 'loops.Member'): Allow,})),
|
||||
('zope.View', 'loops.Member'): Allow,
|
||||
('zope.View', 'loops.Person'): Allow,
|
||||
('zope.View', 'loops.Staff'): Allow,})),
|
||||
State('finished', 'finished', ('reopen', 'archive',),
|
||||
color='lightgreen',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Deny,
|
||||
('zope.View', 'loops.Member'): Allow,})),
|
||||
('zope.View', 'loops.Member'): Deny,
|
||||
('zope.View', 'loops.Person'): Allow,
|
||||
('zope.View', 'loops.Staff'): Deny,})),
|
||||
State('finished_published', 'finished (published)', ('reopen', 'archive',),
|
||||
color='green',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Allow,
|
||||
('zope.View', 'loops.Member'): Allow,})),
|
||||
('zope.View', 'loops.Member'): Allow,
|
||||
('zope.View', 'loops.Person'): Allow,
|
||||
('zope.View', 'loops.Staff'): Allow,})),
|
||||
State('cancelled', 'cancelled', ('reopen',),
|
||||
color='x',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Deny,
|
||||
('zope.View', 'loops.Member'): Deny,})),
|
||||
('zope.View', 'loops.Member'): Deny,
|
||||
('zope.View', 'loops.Person'): Deny,
|
||||
('zope.View', 'loops.Staff'): Deny,})),
|
||||
State('archived', 'archived', ('reopen',),
|
||||
color='grey',
|
||||
setSecurity=setPermissionsForRoles({
|
||||
('zope.View', 'zope.Member'): Deny,
|
||||
('zope.View', 'loops.Member'): Deny,})),
|
||||
('zope.View', 'loops.Member'): Deny,
|
||||
('zope.View', 'loops.Person'): Deny,
|
||||
('zope.View', 'loops.Staff'): Deny,})),
|
||||
Transition('release', 'release', 'active'),
|
||||
Transition('release_publish', 'release, publish', 'active_published'),
|
||||
Transition('publish', 'publish', 'active_published'),
|
||||
|
|
|
@ -79,6 +79,11 @@
|
|||
<grant role="loops.Owner" permission="loops.ViewRestricted" />
|
||||
<grant role="loops.Owner" permission="zope.View" />
|
||||
|
||||
<role id="loops.Person"
|
||||
title="[loops-person-role] Person" />
|
||||
<grant role="loops.Person" permission="zope.View" />
|
||||
<grant role="loops.Person" permission="loops.ViewRestricted" />
|
||||
|
||||
<!-- moved to etc/securitypolicy.zcml: -->
|
||||
<!--<grant role="zope.ContentManager" permission="loops.AssignAsParent" />-->
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2010 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2013 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
|
||||
|
@ -18,8 +18,6 @@
|
|||
|
||||
"""
|
||||
Security-related views.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.app.authentication.groupfolder import GroupInformation
|
||||
|
@ -145,7 +143,7 @@ class PermissionView(object):
|
|||
for e in entry:
|
||||
value = SettingAsBoolean[e[1]]
|
||||
value = (value is False and '-') or (value and '+') or ''
|
||||
result.append(value + e[0])
|
||||
result.append(value + (e[0] or ''))
|
||||
return ', '.join(result)
|
||||
|
||||
def getPrincipalPermissions(self):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2013 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
|
||||
|
@ -18,8 +18,6 @@
|
|||
|
||||
"""
|
||||
Common functions and other stuff for working with permissions and roles.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from persistent import Persistent
|
||||
|
@ -49,12 +47,12 @@ allRolesExceptOwner = (
|
|||
'zope.Anonymous', 'zope.Member', 'zope.ContentManager', 'loops.Staff',
|
||||
'loops.xmlrpc.ConceptManager', # relevant for local security?
|
||||
#'loops.SiteManager',
|
||||
'loops.Member', 'loops.Master',)
|
||||
'loops.Person', 'loops.Member', 'loops.Master')
|
||||
allRolesExceptOwnerAndMaster = tuple(allRolesExceptOwner[:-1])
|
||||
minorPrivilegedRoles = ('zope.Anonymous', 'zope.Member',)
|
||||
localRoles = ('zope.Anonymous', 'zope.Member', 'zope.ContentManager',
|
||||
'loops.SiteManager', 'loops.Staff', 'loops.Member', 'loops.Master',
|
||||
'loops.Owner')
|
||||
'loops.Owner', 'loops.Person')
|
||||
|
||||
localPermissions = ('zope.ManageContent', 'zope.View', 'loops.ManageWorkspaces',
|
||||
'loops.ViewRestricted', 'loops.EditRestricted', 'loops.AssignAsParent',)
|
||||
|
@ -127,7 +125,15 @@ def assignOwner(obj, principalId):
|
|||
|
||||
def removeOwner(obj, principalId):
|
||||
prm = IPrincipalRoleManager(obj)
|
||||
prm.removeRoleFromPrincipal('loops.Owner', principalId)
|
||||
prm.unsetRoleForPrincipal('loops.Owner', principalId)
|
||||
|
||||
def assignPersonRole(obj, principalId):
|
||||
prm = IPrincipalRoleManager(obj)
|
||||
prm.assignRoleToPrincipal('loops.Person', principalId)
|
||||
|
||||
def removePersonRole(obj, principalId):
|
||||
prm = IPrincipalRoleManager(obj)
|
||||
prm.unsetRoleForPrincipal('loops.Person', principalId)
|
||||
|
||||
|
||||
def allowEditingForOwner(obj, deny=allRolesExceptOwner, revert=False):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2013 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
|
||||
|
@ -19,8 +19,6 @@
|
|||
"""
|
||||
Base classes for security setters, i.e. adapters that provide standardized
|
||||
methods for setting role permissions and other security-related stuff.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.app.security.settings import Allow, Deny, Unset
|
||||
|
@ -136,7 +134,7 @@ class LoopsObjectSecuritySetter(BaseSecuritySetter):
|
|||
def copyPrincipalRoles(self, source, revert=False):
|
||||
prm = IPrincipalRoleMap(baseObject(source.context))
|
||||
for r, p, s in prm.getPrincipalsAndRoles():
|
||||
if p in self.workspacePrincipals:
|
||||
#if p in self.workspacePrincipals:
|
||||
if revert:
|
||||
setPrincipalRole(self.principalRoleManager, r, p, Unset)
|
||||
else:
|
||||
|
@ -155,6 +153,7 @@ class ConceptSecuritySetter(LoopsObjectSecuritySetter):
|
|||
setter = ISecuritySetter(adapted(relation.second))
|
||||
setter.setDefaultRolePermissions()
|
||||
setter.acquireRolePermissions()
|
||||
# TODO: use setter.acquirePrincipalRoles() instead of copyPrincipalRoles()
|
||||
wi = baseObject(self.context).workspaceInformation
|
||||
if wi and not wi.propagateParentSecurity:
|
||||
return
|
||||
|
|
Loading…
Add table
Reference in a new issue