Skip to content

Commit

Permalink
- Fixed usability on ZMI Security tab forms for sites with many roles
Browse files Browse the repository at this point in the history
  • Loading branch information
dataflake committed May 23, 2019
1 parent d46045d commit d7be664
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 122 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -38,6 +38,11 @@ Fixes
(`#629 <https://github.com/zopefoundation/Zope/issues/629>`_).
Minor cleanup of ``HTTPRequest.get``.

Other changes
+++++++++++++

- Fixed usability on ZMI Security tab forms for sites with many roles


4.0 (2019-05-10)
----------------
Expand Down
196 changes: 121 additions & 75 deletions src/OFS/dtml/access.dtml
Expand Up @@ -8,19 +8,15 @@

<main class="container-fluid">

<dtml-let roles="valid_roles()"
short_form="len(roles) > 20">

<p class="form-help mb-4">
The listing below shows the current security settings for this item.
Permissions are rows and roles are columns. Checkboxes are used to
indicate where roles are assigned permissions. You can also assign
You can also assign
<strong><a href="manage_listLocalRoles">local roles</a></strong> to
users, which give users extra roles in the context of this object and
its subobjects.<br />
When a role is assigned to a permission, users with the given role
will be able to perform tasks associated with the permission on this
item. When the <em>Acquire permission settings</em> checkbox is selected
then the containing objects's permission settings are used. Note: the
acquired permission settings may be augmented by selecting Roles for
a permission in addition to selecting to acquire permissions.
</p>

<form action="manage_reportUserPermissions" method="get" class="mb-4">
Expand All @@ -42,81 +38,131 @@
</div>
</form>

<dtml-with expr="_.namespace(valid_roles=valid_roles())">
<form action="manage_changePermissions" method="post">
<table class="table table-hover table-bordered">
<thead>
<tr>
<th scope="col" colspan="2" class="zmi-table-head-permisions">
Permissions
</th>
<th scope="col" colspan="<dtml-var expr="_.len(valid_roles)">"
class="zmi-table-head-roles">Roles</th>
<th class="blank">&nbsp;</th>
</tr>
</thead>
<tbody>

<dtml-in permission_settings mapping>
<dtml-let permmission_title="name">
<dtml-if "not (_['sequence-index']%10)">
<tr class="zmi-table-head">
<th class="zmi-akcquire-title" title="Acquire?">
<dtml-unless isTopLevelPrincipiaApplicationObject>
<a href="manage_acquiredForm">Acquire?</a>
</dtml-unless>
</th>
<th class="zmi-permission" title="Permission">Permission</th>
<dtml-in valid_roles>
<th class="zmi-rolename" title="&dtml-sequence-item;">
<div><span>&dtml-sequence-item;</span></div>
<hr/>

<dtml-if short_form>

<h3>Permissions</h3>

<p class="form-help mb-4">
Click on one of the permission names to see the roles they are assigned
to.
</p>

<table>
<dtml-in "ac_inherited_permissions(1)">
<tr>
<td class="zmi-akcquire-title nowrap">
<dtml-let pname="_['sequence-key']">
<a href="manage_permissionForm?permission_to_manage=&dtml.url_quote-pname;">&dtml-pname;</a>
</dtml-let>
</td>
</tr>
</dtml-in>
</table>

<dtml-else>

<h3>Role to permission assignments</h3>

<p class="form-help mb-4">
This table shows which permissions are assigned to each role. Permissions
are rows and roles are columns.<br/>
When a role is assigned to a permission, users with the given role
will be able to perform tasks associated with the permission on this
item.
<dtml-unless isTopLevelPrincipiaApplicationObject>
<br/>
When the <em>Acquire?</em> checkbox is selected
then the containing objects's permission settings are used. Note: the
acquired permission settings may be augmented by selecting Roles for
a permission in addition to selecting to acquire permissions.
</dtml-unless>
</p>

<dtml-with "_.namespace(valid_roles=roles)">
<form action="manage_changePermissions" method="post">
<table class="table table-hover table-bordered">
<thead>
<tr>
<th scope="col" colspan="2" class="zmi-table-head-permisions">
Permissions
</th>
<th scope="col" colspan="<dtml-var expr="_.len(valid_roles)">"
class="zmi-table-head-roles">Roles</th>
<th class="blank">&nbsp;</th>
</tr>
</thead>
<tbody>

<dtml-in permission_settings mapping>
<dtml-let permmission_title="name">
<dtml-if "not (_['sequence-index']%10)">
<tr class="zmi-table-head">
<th class="zmi-akcquire-title" title="Acquire?">
<dtml-unless isTopLevelPrincipiaApplicationObject>
<a href="manage_acquiredForm">Acquire?</a>
</dtml-unless>
</th>
<th class="zmi-permission" title="Permission">Permission</th>
<dtml-in valid_roles>
<th class="zmi-rolename" title="&dtml-sequence-item;">
<div><span>&dtml-sequence-item;</span></div>
</th>
</dtml-in>
<th class="blank"><div><span>&nbsp;</span></div></th>
</tr>
</dtml-if>
<tr>
<td class="zmi-akcquire-check">
<dtml-if isTopLevelPrincipiaApplicationObject>
&nbsp;
<dtml-else>
<input type="checkbox" name="acquire_&dtml-hashed_name;"
&dtml-acquire; />
</dtml-if>
</td>
<td class="zmi-akcquire-title nowrap">
<a href="manage_permissionForm?permission_to_manage=&dtml.url_quote-name;">&dtml-name;</a>
</td>
<dtml-in roles mapping>
<td class="zmi-rolename-check"
title="Role: <dtml-var "valid_roles[_['sequence-index']]">"
onclick="$(this).children('input').trigger('click')">
<label class="sr-only sr-only-focusable"
for="&dtml-name;">
Role: <dtml-var "valid_roles[_['sequence-index']]">,
Permission: <dtml-var "_['permmission_title']">
</label>
<input type="checkbox" &dtml-checked; id="&dtml-name;"
name="&dtml-name;" onclick="event.stopPropagation()" />
</td>
</dtml-in>
<th class="blank"><div><span>&nbsp;</span></div></th>
<td class="blank">&nbsp;</td>
</tr>
</dtml-if>
<tr>
<td class="zmi-akcquire-check">
<dtml-if isTopLevelPrincipiaApplicationObject>
&nbsp;
<dtml-else>
<input type="checkbox" name="acquire_&dtml-hashed_name;"
&dtml-acquire; />
</dtml-if>
</td>
<td class="zmi-akcquire-title nowrap">
<a href="manage_permissionForm?permission_to_manage=&dtml.url_quote-name;">&dtml-name;</a>
</td>
<dtml-in roles mapping>
<td class="zmi-rolename-check"
title="Role: <dtml-var "valid_roles[_['sequence-index']]">"
onclick="$(this).children('input').trigger('click')">
<label class="sr-only sr-only-focusable"
for="&dtml-name;">
Role: <dtml-var "valid_roles[_['sequence-index']]">,
Permission: <dtml-var "_['permmission_title']">
</label>
<input type="checkbox" &dtml-checked; id="&dtml-name;"
name="&dtml-name;" onclick="event.stopPropagation()" />
</td>
</dtml-in>
<td class="blank">&nbsp;</td>
</tr>
</dtml-let>
</dtml-in permission_settings>
</dtml-let>
</dtml-in permission_settings>

</tbody>
</table>
</tbody>
</table>

<div class="zmi-controls">
<input type="submit" class="btn btn-primary" name="submit"
value="Save Changes" />
</div>
</form>
</dtml-with>
<div class="zmi-controls">
<input type="submit" class="btn btn-primary" name="submit"
value="Save Changes" />
</div>
</form>
</dtml-with>

</dtml-if short_form>

</dtml-let>

<dtml-if "_['id'] != 'acl_users'">

<hr/>

<h3>Add or delete user-defined roles</h3>

<p class="form-help mt-4">
You can define new roles by entering a role name and clicking the
&quot;Add Role&quot; button.
Expand Down
54 changes: 23 additions & 31 deletions src/OFS/dtml/editLocalRoles.dtml
Expand Up @@ -5,6 +5,8 @@
</dtml-with>

<main class="container-fluid">

<h3>Local roles for user <strong>&dtml-userid;</strong></h3>
<p class="form-help">
Local roles allow you to give particular users extra roles in the
context of this object, in addition to the roles they already have.
Expand All @@ -15,37 +17,27 @@
</p>

<form action="manage_setLocalRoles" method="post">
<table class="table table-md">
<thead>
<tr>
<th class="pl-3">User</th>
<th>Roles</th>
</tr>
</thead>
<tbody>
<tr>
<td class="pl-3">
&dtml-userid;
<input type="hidden" name="userid" value="&dtml-userid;" />
</td>
<td>
<dtml-with "_(user_roles=get_local_roles_for_userid(userid))">
<select class="form-control" name="roles:list" size="5"
multiple="multiple">
<dtml-in valid_roles>
<dtml-if "_vars['sequence-item'] not in ('Anonymous','Shared',
'Authenticated')">
<option value="&dtml-sequence-item;"
<dtml-if "_['sequence-item'] in user_roles">
selected="selected"
</dtml-if>>&dtml-sequence-item;</option>
</dtml-if>
</dtml-in>
</select>
</dtml-with>
</td>
</tr>
</tbody>
<input type="hidden" name="userid" value="&dtml-userid;" />

<table class="table table-striped table-hover table-sm">
<dtml-with "_(user_roles=get_local_roles_for_userid(userid))">
<dtml-in valid_roles>
<dtml-if "_vars['sequence-item'] not in ('Anonymous','Shared',
'Authenticated')">
<tr>
<td class="zmi-object-check text-right">
<input type="checkbox" name="roles:list"
id="&dtml-sequence-item;"
value="&dtml-sequence-item;"
<dtml-if "_['sequence-item'] in user_roles">
checked
</dtml-if>/>
</td>
<td>&dtml-sequence-item;</td>
</tr>
</dtml-if>
</dtml-in>
</dtml-with>
</table>

<div class="zmi-controls">
Expand Down
22 changes: 11 additions & 11 deletions src/OFS/dtml/listLocalRoles.dtml
Expand Up @@ -22,9 +22,8 @@
</dtml-if>
</p>



<dtml-if has_local_roles>

<form action="manage_delLocalRoles" method="POST"
class="zmi-localroles-delete">
<dtml-in get_local_roles>
Expand Down Expand Up @@ -86,17 +85,18 @@
</dtml-try>
</td>
<td>
<select id="roles" name="roles:list" class="form-control pb-4"
size="6" multiple="multiple" required="required">
<table class="table table-striped table-hover table-sm">
<dtml-in valid_roles>
<dtml-if "_vars['sequence-item'] not in ('Anonymous', 'Shared',
'Authenticated')">
<option value="&dtml-sequence-item;">
&dtml-sequence-item;
</option>
</dtml-if>
<tr>
<td class="zmi-object-check text-right">
<input type="checkbox" name="roles:list"
id="&dtml-sequence-item;"
value="&dtml-sequence-item;"/>
</td>
<td>&dtml-sequence-item;</td>
</tr>
</dtml-in>
</select>
</table>
</td>
</tr>
</tbody>
Expand Down
13 changes: 10 additions & 3 deletions src/OFS/dtml/permissionEdit.dtml
Expand Up @@ -15,11 +15,18 @@
<form action="manage_permission" method="post">
<input type="hidden" name="permission_to_manage"
value="&dtml-permission_to_manage;" />
<select class="form-control" name="roles:list" multiple>

<table class="table table-striped table-hover table-sm">
<dtml-in expr="rolesOfPermission(permission_to_manage)" mapping=1>
<option &dtml-selected;>&dtml-name;</option>
<tr>
<td class="zmi-object-check text-right">
<input type="checkbox" name="roles:list" value="&dtml-name;"
<dtml-if selected>checked</dtml-if>>
</td>
<td class="zmi-object-id">&dtml-name;</td>
</tr>
</dtml-in>
</select>
</table>

<dtml-unless isTopLevelPrincipiaApplicationObject>
<div class="form-check">
Expand Down
7 changes: 5 additions & 2 deletions src/OFS/role.py
Expand Up @@ -172,9 +172,12 @@ def manage_addLocalRoles(self, userid, roles, REQUEST=None):

@security.protected(change_permissions)
@requestmethod('POST')
def manage_setLocalRoles(self, userid, roles, REQUEST=None):
def manage_setLocalRoles(self, userid, roles=[], REQUEST=None):
"""Set local roles for a user."""
BaseRoleManager.manage_setLocalRoles(self, userid, roles)
if roles:
BaseRoleManager.manage_setLocalRoles(self, userid, roles)
else:
return self.manage_delLocalRoles((userid,), REQUEST)
if REQUEST is not None:
stat = 'Your changes have been saved.'
return self.manage_listLocalRoles(self, REQUEST, stat=stat)
Expand Down

0 comments on commit d7be664

Please sign in to comment.