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
	
	 helmutm
						helmutm