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