[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security/Grants/Views/Browser - PrincipalPermissionView.py:1.1 PrincipalRoleView.py:1.1 RolePermissionView.py:1.1 __init__.py:1.1 configure.zcml:1.1 manage_access.pt:1.1 manage_permissionForm.pt:1.1 manage_roleForm.pt:1.1 principal_permission_edit.pt:1.1 principal_role_association.pt:1.1

Jim Fulton jim@zope.com
Thu, 20 Jun 2002 11:55:03 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/Security/Grants/Views/Browser
In directory cvs.zope.org:/tmp/cvs-serv15462/lib/python/Zope/App/Security/Grants/Views/Browser

Added Files:
	PrincipalPermissionView.py PrincipalRoleView.py 
	RolePermissionView.py __init__.py configure.zcml 
	manage_access.pt manage_permissionForm.pt manage_roleForm.pt 
	principal_permission_edit.pt principal_role_association.pt 
Log Message:
implemented:

http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/MergeSecurityIntoZopeNamespace

While I was at it, I couldn't resist implementing a variation of:

http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/SecurityPackageReorg

which was a lot more work. 



=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/PrincipalPermissionView.py ===
##############################################################################
#
# 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.0 (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.
# 
##############################################################################
"""

$Id: PrincipalPermissionView.py,v 1.1 2002/06/20 15:55:00 jim Exp $
"""
import time

from Zope.App.PageTemplate import ViewPageTemplateFile
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.ComponentArchitecture.ContextDependent import ContextDependent
from Zope.ComponentArchitecture import getService, getAdapter
from Zope.App.Security.IPrincipalPermissionMap import IPrincipalPermissionMap
from Zope.App.Security.IPrincipalPermissionManager \
     import IPrincipalPermissionManager
from Zope.App.Security.Settings import Allow, Deny, Unset

class PrincipalPermissionView(BrowserView):

    index = ViewPageTemplateFile('pt/principal_permission_edit.pt')

    def get_permission_service(self):
        return getService(self.context, 'PermissionService')

    def get_principal(self, principal_id):
        return getService(self.context,
                          'AuthenticationService'
                          ).getPrincipal(principal_id)

    def unsetPermissions(self, principal_id, permission_ids, REQUEST=None):
        """Form action unsetting a principals permissions"""
        permission_service = self.get_permission_service()
        principal = self.get_principal(principal_id)
        ppm = getAdapter(self.context, IPrincipalPermissionManager)

        for perm_id in permission_ids:
            permission = permission_service.getPermission(perm_id)
            ppm.unsetPermissionForPrincipal(permission , principal)

        if REQUEST is not None:
            return self.index(message="Settings changed at %s"
                                        % time.ctime(time.time()))

    def grantPermissions(self, principal_id, permission_ids, REQUEST=None):
        """Form action granting a list of permissions to a principal"""
        permission_service = self.get_permission_service()
        principal = self.get_principal(principal_id)
        ppm = getAdapter(self.context, IPrincipalPermissionManager)

        for perm_id in permission_ids:
            permission = permission_service.getPermission(perm_id)
            ppm.grantPermissionToPrincipal(permission , principal)
        if REQUEST is not None:
            return self.index(message="Settings changed at %s"
                                        % time.ctime(time.time()))

    def denyPermissions(self, principal_id, permission_ids, REQUEST=None):
        """Form action denying a list of permissions for a principal"""
        permission_service = self.get_permission_service()
        principal = self.get_principal(principal_id)
        ppm = getAdapter(self.context, IPrincipalPermissionManager)

        for perm_id in permission_ids:
            permission = permission_service.getPermission(perm_id)
            ppm.denyPermissionToPrincipal(permission , principal)
        if REQUEST is not None:
            return self.index(message="Settings changed at %s"
                                        % time.ctime(time.time()))

    # Methods only called from the zpt view
    def getUnsetPermissionsForPrincipal(self, principal_id):
        """Returns all unset permissions for this principal"""

        ppmap = getAdapter(self.context, IPrincipalPermissionMap)
        principal = self.get_principal(principal_id)
        perm_serv = getService(self.context, 'PermissionService')
        result = []
        for perm in perm_serv.getPermissions():
            if ppmap.getSetting(perm, principal) == Unset:
                result.append(perm)

        return result
        
    def getPermissionsForPrincipal(self, principal_id, setting_name):
        """Return a list of permissions with the given setting_name
           string for the principal.
           
           Return empty list if there are no permissions.
        """
    
        ppmap = getAdapter(self.context, IPrincipalPermissionMap)
        principal = self.get_principal(principal_id)
        
        permission_settings = ppmap.getPermissionsForPrincipal(principal)
        setting_map = {'Deny': Deny, 'Allow':Allow}
        asked_setting = setting_map[setting_name]

        result = []
        for permission, setting in permission_settings:
            if asked_setting == setting:
                result.append(permission)
            
        return result


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/PrincipalRoleView.py ===
##############################################################################
#
# 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.0 (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.
# 
##############################################################################
""" Management view component for principal-role management (Zope2's
    "local roles").

$Id: PrincipalRoleView.py,v 1.1 2002/06/20 15:55:00 jim Exp $
"""

import time
from Zope.App.PageTemplate import ViewPageTemplateFile
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.ComponentArchitecture.ContextDependent import ContextDependent
from Zope.ComponentArchitecture import getService, getAdapter

from Zope.App.Security.IPrincipalRoleManager import IPrincipalRoleManager
from Zope.App.Security.IPrincipalRoleMap import IPrincipalRoleMap

from Zope.App.Security.IPermission import IPermission
from Zope.App.Security.IRole import IRole

class PrincipalRoleView(BrowserView):

    index = ViewPageTemplateFile('principal_role_association.pt')

    def getAllPrincipals(self):

        principals = getattr(self, '_principals', None)

        if principals is None:
            principals = self._principals = getService(
                self.context, 'AuthenticationService'
                ).getPrincipals()

        return principals
    
    def getAllRoles(self):

        roles = getattr(self, '_roles', None)

        if roles is None:
            roles = self._roles = getService(self.context, 'RoleService'
                ).getRoles()

        return roles

    def createGrid( self, principals=None, roles=None ):

        if not principals:
            principals = self.getAllPrincipals()

        if not roles:
            roles = self.getAllRoles()

        return PrincipalRoleGrid( principals, roles, self.context )
        
    def action(self, principals, roles, mapping, testing=None):

        for row in mapping:
            pid = row.permission_id
            roles = row.role_ids

        if not testing:
            return self.index( 
                message="Settings changed at %s" % time.ctime(time.time())
                )


class PrincipalRoleGrid:

    def __init__( self, principals, roles, context ):    

        self._principals = principals
        self._roles = roles
        self._grid = {}

        map = getAdapter( context, IPrincipalRoleMap )

        for role in roles:
            for principal in principals:
                setting = map.getSetting( role, principal )
                self._grid[ ( role, principal ) ] = setting

    def principals( self ):
        return self._principals

    def roles( self ):
        return self._roles

    def getValue( self, role, principal ):
        return self._grid[ ( role, principal ) ]

    def listAvailableValues( self ):
        return ( 'Unset', 'Assigned', 'Removed' )



=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/RolePermissionView.py ===
##############################################################################
#
# 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.0 (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.
# 
##############################################################################
"""

$Id: RolePermissionView.py,v 1.1 2002/06/20 15:55:00 jim Exp $
"""

import time
from Zope.App.PageTemplate import ViewPageTemplateFile
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.ComponentArchitecture import getService, getAdapter
from Zope.App.Security.IRolePermissionManager import IRolePermissionManager
from Zope.App.Security.Grants.PermissionRoles import PermissionRoles
from Zope.App.Security.Grants.RolePermissions import RolePermissions


class RolePermissionView(BrowserView):

    index = ViewPageTemplateFile('manage_access.pt')
    manage_permissionForm = ViewPageTemplateFile('manage_permissionForm.pt')
    manage_roleForm = ViewPageTemplateFile('manage_roleForm.pt')
    
    def roles(self):
        roles = getattr(self, '_roles', None)
        if roles is None:
            roles = self._roles = getService(
                self.context, 'RoleService'
                ).getRoles()
        return roles

    def permissions(self):
        permissions = getattr(self, '_permissions', None)
        if permissions is None:
            permissions = self._permissions = getService(
                self.context, 'PermissionService'
                ).getPermissions()
        return permissions

        
    def permissionRoles(self):
        context = self.context
        roles = self.roles()
        return [PermissionRoles(permission, context, roles)
                for permission in self.permissions()]

    def permissionForID(self, pid):
        context = self.context
        roles = self.roles()
        perm = getService(context, 'PermissionService'
                          ).getPermission(pid)
        return PermissionRoles(perm, context, roles)

    def roleForID(self, rid):
        context = self.context
        permissions = self.permissions()
        role = getService(context, 'RoleService'
                          ).getRole(rid)
        return RolePermissions(role, context, permissions)


    def action(self, REQUEST, testing=None):
        roles       = [r.getId() for r in self.roles()]
        permissions = [p.getId() for p in self.permissions()]
        prm         = getAdapter(self.context, IRolePermissionManager)
        for ip in range(len(permissions)):
            rperm = REQUEST.get("p%s" % ip)
            if rperm not in permissions: continue
            for ir in range(len(roles)):
                rrole = REQUEST.get("r%s" % ir)
                if rrole not in roles: continue
                if ("p%sr%s" % (ip, ir))  in REQUEST:
                    prm.grantPermissionToRole(rperm, rrole)
                else:
                    prm.unsetPermissionFromRole(rperm, rrole)

        if not testing:
            return self.index( REQUEST,
                message="Settings changed at %s" % time.ctime(time.time())
                )

    def update_permission(self, REQUEST, permission_id,
                          roles=(), testing=None):
        prm = getAdapter(self.context, IRolePermissionManager)

        for ir in [r.getId() for r in self.roles()]:
            if ir in roles:
                prm.grantPermissionToRole(permission_id, ir)
            else:
                prm.unsetPermissionFromRole(permission_id, ir)
        if not testing:
            return self.index(REQUEST,
                              message="Settings changed at %s"
                                  % time.ctime(time.time())
                              )

    def update_role(self, REQUEST, role_id,
                    permissions=(), testing=None):
        prm = getAdapter(self.context, IRolePermissionManager)

        for ip in [p.getId() for p in self.permissions()]:
            if ip in permissions:
                prm.grantPermissionToRole(ip, role_id)
            else:
                prm.unsetPermissionFromRole(ip, role_id)
        if not testing:
            return self.index(REQUEST,
                              message="Settings changed at %s"
                                  % time.ctime(time.time())
                              )        
        
    


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/__init__.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""XXX short summary goes here.

XXX longer description goes here.

$Id: __init__.py,v 1.1 2002/06/20 15:55:00 jim Exp $
"""


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/configure.zcml ===
<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:zmi='http://namespaces.zope.org/zmi'
   xmlns:browser='http://namespaces.zope.org/browser'
>

<!-- Role-Permission management view -->
  
  <browser:view for="Zope.App.OFS.Annotation.IAnnotatable."
                permission="Zope.Security"
                factory=".RolePermissionView.">

    <browser:page name="AllRolePermissions.html" 
                  attribute="index" />
    <browser:page name="ChangeAllRolePermissions.html" 
                  attribute="action" />
    <browser:page name="RolePermissions.html" 
                  attribute="manage_RoleForm" />
    <browser:page name="ChangeRolePermissions.html" 
                  attribute="update_role" />
    <browser:page name="RolesWithPermission.html" 
                  attribute="manage_permissionForm" />
    <browser:page name="ChangeRolesWithPermission.html" 
                  attribute="update_permission" />
  </browser:view>

  <content class=".PrincipalPermissionView.">
    <require
        permission="Zope.Security"
        attributes="index get_principal unsetPermissions denyPermissions
                    grantPermissions getUnsetPermissionsForPrincipal
                    getPermissionsForPrincipal" />
  </content>

  <browser:view
      name="PrincipalPermissionsManagement"
      for="Zope.App.OFS.Annotation.IAnnotatable."
      factory=".PrincipalPermissionView." />
  
</zopeConfigure>


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/manage_access.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
<!--

h1 {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 24pt; 
  font-weight: bold; 
}

h2 {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 18pt; 
  font-weight: bold; 
}

h3 {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 14pt; 
  font-weight: bold; 
}

a:hover {  
  font-family: Verdana, Helvetica, sans-serif; 
  text-decoration: underline;
  color: #333333; 
}

a:link {
  font-family: Verdana, Helvetica, sans-serif; 
  text-decoration: none;
  color: #000099;
}

a {
  font-family: Verdana, Helvetica, sans-serif; 
  text-decoration: none;
  color: #000099;
}

a.strong-link {
  font-family: Verdana, Helvetica, sans-serif;
  text-decoration: underline;
  color: #000099;
}

p {
  font-family: Verdana, Helvetica, sans-serif;
  font-size: 10pt;
  color: #333333;
}

th {
  font-family: Verdana, Helvetica, sans-serif; 
  font-weight: bold;
  font-size: 10pt; 
  color: #333333;
}

.form-help {
  font-family: Verdana, Helvetica, sans-serif;
  font-size: 10pt;
  color: #333333;
}

.std-text {
  font-family: Verdana, Helvetica, sans-serif;
  font-size: 10pt;
  color: #333333;
}

.tab-small {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 8pt; 
  color: #333333;
}

.location-bar {
  background-color: #efefef;
  border: none;
}

.strong-header {
  font-family: Verdana, Helvetica, sans-serif;
  font-size: 12pt;
  font-weight: bold;
  background-color: #000000;
  color: #ffffff;
}

.list-header {
  background-color: #c0c0c0;
  border: none;
}

.list-item {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 10pt; 
}

.list-nav {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 10pt; 
  font-weight: bold;
}

.row-normal {
  background-color: #ffffff;
  border: none;

}

.row-hilite {
  background-color: #efefef;
  border: none;
}

.section-bar {
  background-color: #c0c0c0;
  border: none;
}

.system-msg {
  font-family: Verdana, Helvetica, sans-serif; 
  font-size: 10pt; 
  background-color: #ffffff;
  border:  1px solid #000000;
  margin-bottom: 6px;
  margin-top: 6px;
  padding: 4px;
  width: 100%;
  color: #660033;
}

.form-title {
  font-family: Verdana, Helvetica, sans-serif; 
  font-weight: bold;
  font-size: 12pt; 
  color: #333333;
}

.form-label {
  font-family: Verdana, Helvetica, sans-serif; 
  font-weight: bold;
  font-size: 10pt; 
  color: #333333;
}

.form-optional {
  font-family: Verdana, Helvetica, sans-serif; 
  font-weight: bold;
  font-style: italic;
  font-size: 10pt; 
  color: #333333;
}

.form-element {
  font-family: Verdana, Helvetica, aans-serif;
  font-size: 10pt;
  color: #000000;
}

.form-text {
  font-family: Verdana, Helvetica, sans-serif;
  font-size: 10pt;
  color: #333333;
}

.form-mono {
  font-family: monospace;
  font-size: 12px;
  text-decoration: none;
}

-->
</style>

</head>
<body bgcolor="#ffffff" link="#000099" alink="#000099" vlink="#000099">
<div metal:fill-slot="body">
<p class="form-help">
a helpful message
</p>

<p class="form-help">  
another helpful message
</p>

<form action="action.html" method="post">

<table width="100%" cellspacing="0" cellpadding="2" border="0" nowrap>
<tr class="list-header">
    <td align="left" valign="top">
      <div class="form-label">
        <strong>Permission</strong>
      </div>
  </td>
  <td align="left">
  <div class="form-label">
  <strong>Roles</strong>
  </div>
  </td>
</tr>

<tr class="row-normal">
  <td></td>
  <td align="center" tal:repeat="role view/roles">
    <div class="list-item">
      <a href="manage_roleForm.pt"
        tal:attributes="
        href string:manage_roleForm?role_to_manage=${role/getId}" 
        tal:content="role/getTitle">Anonymous</a>
      <input type="hidden" name="r0" value=""
        tal:attributes="
        name string:r${repeat/role/index};
        value  string:${role/getId}">

    </div>
  </td>
</tr>

<tbody tal:repeat="perm view/permissionRoles">
<tr class="row-hilite" 
    tal:condition="repeat/perm/odd"
    >
  <td align="left" nowrap>
    <div class="list-item">
       <a
       href="manage_permissionForm.pt"
       tal:attributes="
         href string:manage_permissionForm?permission_to_manage=${perm/getId}"
       tal:content="perm/getTitle"
       >Access Transient Objects</a>
       <input type="hidden" name="r0" value=""
         tal:attributes="
         name string:p${repeat/perm/index};
         value  string:${perm/getId}">
    </div>
  </td>
  <td align="center" tal:repeat="role perm/roles">
    <input type="checkbox" name="p0r0"
           tal:attributes="
           CHECKED role; 
           name string:p${repeat/perm/index}r${repeat/role/index}"
           />
  </td>
</tr>
<tr class="row-normal" 
    tal:condition="repeat/perm/even"
    >
  <td align="left" nowrap>
    <div class="list-item">
       <a
       href="manage_permissionForm.pt"
       tal:attributes="
         href string:manage_permissionForm?permission_to_manage=${perm/getId}"
       tal:content="perm/getTitle"
       >Access Transient Objects</a>
       <input type="hidden" name="r0" value=""
         tal:attributes="
         name string:p${repeat/perm/index};
         value  string:${perm/getId}">
    </div>
  </td>
  <td align="center" tal:repeat="role perm/roles">
    <input type="checkbox" name="p0r0"
           tal:attributes="
           CHECKED role; 
           name string:p${repeat/perm/index}r${repeat/role/index}"
            />
  </td>
</tr>
</tbody>

<tr>
<td colspan="5" align="left">
<div class="form-element">
<input class="form-element" type="submit" name="submit" value="Save Changes" />
<div tal:replace="options/message|nothing" />
</div>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>




=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/manage_permissionForm.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css" ></style>
</head>
<body bgcolor="#ffffff" link="#000099" alink="#000099" vlink="#000099">
<div metal:fill-slot="body">
<p class="form-help">
Helpful message.
</p>

<div tal:define="perm python:view.permissionForID(request.get('permission_to_manage'))">
<p class="form-text">
Roles assigned to the permission
<strong tal:content="perm/getTitle">Change DTML Methods</strong>
(id: <strong tal:content="perm/getId">Zope.Some.Permission</strong>)
</p>


<form action="update_permission" method="post">
<input type="hidden" name="permission_id" value="Permission Name"
    tal:attributes="value perm/getId" />
<div class="form-element">
<select name="roles:list" multiple size="10">
<option tal:repeat="role perm/rolesInfo"
        tal:content="role/title"
        tal:attributes="selected role/checked;
                        value role/id"
        >Sample</option>
</select>
</div>

<div class="form-element">
<input class="form-element" type="submit" name="submit" value="Save Changes" />
</div>
</form>

</div>
</div>
</body>
</html>


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/manage_roleForm.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css" ></style>
</head>
<body bgcolor="#ffffff" link="#000099" alink="#000099" vlink="#000099">
<div metal:fill-slot="body">
<p class="form-help">
Helpful message explaing about how to set specific roles
</p>

<div tal:define="role python:view.roleForID(request.get('role_to_manage'))" tal:omit-tag="">
<p class="form-text">
Permissions assigned to the role
<strong tal:content="role/getTitle">Great Master Guru</strong>
(id: <strong tal:content="role/getId">Zope.Some.Role</strong>)
</p>


<form action="update_role" method="get">
<input type="hidden" name="role_id" value="Role ID"
    tal:attributes="value role/getId" />
<div class="form-element">
<select name="permissions:list" multiple size="20">
<option tal:repeat="permission role/permissionsInfo"
        tal:content="permission/title"
        tal:attributes="selected permission/checked;
                        value permission/id"
        >Sample Permission</option>
</select>
</div>

<div class="form-element">
<input class="form-element" type="submit" name="submit" value="Save Changes" />
</div>
</form>

</div>
</div>
</body>
</html>


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/principal_permission_edit.pt ===
<html metal:use-macro="views/standard_macros/page">
<div metal:fill-slot="body" tal:define="rprincipal_id python:request['principal_id']">
<h1>Permission settings for <span tal:replace="python:view.get_principal(rprincipal_id).getTitle()">PrincipalName</span></h1>

<form action="unsetPermissions.html" method="post">
<h2>Permission Settings</h2>
<table>
  <tr>
    <td valign="top">
      <table border="0">
	<tr>
	  <th colspan="2" align="center">Allowed Permissions</th>
	</tr>
	<tr tal:repeat="perm python:view.get_set_permissions_for_principal(rprincipal_id, 'Allow')">
	  <td><input type="checkbox" tal:attributes="name perm/getId"></td><td tal:content="perm/getTitle">Permission1</td>
	</tr>
	<tr tal:replace="nothing">
	  <td><input type="checkbox" name="permission_ids"></td><td>Permission2</td>
	</tr>
	<tr tal:replace="nothing">
	  <td><input type="checkbox" name="permission_ids"></td><td>Permission3</td>
	</tr>
	<tr tal:replace="nothing">
	  <td><input type="checkbox" name="permission_ids"></td><td>Permission5</td>
	</tr>
      </table>
    </td>
    <td valign="top"> 
      <table border="0">
	<tr >
	  <th colspan="2" align="center">Denied Permissions</th>
	</tr>
	<tr tal:repeat="perm python:view.get_set_permissions_for_principal(rprincipal_id, 'Deny')">
	  <td><input type="checkbox" tal:attributes="name perm/getId"></td><td tal:content="perm/getTitle">Permission1</td>
	</tr>
	<tr tal:replace="nothing">
	  <td><input type="checkbox" name="permission_ids"></td><td>Permission2</td>
	</tr>
      </table>
    </td>
  </tr>
  <tr>
    <td colspan="2" align="center"><input type="submit" name="unset" value="Remove selected permission settings"></td></tr>
</table>
</form>
<p>&nbsp;</p>
<form action="./" method="post">
<h2>Add permission settings</h2>
  <table>
    <tr>
      <td>
	<select name="permissions" multiple>
	  <option 
	    tal:repeat="perm python:view.get_unset_permissions_for_principal(rprincipal_id)" 
	    tal:attributes="value perm/getId"
	    tal:content="perm/getTitle">Perm1</option>
	  <option tal:replace="nothing">Perm2</option>
	  <option tal:replace="nothing">Perm3</option>
	  <option tal:replace="nothing">Perm4</option>
	  <option tal:replace="nothing">Perm5</option>
	</select>
      </td>	
      <td valign="center">
	<p>
	  <input type="submit" name="grantPermissions.html:method" value="Grant">
	  </p>
	<p>
	  <input type="submit" name="denyPermissions.html:method" value="Deny">
	  </p>
      </td>
    </tr>
  </table>
</form>
</div>
</html>


=== Added File Zope3/lib/python/Zope/App/Security/Grants/Views/Browser/principal_role_association.pt ===
<html metal:use-macro="views/standard_macros/page">
  <head>
    <style metal:fill-slot="headers" type="text/css"> </style>
  </head>
  <body metal:fill-slot="main" tal:define="hasFilter python:request.get('Filter', None)">
      <div tal:condition="not: hasFilter">
        <span class="message"> Apply filter </span>       
        <form method="POST" action="" tal:attributes="action template/getId">
           <span tal:define="principals view/getAllPrincipals"> 
           Principal(s): 
            <select name="principals:list" multiple>
             <option tal:repeat="principal principals" tal:attributes="value principal/getId" tal:content="principal/getTitle">my title</option>
            </select>
           </span>
            
           <span tal:define="roles view/getAllRoles">
           Role(s): 
            <select name="roles:list" multiple>
             <option tal:repeat="role roles" tal:attributes="value role/getId" tal:content="role/getTitle">my title</option>
            </select>
           </span>
            
           <input type="submit" name="Filter" value="Filter" />
        </form>
        
      </div>      
      <!-- WANRING!! SELF POSTING FORM!! -->
      
      <div tal:condition="hasFilter">
        <div class="principalRolesGrid"
             tal:define="principalRoleGrid python:view.createGrid( request.get('roles', None), request.get('principals', None)); " >

          <span tal:define="global listPrincipals principalRoleGrid/principals;       
                            global listRoles principalRoleGrid/roles;
                            global listValues principalRoleGrid/listAvailabaleValues" />

          <form method="POST" action="apply">
          <table>
            <tr class="roleHeading">
              <td class="principal">
                &nbsp;
              </td>
              <td class="role" tal:repeat="role listRoles" tal:content="role/getId">
                role id
              </td>
            </tr>
            
            <tr class="principalRoleRow" tal:repeat="principal listPrincipals">
              <td class="principalLabel" tal:content="principal/getId">
							  Principal Id
              </td>
							
              <td class="principalRole" tal:repeat="role listRoles">
                <select name="mapping.principal.row" 
                        tal:attributes="name string:grid.${principal/getId}.${role/getId}:records"
                        tal:define="selectedValue python:1 or principalRoleGrid.grid(principal, role)" >
                  <option value="" tal:repeat="defaultValue listValues" 
                   tal:attributes="selected python:test(defaultValue==selectedValue, 'selected', '');
									                 value defaultValue;"
                   tal:content="defaultValue">
                  &nbsp;
                  </option>
                </select>
              </td>
            </tr>  
            
          </table>
					<input type="submit" name="apply" value="apply" />        
          </form>
          
        </div> 
      </div>
       
  </body>
</html>