diff --git a/compound/blog/post.py b/compound/blog/post.py index 805e5fa..649e498 100644 --- a/compound/blog/post.py +++ b/compound/blog/post.py @@ -42,7 +42,7 @@ TypeInterfaceSourceList.typeInterfaces += (ISimpleBlogPost, IBlogPost,) class SimpleBlogPost(Compound): - implements(IBlogPost) + implements(ISimpleBlogPost) textContentType = 'text/html' diff --git a/organize/README.txt b/organize/README.txt index 0fc6988..92c46e0 100644 --- a/organize/README.txt +++ b/organize/README.txt @@ -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. diff --git a/organize/party.py b/organize/party.py index ee6813a..1ad33d5 100644 --- a/organize/party.py +++ b/organize/party.py @@ -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): diff --git a/organize/stateful/README.txt b/organize/stateful/README.txt index e6445eb..11182e4 100644 --- a/organize/stateful/README.txt +++ b/organize/stateful/README.txt @@ -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 ============= diff --git a/organize/stateful/task.py b/organize/stateful/task.py index c77746b..b1ae6d7 100644 --- a/organize/stateful/task.py +++ b/organize/stateful/task.py @@ -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'), diff --git a/security.zcml b/security.zcml index f2882a8..08faba0 100644 --- a/security.zcml +++ b/security.zcml @@ -79,6 +79,11 @@ + + + + diff --git a/security/browser/admin.py b/security/browser/admin.py index 1ef9e7b..0f23745 100644 --- a/security/browser/admin.py +++ b/security/browser/admin.py @@ -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): diff --git a/security/common.py b/security/common.py index 31ac6f2..ba67833 100644 --- a/security/common.py +++ b/security/common.py @@ -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): diff --git a/security/setter.py b/security/setter.py index 5c9e0c0..b61e41f 100644 --- a/security/setter.py +++ b/security/setter.py @@ -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