Add ability to download roles / permissions matrix as Excel file
This commit is contained in:
parent
6463df7224
commit
e5f0831369
12
tailbone/templates/roles/index.mako
Normal file
12
tailbone/templates/roles/index.mako
Normal file
|
@ -0,0 +1,12 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/principal/index.mako" />
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
${parent.context_menu_items()}
|
||||
% if master.has_perm('download_permissions_matrix'):
|
||||
<li>${h.link_to("Download Permissions Matrix", url('roles.download_permissions_matrix'))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
|
||||
${parent.body()}
|
|
@ -26,12 +26,16 @@ Role Views
|
|||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import os
|
||||
|
||||
import six
|
||||
from sqlalchemy import orm
|
||||
from openpyxl.styles import Font, PatternFill
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db.auth import (has_permission, grant_permission, revoke_permission,
|
||||
administrator_role, guest_role, authenticated_role)
|
||||
from rattail.excel import ExcelWriter
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
|
@ -278,6 +282,69 @@ class RolesView(PrincipalMasterView):
|
|||
roles.append(role)
|
||||
return roles
|
||||
|
||||
def download_permissions_matrix(self):
|
||||
"""
|
||||
View which renders the complete role / permissions matrix data into an
|
||||
Excel spreadsheet, and returns that file.
|
||||
"""
|
||||
roles = self.Session.query(model.Role)\
|
||||
.order_by(model.Role.name)\
|
||||
.all()
|
||||
|
||||
permissions = self.get_available_permissions()
|
||||
|
||||
# prep the excel writer
|
||||
path = os.path.join(self.rattail_config.workdir(),
|
||||
'permissions-matrix.xlsx')
|
||||
writer = ExcelWriter(path, None)
|
||||
sheet = writer.sheet
|
||||
|
||||
# write header
|
||||
sheet.cell(row=1, column=1, value="")
|
||||
for i, role in enumerate(roles, 2):
|
||||
sheet.cell(row=1, column=i, value=role.name)
|
||||
|
||||
# font and fill pattern for permission group rows
|
||||
bold = Font(bold=True)
|
||||
group_fill = PatternFill(patternType='solid',
|
||||
fgColor='d9d9d9',
|
||||
bgColor='d9d9d9')
|
||||
|
||||
# now we'll write the rows
|
||||
writing_row = 2
|
||||
for groupkey in sorted(permissions, key=lambda k: permissions[k]['label'].lower()):
|
||||
group = permissions[groupkey]
|
||||
|
||||
# group label is bold, with fill pattern
|
||||
cell = sheet.cell(row=writing_row, column=1, value=group['label'])
|
||||
cell.font = bold
|
||||
cell.fill = group_fill
|
||||
|
||||
# continue fill pattern for rest of group row
|
||||
for col, role in enumerate(roles, 2):
|
||||
cell = sheet.cell(row=writing_row, column=col)
|
||||
cell.fill = group_fill
|
||||
|
||||
# okay, that row is done
|
||||
writing_row += 1
|
||||
|
||||
# now we list each perm in the group
|
||||
perms = group['perms']
|
||||
for key in sorted(perms, key=lambda p: perms[p]['label'].lower()):
|
||||
sheet.cell(row=writing_row, column=1, value=perms[key]['label'])
|
||||
|
||||
# and show an 'X' for any role which has this perm
|
||||
for col, role in enumerate(roles, 2):
|
||||
if has_permission(self.Session(), role, key, include_guest=False):
|
||||
sheet.cell(row=writing_row, column=col, value="X")
|
||||
|
||||
writing_row += 1
|
||||
|
||||
writer.auto_resize()
|
||||
writer.auto_freeze()
|
||||
writer.save()
|
||||
return self.file_response(path)
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
cls._principal_defaults(config)
|
||||
|
@ -286,6 +353,8 @@ class RolesView(PrincipalMasterView):
|
|||
|
||||
@classmethod
|
||||
def _role_defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
url_prefix = cls.get_url_prefix()
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
|
||||
# extra permissions for editing built-in roles etc.
|
||||
|
@ -296,6 +365,14 @@ class RolesView(PrincipalMasterView):
|
|||
config.add_tailbone_permission(permission_prefix, '{}.edit_my'.format(permission_prefix),
|
||||
"Edit Role(s) to which current user belongs")
|
||||
|
||||
# download permissions matrix
|
||||
config.add_tailbone_permission(permission_prefix, '{}.download_permissions_matrix'.format(permission_prefix),
|
||||
"Download complete Role/Permissions matrix")
|
||||
config.add_route('{}.download_permissions_matrix'.format(route_prefix), '{}/permissions-matrix'.format(url_prefix),
|
||||
request_method='GET')
|
||||
config.add_view(cls, attr='download_permissions_matrix', route_name='{}.download_permissions_matrix'.format(route_prefix),
|
||||
permission='{}.download_permissions_matrix'.format(permission_prefix))
|
||||
|
||||
|
||||
class PermissionsWidget(dfwidget.Widget):
|
||||
template = 'permissions'
|
||||
|
|
Loading…
Reference in a new issue