[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}&amp;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