[Checkins] SVN: z3c.securitytool/ Adding z3c.securitytool to svn
Daniel Blackburn
blackburnd at gmail.com
Sat Sep 29 19:39:12 EDT 2007
Log message for revision 80414:
Adding z3c.securitytool to svn
Changed:
A z3c.securitytool/
A z3c.securitytool/branches/
A z3c.securitytool/tags/
A z3c.securitytool/trunk/
A z3c.securitytool/trunk/src/
A z3c.securitytool/trunk/src/z3c/
A z3c.securitytool/trunk/src/z3c/__init__.py
A z3c.securitytool/trunk/src/z3c/securitytool/
A z3c.securitytool/trunk/src/z3c/securitytool/README.txt
A z3c.securitytool/trunk/src/z3c/securitytool/SETUP.cfg
A z3c.securitytool/trunk/src/z3c/securitytool/TODO.txt
A z3c.securitytool/trunk/src/z3c/securitytool/__init__.py
A z3c.securitytool/trunk/src/z3c/securitytool/browser/
A z3c.securitytool/trunk/src/z3c/securitytool/browser/__init__.py
A z3c.securitytool/trunk/src/z3c/securitytool/browser/configure.zcml
A z3c.securitytool/trunk/src/z3c/securitytool/browser/permdetails.pt
A z3c.securitytool/trunk/src/z3c/securitytool/browser/principalinfo.pt
A z3c.securitytool/trunk/src/z3c/securitytool/browser/securitytool.css
A z3c.securitytool/trunk/src/z3c/securitytool/browser/viewprincipalmatrix.pt
A z3c.securitytool/trunk/src/z3c/securitytool/browser/views.py
A z3c.securitytool/trunk/src/z3c/securitytool/configure.zcml
A z3c.securitytool/trunk/src/z3c/securitytool/interfaces.py
A z3c.securitytool/trunk/src/z3c/securitytool/securitytool.py
A z3c.securitytool/trunk/src/z3c/securitytool/tests.py
A z3c.securitytool/trunk/src/z3c/securitytool/z3c.securitytool-configure.zcml
-=-
Added: z3c.securitytool/trunk/src/z3c/__init__.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/__init__.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/__init__.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1 @@
+pass
Added: z3c.securitytool/trunk/src/z3c/securitytool/README.txt
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/README.txt (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/README.txt 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,145 @@
+================
+z3c.securitytool
+================
+
+
+z3c.securitytool is a Zope3 package aimed at providing component level security
+information to assist in analyzing security problems and to potentially expose
+weaknesses. The goal of the security tool is to provide a matrix of users and
+their effective permissions for all available views for any given component
+and context. We also provide two further levels of detail. You can view the
+details of how a user came to have the permission on a given view, by clicking
+on the permission in the matrix.
+
+
+ >>> from pprint import pprint
+ >>> from zope.interface import implements
+ >>> from zope.annotation.interfaces import IAttributeAnnotatable
+ >>> from zope.app.container import contained
+ >>> from zope.app.folder import Folder, rootFolder
+
+ >>> from zope.app.authentication.principalfolder import Principal
+ >>> from zope.app.securitypolicy.role import Role
+ >>> from zope.security.permission import Permission
+
+
+
+The news agency, the Concord Times, is implementing a new article management
+system in Zope 3. In order to better understand their security situation, they
+have installed z3c.security tool.
+
+ >>> concordTimes = rootFolder()
+
+The Concord Times site is a folder which contains a Folder per issue and each
+issue contains articles.
+
+ >>> class Issue(Folder):
+ ... def __init__(self, title):
+ ... self.title = title
+ ...
+ ... def __repr__(self):
+ ... return '<%s %r>' %(self.__class__.__name__, self.title)
+
+ >>> class Article(contained.Contained):
+ ... implements(IAttributeAnnotatable)
+ ...
+ ... def __init__(self, title, text):
+ ... self.title = title
+ ... self.text = text
+ ...
+ ... def __repr__(self):
+ ... return '<%s %r>' %(self.__class__.__name__, self.title)
+
+At the Concord Times, they have only three levels of users: Editors, Writers,
+and Janitors.
+
+ >>> editor = Role('concord.Editor', 'The editors')
+ >>> writer = Role('concord.Writer', 'The writers')
+ >>> janitor = Role('concord.Janitor', 'The janitors')
+
+In order to control who has access to the system, they define the following
+necessary permissions:
+
+ >>> createIssue = Permission('concord.CreateIssue','Create Issue')
+ >>> publishIssue = Permission('concord.PublishIssue', 'Publish Issue')
+ >>> readIssue = Permission('concord.ReadIssue', 'Read Issue')
+ >>> createArticle = Permission('concord.CreateArticle', 'Create Article')
+ >>> deleteArticle = Permission('concord.DeleteArticle', 'Delete Article')
+
+Now we need to setup the security system on the level of the news agency.
+In order to assign the permissions to the roles, we must setup a role-
+permission Manager, which is used to map permissions to roles.
+
+ >>> from zope.app.securitypolicy.interfaces import IRolePermissionManager
+ >>> rolePermManager = IRolePermissionManager(concordTimes)
+
+Now we can use our ``rolePermManager`` to assign the roles.
+Editors are the only users that are allowed to create and publish issues.
+Writers and Editors may create articles, but only editors can delete them.
+Everyone can read the issues.
+
+ >>> rolePermManager.grantPermissionToRole(createIssue.id, editor.id)
+ >>> rolePermManager.grantPermissionToRole(publishIssue.id, editor.id)
+ >>> rolePermManager.grantPermissionToRole(readIssue.id, editor.id)
+ >>> rolePermManager.grantPermissionToRole(createArticle.id, editor.id)
+ >>> rolePermManager.grantPermissionToRole(deleteArticle.id, editor.id)
+
+ >>> rolePermManager.grantPermissionToRole(readIssue.id, writer.id)
+ >>> rolePermManager.grantPermissionToRole(createArticle.id, writer.id)
+
+ >>> rolePermManager.grantPermissionToRole(readIssue.id, janitor.id)
+
+The news agency now hires the initial set of staff members. So let's create
+a principal for each hired person:
+
+ >>> martin = Principal('martin', 'Martin')
+ >>> randy = Principal('randy', 'Randy')
+ >>> markus = Principal('markus', 'Markus')
+ >>> daniel = Principal('daniel', 'Daniel')
+ >>> stephan = Principal('stephan', 'Stephan')
+
+Based on their positions we assign proper roles to the staff.
+In order to assign roles to our staff members, we must first create a
+principal-role manager.
+
+ >>> from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+ >>> prinRoleManager = IPrincipalRoleManager(concordTimes)
+
+And now we can assign the roles. At the Concord Times, Martin is an editor,
+Randy and Markus are writers, and Daniel and Stephan are janitors.
+
+ >>> prinRoleManager.assignRoleToPrincipal(editor.id, martin.id)
+ >>> prinRoleManager.assignRoleToPrincipal(writer.id, randy.id)
+ >>> prinRoleManager.assignRoleToPrincipal(writer.id, markus.id)
+ >>> prinRoleManager.assignRoleToPrincipal(janitor.id, daniel.id)
+ >>> prinRoleManager.assignRoleToPrincipal(janitor.id, stephan.id)
+
+To allow editors to create articles Martin has to create a new Issue:
+
+ >>> firstIssue = concordTimes['issue.1'] = \
+ ... Issue('The very first issue of `The Concord Times`')
+
+Randy starts to write his first article:
+
+ >>> firstArticle = Article('A new star is born',
+ ... 'A new star is born, the `The Concord Times` ...')
+
+
+ >>> from zope.security import testing
+ >>> from zope.app.securitypolicy import zopepolicy
+
+ >>> policy = zopepolicy.ZopeSecurityPolicy()
+ >>> participation = testing.Participation(markus)
+ >>> policy.add(participation)
+ >>> policy.checkPermission(createIssue.id, concordTimes)
+ False
+
+ >>> policy2 = zopepolicy.ZopeSecurityPolicy()
+ >>> participation2 = testing.Participation(martin)
+ >>> policy2.add(participation2)
+ >>> policy2.checkPermission(createIssue.id, concordTimes)
+ True
+
+
+
+
\ No newline at end of file
Added: z3c.securitytool/trunk/src/z3c/securitytool/SETUP.cfg
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/SETUP.cfg (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/SETUP.cfg 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,5 @@
+<data-files zopeskel/etc/package-includes>
+ z3c.securitytool-*.zcml
+</data-files>
+
+
Added: z3c.securitytool/trunk/src/z3c/securitytool/TODO.txt
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/TODO.txt (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/TODO.txt 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,15 @@
+* principal-role Allow/Deny
+
+* Make a z3c package (License stuff)
+
+* Unit tests
+
+* Functional test
+
+* Solve the security proxy problem in `SettingsForObject`
+
+* Discrimante by interface (see `zope.app.apidoc.presentattion.filterViewRegistrations`)
+
+* Show the permission details as a graph
+
+* Check namespaces
\ No newline at end of file
Added: z3c.securitytool/trunk/src/z3c/securitytool/__init__.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/__init__.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/__init__.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1 @@
+# make a package
\ No newline at end of file
Property changes on: z3c.securitytool/trunk/src/z3c/securitytool/__init__.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/__init__.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/__init__.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/__init__.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1 @@
+# make a package
\ No newline at end of file
Property changes on: z3c.securitytool/trunk/src/z3c/securitytool/browser/__init__.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/configure.zcml
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/configure.zcml (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/configure.zcml 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,40 @@
+<configure
+ xmlns="http://namespaces.zope.org/browser"
+ xmlns:z3c="http://namespaces.zope.org/z3c"
+ >
+
+ <page name="vum.html"
+ for="*"
+ class=".views.ViewPrincipalMatrix"
+ permission="zope.Public"
+ />
+
+ <page name="ud.html"
+ for="*"
+ class=".views.PrincipalDetails"
+ permission="zope.Public"
+ />
+
+ <page name="pd.html"
+ for="*"
+ class=".views.PermissionDetails"
+ permission="zope.Public"
+ />
+
+ <z3c:macro
+ name="permission-details"
+ macro="permission-details"
+ template="permdetails.pt"
+ />
+
+ <z3c:macro
+ name="user-details"
+ macro="user-details"
+ template="principalinfo.pt"
+ />
+
+ <resource
+ name="securitytool.css"
+ file="securitytool.css"
+ />
+</configure>
Property changes on: z3c.securitytool/trunk/src/z3c/securitytool/browser/configure.zcml
___________________________________________________________________
Name: svn:executable
+
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/permdetails.pt
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/permdetails.pt (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/permdetails.pt 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,61 @@
+<html>
+<head>
+ <link type="text/css" rel="stylesheet" media="all" href=""
+ tal:attributes="href context/++resource++securitytool.css"/>
+</head>
+ <body>
+ <h1>Permission Details</h1>
+ <p tal:content="structure view/message">This permission details
+ for the user</p>
+ <tal:div define="permissions view/permissionDetails/permissions;
+ roles view/permissionDetails/roles;
+ groups view/permissionDetails/groups">
+ <div tal:condition="view/legend" tal:content="structure view/legend"/>
+ <metal:block define-macro="permission-details">
+ <ul tal:condition="permissions|roles|groups">
+ <li>
+ <tal:block tal:condition="permissions">
+ <div>
+ <b>Directly provided in context(s)</b>
+ </div>
+ <div tal:repeat="permission permissions">
+ <div tal:attributes="class permission/setting"
+ tal:content="permission/name"></div>
+ </div>
+ </tal:block>
+ <tal:block tal:condition="roles">
+ <div>
+ <b>Provided by role in context(s)</b>
+ </div>
+ <div tal:repeat="role_context roles">
+ <div>
+ <span tal:content="role_context" />:
+ <span tal:repeat="perm
+ python:roles[role_context]">
+ <span tal:attributes="class perm/setting"
+ tal:content="perm/name"/><span tal:condition="not:repeat/perm/end"
+ tal:replace="string:,"/>
+ </span></div>
+
+ </div>
+ </tal:block>
+ <tal:block tal:condition="groups">
+ <div>
+ <b>Provided by group(s) in context(s)</b>
+ </div>
+ <div tal:repeat="group_id groups">
+ <div tal:content="group_id">zope.Authenticated</div>
+ <div tal:define="group python:groups[group_id];
+ permissions group/permissions;
+ roles group/roles;
+ groups group/groups">
+ <div metal:use-macro="macro:permission-details" />
+ </div>
+ </div>
+ </tal:block>
+ </li>
+ </ul>
+ </metal:block>
+ </tal:div>
+ </body>
+</html>
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/principalinfo.pt
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/principalinfo.pt (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/principalinfo.pt 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,35 @@
+<html>
+ <body>
+ <h1>Permission settings for principal <em tal:content="view/principal"></em></h1>
+ <p tal:content="view/principalPermissions"></p>
+ <tal:block define="permissions view/principalPermissions/permissions;
+ roles view/principalPermissions/roles;
+ groups view/principalPermissions/groups">
+ <metal:block define-macro="user-details">
+ <tal:block tal:condition="permissions">
+ <h3>Directly provided permissions</h3>
+ <div tal:repeat="permission permissions"><span tal:replace="permission">zope.ManageSite</span>, </div>
+ </tal:block>
+ <tal:block tal:condition="roles">
+ <h3>Permissions provided by roles</h3>
+ <div tal:repeat="role roles">
+ <b tal:content="role">zope.ManageSite:</b>
+ <div tal:repeat="permission python:roles[role]" tal:content="permission"></div>
+ </div>
+ </tal:block>
+ <tal:block tal:condition="groups">
+ <h3>Permissions provided by group(s)</h3>
+ <div tal:repeat="group_id groups">
+ <div tal:content="group_id">zope.Authenticated</div>
+ <div tal:define="group python:groups[group_id];
+ permissions group/permissions;
+ roles group/roles;
+ groups group/groups">
+ <div metal:use-macro="macro:user-details" />
+ </div>
+ </div>
+ </tal:block>
+ </metal:block>
+ </tal:block>
+ </body>
+</html>
\ No newline at end of file
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/securitytool.css
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/securitytool.css (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/securitytool.css 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,102 @@
+/* Normalize */
+
+body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, p, blockquote, th, td {
+ margin : 0;
+ padding : 0;
+ font-size: 100%;
+ font-weight: normal;
+}
+
+/* remove borders from tables */
+
+table {
+ border-collapse : collapse;
+ border-spacing : 0;
+}
+
+/* start formatting the page */
+
+body {
+ padding: 5px;
+ font-family:Arial,sans-serif;
+ font-size:small;
+}
+
+h1 {
+ font-size: 130%;
+ font-weight: bold;
+ padding: 10px 20px;
+ width: 100%;
+ border-bottom: 1px solid #ccc;
+}
+
+h2 {
+ font-size: 110%;
+ font-weight: bold;
+ padding: 5px 35px;
+}
+
+form {
+ margin-top: 25px;
+}
+
+form input {
+ font-size: 90%;
+}
+
+form select {
+ font-size: 90%;
+}
+
+table {
+ border: 1px solid #999;
+}
+
+table td {
+ text-align : center;
+ vertical-align : middle;
+ font-size: 90%;
+ padding: 2px 5px;
+}
+
+* html table { /* for Internet Explorer */
+ font-size: 120%;
+}
+
+table th {
+ background-color : #ccc;
+ font-size: 90%;
+ font-weight: bolder;
+ padding:5px;
+
+}
+
+table th a {
+ text-decoration:none;
+}
+
+table th a:visited {
+ color: blue;
+}
+
+.viewname {
+ font-weight: bold;
+}
+
+.permission {
+ font-style:italic;
+}
+
+.even {
+ background-color: #ddd;
+}
+
+/* Permission setting classes */
+.Allow {
+ color:green;
+}
+
+.Deny {
+ font-weight:bold;
+ color:red;
+}
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/viewprincipalmatrix.pt
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/viewprincipalmatrix.pt (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/viewprincipalmatrix.pt 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,63 @@
+<html>
+ <head>
+ <link type="text/css" rel="stylesheet" media="all" href=""
+ tal:attributes="href context/++resource++securitytool.css"/>
+ </head>
+<body>
+ <h1>Security Checking Tool</h1>
+ <h2>View User Matrix</h2>
+ <form action="." method="POST"
+ tal:attributes="action request/URL">
+ <p>Select a skin:
+ <select name="selectedSkin">
+ <option value="SkinType"
+ tal:repeat="skinName view/skinTypes"
+ tal:attributes="value skinName;
+ selected python:request.form.has_key('selectedSkin') and request.form['selectedSkin']==skinName"
+ tal:content="skinName">SkinName</option>
+ </select>
+ </p>
+ <p>Filter by permission:
+ <select name="selectedPermission">
+ <option value="None">---</option>
+ <option value="Permission"
+ tal:repeat="permission view/getPermissionList"
+ tal:attributes="value permission;
+ selected python:request.form.has_key('selectedPermission') and request.form['selectedPermission']==permission"
+ tal:content="permission">permission</option>
+ </select>
+
+ <input type="submit" name="FILTER" value="Filter"/>
+ </p>
+ </form>
+ <br />
+ <table tal:define="urlViewName view/urlEncodedViewName">
+ <tr>
+ <th></th>
+ <th tal:repeat="principal view/viewMatrix">
+ <a tal:content="principal"
+ tal:attributes="href string:ud.html?userid=${principal}">Principal</a>
+ </th>
+ </tr>
+ <tr tal:repeat="viewName view/views"
+ tal:attributes="class view/cssclass">
+ <td>
+ <span tal:content="structure viewName"
+ class="viewname"/><br />
+ <span class="permission">
+ (<span tal:content="python: view.views[viewName]"
+ tal:omit-tag="">Read Permission</span>)
+ </span>
+ </td>
+ <td tal:repeat="principal view/viewMatrix"
+ tal:define="enc python:urlViewName[viewName]">
+ <a tal:attributes="href string:pd.html?principal=${principal}&view=${enc}"
+ tal:omit-tag="python: view.getPermissionSetting(viewName,principal)=='--'">
+ <span tal:content="python: view.getPermissionSetting(viewName,principal)"
+ tal:omit-tag="">Allow</span>
+ </a>
+ </td>
+ </tr>
+ </table>
+</body>
+</html>
Added: z3c.securitytool/trunk/src/z3c/securitytool/browser/views.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/browser/views.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/browser/views.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,156 @@
+from zope.publisher.browser import BrowserView
+
+from zope.publisher.interfaces.browser import IBrowserRequest,IBrowserSkinType
+from zope.component import getGlobalSiteManager
+from zope.publisher.interfaces import IRequest
+import zope.interface
+import urllib
+
+from zope.app.apidoc.presentation import getViewInfoDictionary
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.app.securitypolicy.zopepolicy import settingsForObject
+from zope.security.proxy import removeSecurityProxy
+from zope.interface import providedBy
+from zope.app.session.interfaces import ISession
+from zope.app import zapi
+
+from z3c.securitytool.interfaces import ISecurityChecker
+
+SESSION_KEY = 'securitytool'
+
+class ViewPrincipalMatrix(BrowserView):
+ pageTemplateFile = "viewprincipalmatrix.pt"
+
+ evenOddClasses = ('even','odd')
+ evenodd = 0
+
+ def update(self):
+ selectedPermission = None
+ if 'FILTER' in self.request.form:
+ selectedSkin = self.request.form['selectedSkin']
+ ISession(self.request)[SESSION_KEY]['selectedSkin'] = selectedSkin
+ skin = zapi.getUtility(IBrowserSkinType,selectedSkin)
+ if (self.request.form.has_key('selectedPermission') and
+ self.request.form['selectedPermission'] != 'None'):
+ selectedPermission = self.request.form['selectedPermission']
+ else:
+ skin = IBrowserRequest
+ ifaces = tuple(providedBy(self.context))
+ security_checker = ISecurityChecker(self.context)
+ self.viewMatrix, self.views, self.permissions = \
+ security_checker.getPermissionSettingsForAllViews(ifaces, skin,
+ selectedPermission)
+
+ def cssclass(self):
+ if self.evenodd != 1:
+ self.evenodd = 1
+ else:
+ self.evenodd = 0
+ return self.evenOddClasses[self.evenodd]
+
+
+ def getPermissionSetting(self, view, principal):
+ try:
+ return self.viewMatrix[principal][view]
+ except KeyError:
+ return '--'
+
+ @property
+ def skinTypes(self):
+ skinNames = {}
+ for name, util in zapi.getUtilitiesFor(IBrowserSkinType, self.context):
+ skinNames[name] = False
+ if (self.request.form.has_key('selectedSkin') and
+ self.request.form['selectedSkin'] == name):
+ skinNames[name] = True
+ return skinNames
+
+ @property
+ def urlEncodedViewName(self):
+ urlNames = {}
+ for key in self.views.keys():
+ urlNames[key] = urllib.quote(key)
+ return urlNames
+
+
+ def getPermissionList(self):
+ return sorted(self.permissions)
+
+ def render(self):
+ return ViewPageTemplateFile(self.pageTemplateFile)(self)
+
+ def __call__(self):
+ self.update()
+ return self.render()
+
+class PrincipalDetails(BrowserView):
+ pageTemplateFile = "principalinfo.pt"
+
+ def update(self):
+ if self.request.form.has_key('principal'):
+ self.principal = self.request.form['principal']
+ else:
+ self.principal = 'no principal specified'
+
+ skin = getSkin(self.request)
+ principal_security = ISecurityChecker(self.context)
+ self.principalPermissions = principal_security.principalPermissions(
+ self.principal, skin=skin)
+
+ def render(self):
+ return ViewPageTemplateFile(self.pageTemplateFile)(self)
+
+ def __call__(self):
+ self.update()
+ return self.render()
+
+class PermissionDetails(BrowserView):
+ pageTemplateFile = "permdetails.pt"
+
+ def update(self):
+ if self.request.form.has_key('principal'):
+ self.principal = self.request.form['principal']
+ else:
+ self.principal = 'no user specified'
+
+ if self.request.form.has_key('view'):
+ self.view = self.request.form['view']
+ else:
+ self.view = 'no view specified'
+
+ skin = getSkin(self.request)
+ principal_security = ISecurityChecker(self.context)
+ self.permissionDetails = principal_security.permissionDetails(
+ self.principal, self.view, skin=skin)
+
+ self.read_perm = self.permissionDetails['read_perm']
+ if self.read_perm == 'zope.Public':
+ self.message =(u"The view <b>%s</b> has the permission "
+ u"<b>zope.Public</b> and can be accessed "
+ u"by any principal." % self.view)
+
+ self.legend = u""
+ else:
+ self.message = (u"These are the security settings for the "
+ u"principal <b>%(principal)s</b> and the view "
+ u"<b>%(view)s</b> with the permission "
+ u"<b>%(read_perm)s</b>."
+ % self.__dict__
+ )
+
+ self.legend = (u"<span class='Deny'>Red Bold = Denied Permission"
+ u"</span>,<span class='Allow'> Green Normal = "
+ u"Allowed Permission </span>")
+
+ def render(self):
+ return ViewPageTemplateFile(self.pageTemplateFile)(self)
+
+ def __call__(self):
+ self.update()
+ return self.render()
+
+def getSkin(request):
+ """Get the skin from the session."""
+ sessionData = ISession(request)[SESSION_KEY]
+ selectedSkin = sessionData.get('selectedSkin', IBrowserRequest)
+ return zapi.queryUtility(IBrowserSkinType, selectedSkin)
Property changes on: z3c.securitytool/trunk/src/z3c/securitytool/browser/views.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.securitytool/trunk/src/z3c/securitytool/configure.zcml
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/configure.zcml (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/configure.zcml 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,11 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ >
+ <include package=".browser" />
+
+ <adapter
+ factory=".securitytool.SecurityChecker"
+ for="*"
+ />
+
+</configure>
\ No newline at end of file
Property changes on: z3c.securitytool/trunk/src/z3c/securitytool/configure.zcml
___________________________________________________________________
Name: svn:executable
+
Added: z3c.securitytool/trunk/src/z3c/securitytool/interfaces.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/interfaces.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/interfaces.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,4 @@
+from zope.interface import Interface
+
+class ISecurityChecker(Interface):
+ """TODO"""
Added: z3c.securitytool/trunk/src/z3c/securitytool/securitytool.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/securitytool.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/securitytool.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,284 @@
+from zope.interface import Interface, implements, providedBy
+from zope.component import adapts, getMultiAdapter, getGlobalSiteManager
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.browser import TestRequest, applySkin
+from zope.publisher.interfaces import IRequest
+
+from zope.app.apidoc.presentation import getViewInfoDictionary
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.app.security.principalregistry import PrincipalRegistry
+from zope.app.securitypolicy.zopepolicy import settingsForObject
+from zope.app.session.interfaces import ISession
+from zope.app import zapi
+
+from z3c.securitytool import interfaces
+
+class SecurityChecker(object):
+ implements(interfaces.ISecurityChecker)
+ adapts(Interface)
+
+ def __init__(self, context):
+ self.context = context
+
+ def getView(self, view_reg, skin=IBrowserRequest):
+ """Instantiate view from given registration and skin.
+
+ Return `None` if the view isn't callable.
+ """
+ request = TestRequest()
+ applySkin(request, skin)
+ try:
+ view_inst = view_reg.factory(self.context, request)
+ if callable(view_inst):
+ return view_inst
+ except TypeError:
+ pass
+
+ def getPermissionSettingsForAllViews(self,interfaces,skin=IBrowserRequest,
+ selectedPermission=None):
+ import pdb; pdb.set_trace()
+ request = TestRequest()
+ applySkin(request, skin)
+ viewMatrix = {}
+ views = {}
+ permissions = set()
+ for iface in interfaces:
+ for view_reg in getViews(iface, skin):
+ viewInstance = self.getView(view_reg, skin)
+ if viewInstance:
+ info = getViewInfoDictionary(view_reg)
+ read_perm = info['read_perm']
+ permissions.add(read_perm)
+ if read_perm == None:
+ read_perm = 'zope.Public'
+ if selectedPermission and selectedPermission != read_perm:
+ continue
+ name = info['name']
+ views[name] = read_perm
+ settings = [entry[1] for entry in \
+ settingsForObject(viewInstance)]
+ for setting in settings:
+ rolePermMap = setting.get('rolePermissions', ())
+ principalRoles = setting.get('principalRoles', [])
+ for role in principalRoles:
+ principal = role['principal']
+ if read_perm == 'zope.Public':
+ permissionSetting = (role,'Allow')
+ else:
+ permissionSetting=principalRoleProvidesPermission(
+ principalRoles, rolePermMap,
+ principal, read_perm)
+ if permissionSetting[1]:
+ if viewMatrix.has_key(principal):
+ if viewMatrix[principal].has_key(name):
+ if viewMatrix[principal][name] != 'Deny':
+ viewMatrix[principal].update(
+ {name: permissionSetting[1]}
+ )
+ else:
+ viewMatrix[principal][name] = permissionSetting[1]
+ else:
+ viewMatrix[principal] = {name: permissionSetting[1]}
+
+ principalPermissions = setting.get('principalPermissions',[])
+ for principalPermission in principalPermissions:
+ if principalPermission['permission'] == read_perm:
+ principal = principalPermission['principal']
+ permissionSetting = principalPermission['setting'].getName()
+ if viewMatrix.has_key(principal):
+ if viewMatrix[principal].has_key(name):
+ if viewMatrix[principal][name] != 'Deny':
+ viewMatrix[principal].update(
+ {name: permissionSetting}
+ )
+ else:
+ viewMatrix[principal][name] = permissionSetting
+ else:
+ viewMatrix[principal] = {name: permissionSetting}
+ return [viewMatrix,views,permissions]
+
+ def principalPermissions(self, principal_id, skin=IBrowserRequest):
+ """Return all security settings for a `principal_id`."""
+
+ request = TestRequest()
+ applySkin(request, skin)
+
+ principals = zapi.principals()
+ principal = principals.getPrincipal(principal_id)
+
+ ifaces = tuple(providedBy(self.context))
+ for iface in ifaces:
+ for view_reg in getViews(iface, IBrowserRequest):
+ view = self.getView(view_reg, skin)
+ if not view:
+ continue
+ all_settings = [ settings[1] for settings in
+ settingsForObject(view) ]
+ prinPermSettings = self.policyPermissions(principal,
+ all_settings)
+
+ return prinPermSettings
+
+# TODO: Rename
+ def policyPermissions(self, principal, settings):
+ prinPermSettings = {'permissions': [],
+ 'roles': {},
+ 'groups': {}}
+ principals = zapi.principals()
+ for setting in settings:
+ for prinPerms in setting.get('principalPermissions', ()):
+ if prinPerms['principal'] == principal.id:
+ permission = prinPerms['permission']
+ _setting = prinPerms['setting'].getName()
+ mapping = {'permission': permission,
+ 'setting': _setting}
+ if not mapping in prinPermSettings['permissions']:
+ prinPermSettings['permissions'].append(mapping)
+ for prinRoles in setting.get('principalRoles', ()):
+ if prinRoles['principal'] != principal.id:
+ continue
+ role = prinRoles['role']
+ for rolePerms in setting['rolePermissions']:
+ if rolePerms['role'] == role:
+ permission = rolePerms['permission']
+ _setting = rolePerms['setting'].getName()
+ mapping = {'permission': permission,
+ 'setting': _setting}
+ perms = prinPermSettings['roles'].setdefault(
+ role, [])
+ if not mapping in perms:
+ perms.append(mapping)
+ for group_id in principal.groups:
+ group = principals.getPrincipal(group_id)
+ prinPermSettings['groups'][group_id] = \
+ self.policyPermissions(group, settings)
+ return prinPermSettings
+
+
+
+
+ def permissionDetails(self, principal_id, view_name, skin=IBrowserRequest):
+ """Get permission details for a given principal and view.
+
+ Includes the permissions set by the groups the principal belongs to.
+ """
+ principals = zapi.principals()
+ principal = principals.getPrincipal(principal_id)
+
+ read_perm = settings = None
+ ifaces = tuple(providedBy(self.context))
+ for iface in ifaces:
+ for view_reg in getViews(iface, skin):
+ if view_reg.name == view_name:
+
+ view = self.getView(view_reg, skin)
+ settings = settingsForObject(view)
+ read_perm = getViewInfoDictionary(view_reg)['read_perm']
+ break
+
+ if read_perm is None:
+ prinPermSettings = {'permissions': [],'roles': {},'groups': {}}
+ read_perm ='zope.Public'
+ else:
+ prinPermSettings = self._permissionDetails(principal, read_perm,
+ settings)
+
+ prinPermSettings['read_perm'] = read_perm
+
+ return prinPermSettings
+
+ def _permissionDetails(self, principal, read_perm, settings):
+ """Recursively get the permission details for a given principal and
+ permission from a security mapping.
+ """
+ principalSettings = {'permissions': [],
+ 'roles': {},
+ 'groups': {}}
+ principals = zapi.principals()
+ for name, setting in settings:
+ prinPermMap = setting.get('principalPermissions', ())
+ prinRoleMap = setting.get('principalRoles', ())
+ rolePermMap = setting.get('rolePermissions', ())
+ permSetting = principalDirectlyProvidesPermission(prinPermMap,
+ principal.id, read_perm)
+ if permSetting:
+ principalSettings['permissions'].append(
+ {'name': renderedName(name), 'setting': permSetting})
+ role_id, permSetting = principalRoleProvidesPermission(
+ prinRoleMap, rolePermMap, principal.id,read_perm )
+ if permSetting:
+ nameList = principalSettings['roles'].setdefault(role_id, [])
+ nameList.append({'name': renderedName(name),
+ 'setting': permSetting})
+
+ for group_id in principal.groups:
+ group = principals.getPrincipal(group_id)
+ group_settings = self._permissionDetails(group,
+ read_perm, settings)
+
+ if hasPermissionSetting(group_settings):
+ principalSettings['groups'][group_id] = group_settings
+
+ return principalSettings
+
+
+def getViews(iface, type=IRequest):
+ """Get all view registrations for a particular interface."""
+ gsm = getGlobalSiteManager()
+ for reg in gsm.registeredAdapters():
+ if (len(reg.required) == 2 and
+ reg.required[1] is not None and
+ type.isOrExtends(reg.required[1])):
+ if (reg.required[0] is None or
+ iface.isOrExtends(reg.required[0])):
+ yield reg
+
+# TODO: Not yet tested
+def hasPermissionSetting(settings):
+ """Check recursively if a security mapping contains any permission
+ setting.
+ """
+ if (settings['permissions'] or settings['roles']):
+ return True
+
+ for setting in settings['groups'].values():
+ if hasPermissionSetting(setting):
+ return True
+
+ return False
+
+def principalDirectlyProvidesPermission(prinPermMap, principal_id,
+ permission_id):
+ """Return directly provided permission setting for a given principal and
+ permission.
+ """
+ for prinPerm in prinPermMap:
+ if (prinPerm['principal'] == principal_id and
+ prinPerm['permission'] == permission_id):
+ return prinPerm['setting'].getName()
+
+def roleProvidesPermission(rolePermMap, role_id, permission_id):
+ """Return the permission setting for a given role and permission."""
+ for rolePerm in rolePermMap:
+ if (rolePerm['role'] == role_id and
+ rolePerm['permission'] == permission_id):
+ return rolePerm['setting'].getName()
+
+def principalRoleProvidesPermission(prinRoleMap, rolePermMap, principal_id,
+ permission_id):
+ """Return the role id and permission setting for a given principal and
+ permission.
+ """
+ for prinRole in prinRoleMap:
+ if (prinRole['principal'] == principal_id and
+ prinRole['setting'].getName() == 'Allow'):
+ role_id = prinRole['role']
+ return (role_id, roleProvidesPermission(rolePermMap, role_id,
+ permission_id))
+ return (None, None)
+
+def renderedName(name):
+ """The root folder is the only unlocated context object."""
+ if name is None:
+ return u'Root Folder'
+ return name
Added: z3c.securitytool/trunk/src/z3c/securitytool/tests.py
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/tests.py (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/tests.py 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,102 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests the zope policy.
+
+$Id: test_zopepolicy.py 73662 2007-03-27 06:52:40Z dobe $
+"""
+
+import unittest, doctest
+from zope.testing import module
+from zope.testing.doctestunit import DocFileSuite
+
+from zope.interface import Interface
+from zope.component import provideAdapter
+from zope.annotation.interfaces import IAnnotatable
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.annotation.interfaces import IAnnotations
+from zope.annotation.attribute import AttributeAnnotations
+from zope.security.management import endInteraction
+
+from zope.app.testing import placelesssetup, ztapi
+from zope.app.securitypolicy.interfaces import IGrantInfo
+from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager
+from zope.app.securitypolicy.interfaces import IRolePermissionManager
+from zope.app.securitypolicy.principalpermission \
+ import AnnotationPrincipalPermissionManager
+from zope.app.securitypolicy.principalrole \
+ import AnnotationPrincipalRoleManager
+from zope.app.securitypolicy.rolepermission \
+ import AnnotationRolePermissionManager
+from zope.app.securitypolicy.grantinfo \
+ import AnnotationGrantInfo
+from zope.app.authentication import principalfolder
+
+from z3c.securitytool.securitytool import SecurityChecker
+
+def setUp(test):
+ placelesssetup.setUp()
+# endInteraction()
+ ztapi.provideAdapter(
+ IAttributeAnnotatable, IAnnotations,
+ AttributeAnnotations)
+ ztapi.provideAdapter(
+ IAnnotatable, IPrincipalPermissionManager,
+ AnnotationPrincipalPermissionManager)
+ ztapi.provideAdapter(
+ IAnnotatable, IPrincipalRoleManager,
+ AnnotationPrincipalRoleManager)
+ ztapi.provideAdapter(
+ IAnnotatable, IRolePermissionManager,
+ AnnotationRolePermissionManager)
+ ztapi.provideAdapter(
+ IAnnotatable, IGrantInfo,
+ AnnotationGrantInfo)
+ # createPrincipalFolder(test)
+ # createPrincipals(test,'randy')
+ # createPrincipals(test,'markus')
+ # createPrincipals(test,'daniel')
+
+ module.setUp(test, 'z3c.securitytool.securitytool.README')
+ provideAdapter(SecurityChecker, (Interface,))
+
+# def defineRole(id, title=None, description=None):
+# role = Role(id, title, description)
+# ztapi.provideUtility(IRole, role, name=role.id)
+# return role
+#
+# def definePermission(id, title=None, description=None):
+# perm = Permission(id, title, description)
+# ztapi.provideUtility(IPermission, perm, name=perm.id)
+# return perm
+#
+# def createPrincipalFolder(test):
+# test.globs['pf'] = principalfolder.PrincipalFolder(u'Members.')
+#
+# def createPrincipals(test,name):
+# principal = principalfolder.InternalPrincipal(
+# name,'password',name,'SHA1')
+# test.globs['pf'][name] = principal
+
+
+def test_suite():
+ flags = doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',optionflags=flags,
+ setUp=setUp, tearDown=placelesssetup.tearDown),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Added: z3c.securitytool/trunk/src/z3c/securitytool/z3c.securitytool-configure.zcml
===================================================================
--- z3c.securitytool/trunk/src/z3c/securitytool/z3c.securitytool-configure.zcml (rev 0)
+++ z3c.securitytool/trunk/src/z3c/securitytool/z3c.securitytool-configure.zcml 2007-09-29 23:39:12 UTC (rev 80414)
@@ -0,0 +1,4 @@
+<configure
+ xmlns:zcml="http://namespaces.zope.org/zcml">
+ <include package="z3c.securitytool" />
+</configure>
More information about the Checkins
mailing list