Add initial version of "Find Users by Permission" page
This commit is contained in:
parent
afffb911d2
commit
dd5162c151
1
setup.py
1
setup.py
|
@ -87,6 +87,7 @@ requires = [
|
|||
'pyramid_simpleform', # 0.6.1
|
||||
'pyramid_tm', # 0.3
|
||||
'rattail[db,auth,bouncer]', # 0.5.0
|
||||
'six', # 1.10.0
|
||||
'transaction', # 1.2.0
|
||||
'waitress', # 0.8.1
|
||||
'WebHelpers', # 1.3
|
||||
|
|
81
tailbone/templates/users/find_by_perm.mako
Normal file
81
tailbone/templates/users/find_by_perm.mako
Normal file
|
@ -0,0 +1,81 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/base.mako" />
|
||||
|
||||
<%def name="title()">Find Users by Permission</%def>
|
||||
|
||||
<%def name="extra_javascript()">
|
||||
${parent.extra_javascript()}
|
||||
<script type="text/javascript">
|
||||
|
||||
<% gcount = len(permissions) %>
|
||||
var permissions_by_group = {
|
||||
% for g, (gkey, group) in enumerate(permissions, 1):
|
||||
<% pcount = len(group['perms']) %>
|
||||
'${gkey}': {
|
||||
% for p, (pkey, perm) in enumerate(group['perms'], 1):
|
||||
'${pkey}': "${perm['label']}"${',' if p < pcount else ''}
|
||||
% endfor
|
||||
}${',' if g < gcount else ''}
|
||||
% endfor
|
||||
};
|
||||
|
||||
$(function() {
|
||||
|
||||
$('#permission_group').selectmenu({
|
||||
change: function(event, ui) {
|
||||
var perms = $('#permission');
|
||||
perms.find('option:first').siblings('option').remove();
|
||||
$.each(permissions_by_group[ui.item.value], function(key, label) {
|
||||
perms.append($('<option value="' + key + '">' + label + '</option>'));
|
||||
});
|
||||
perms.selectmenu('refresh');
|
||||
}
|
||||
});
|
||||
|
||||
$('#permission').selectmenu();
|
||||
|
||||
$('#find-by-perm-form').submit(function() {
|
||||
$('.newgrid').remove();
|
||||
$(this).find('#submit').button('disable').button('option', 'label', "Searching, please wait...");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
${h.form(request.current_route_url(), id='find-by-perm-form')}
|
||||
${h.csrf_token(request)}
|
||||
|
||||
<div class="form">
|
||||
${self.wtfield(form, 'permission_group')}
|
||||
${self.wtfield(form, 'permission')}
|
||||
<div class="buttons">
|
||||
${h.submit('submit', "Find Users")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${h.end_form()}
|
||||
|
||||
% if users is not None:
|
||||
<div class="newgrid half">
|
||||
<br />
|
||||
<h2>Users with that permission (${len(users)} total):</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Person</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
% for user in users:
|
||||
<tr>
|
||||
<td>${h.link_to(user.username, url('users.view', uuid=user.uuid))}</td>
|
||||
<td>${user.person or ''}</td>
|
||||
</tr>
|
||||
% endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
% endif
|
11
tailbone/templates/users/index.mako
Normal file
11
tailbone/templates/users/index.mako
Normal file
|
@ -0,0 +1,11 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/master/index.mako" />
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
${parent.context_menu_items()}
|
||||
% if request.has_perm('users.find_by_perm'):
|
||||
<li>${h.link_to("Find Users with Permission X", url('users.find_by_perm'))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2016 Lance Edgar
|
||||
# Copyright © 2010-2017 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -26,11 +26,14 @@ User Views
|
|||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import copy
|
||||
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db.auth import guest_role, authenticated_role, set_user_password
|
||||
from rattail.db.auth import guest_role, authenticated_role, set_user_password, has_permission
|
||||
|
||||
import wtforms
|
||||
import formalchemy
|
||||
from formalchemy.fields import SelectFieldRenderer
|
||||
from webhelpers.html import HTML, tags
|
||||
|
@ -185,6 +188,73 @@ class UsersView(MasterView):
|
|||
del fs.password
|
||||
del fs.confirm_password
|
||||
|
||||
def find_by_perm(self):
|
||||
"""
|
||||
View for finding all users who have been granted a given permission
|
||||
"""
|
||||
permissions = copy.deepcopy(self.request.registry.settings.get('tailbone_permissions', {}))
|
||||
|
||||
# sort groups, and permissions for each group, for UI's sake
|
||||
sorted_perms = sorted(permissions.items(), key=lambda (k, v): v['label'].lower())
|
||||
for key, group in sorted_perms:
|
||||
group['perms'] = sorted(group['perms'].items(), key=lambda (k, v): v['label'].lower())
|
||||
|
||||
# group options are stable, permission options may depend on submitted group
|
||||
group_choices = [(gkey, group['label']) for gkey, group in sorted_perms]
|
||||
permission_choices = [('_any_', "(any)")]
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('permission_group') in permissions:
|
||||
permission_choices.extend([
|
||||
(pkey, perm['label'])
|
||||
for pkey, perm in permissions[self.request.POST['permission_group']]['perms']
|
||||
])
|
||||
|
||||
class PermissionForm(wtforms.Form):
|
||||
permission_group = wtforms.SelectField(choices=group_choices)
|
||||
permission = wtforms.SelectField(choices=permission_choices)
|
||||
|
||||
users = None
|
||||
form = PermissionForm(self.request.POST)
|
||||
if self.request.method == 'POST' and form.validate():
|
||||
permission = form.permission.data
|
||||
users = self.find_users_by_permission(self.Session(), permission)
|
||||
|
||||
context = {'form': form, 'permissions': sorted_perms, 'users': users}
|
||||
return self.render_to_response('find_by_perm', context)
|
||||
|
||||
def find_users_by_permission(self, session, permission):
|
||||
# TODO: this should search Permission table instead, and work backward to User?
|
||||
all_users = session.query(model.User)\
|
||||
.filter(model.User.active == True)\
|
||||
.order_by(model.User.username)\
|
||||
.options(orm.joinedload(model.User._roles)\
|
||||
.joinedload(model.UserRole.role)\
|
||||
.joinedload(model.Role._permissions))
|
||||
users = []
|
||||
for user in all_users:
|
||||
if has_permission(session, user, permission):
|
||||
users.append(user)
|
||||
return users
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
cls._user_defaults(config)
|
||||
cls._defaults(config)
|
||||
|
||||
@classmethod
|
||||
def _user_defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
url_prefix = cls.get_url_prefix()
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
model_title_plural = cls.get_model_title_plural()
|
||||
|
||||
# find users by permission
|
||||
config.add_route('{}.find_by_perm'.format(route_prefix), '{}/find-by-perm'.format(url_prefix))
|
||||
config.add_view(cls, attr='find_by_perm', route_name='{}.find_by_perm'.format(route_prefix),
|
||||
permission='{}.find_by_perm'.format(permission_prefix))
|
||||
config.add_tailbone_permission(permission_prefix, '{}.find_by_perm'.format(permission_prefix),
|
||||
"Find all {} with permission X".format(model_title_plural))
|
||||
|
||||
|
||||
class UserVersionView(VersionView):
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue