Add permissions field when viewing user details

About damn time I'm sure...
This commit is contained in:
Lance Edgar 2016-08-12 01:58:07 -05:00
parent a70c9d3360
commit a6438e4bb5
5 changed files with 74 additions and 58 deletions

View file

@ -38,7 +38,7 @@ from .files import FileFieldRenderer
from .people import (PersonFieldRenderer, PersonFieldLinkRenderer, from .people import (PersonFieldRenderer, PersonFieldLinkRenderer,
CustomerFieldRenderer, CustomerFieldLinkRenderer) CustomerFieldRenderer, CustomerFieldLinkRenderer)
from .users import UserFieldRenderer from .users import UserFieldRenderer, PermissionsFieldRenderer
from .employees import EmployeeFieldRenderer from .employees import EmployeeFieldRenderer

View file

@ -26,7 +26,13 @@ User Field Renderers
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from rattail.db import model
from rattail.db.auth import has_permission, administrator_role
import formalchemy import formalchemy
from webhelpers.html import HTML, tags
from tailbone.db import Session
class UserFieldRenderer(formalchemy.TextFieldRenderer): class UserFieldRenderer(formalchemy.TextFieldRenderer):
@ -39,3 +45,56 @@ class UserFieldRenderer(formalchemy.TextFieldRenderer):
if not user: if not user:
return '' return ''
return user.display_name return user.display_name
def PermissionsFieldRenderer(permissions, include_guest=False, include_authenticated=False):
class PermissionsFieldRenderer(formalchemy.FieldRenderer):
def deserialize(self):
perms = []
i = len(self.name) + 1
for key in self.params:
if key.startswith(self.name):
perms.append(key[i:])
return perms
def _render(self, readonly=False, **kwargs):
principal = self.field.model
if isinstance(principal, model.Role) and principal is administrator_role(Session()):
html = HTML.tag('p', c="This is the administrative role; "
"it has full access to the entire system.")
if not readonly:
html += tags.hidden(self.name, value='') # ugly hack..or good idea?
else:
html = ''
for groupkey in sorted(permissions, key=lambda k: permissions[k]['label'].lower()):
inner = HTML.tag('p', c=permissions[groupkey]['label'])
perms = permissions[groupkey]['perms']
rendered = False
for key in sorted(perms, key=lambda p: perms[p]['label'].lower()):
checked = has_permission(Session(), principal, key,
include_guest=include_guest,
include_authenticated=include_authenticated)
if checked or not readonly:
label = perms[key]['label']
if readonly:
span = HTML.tag('span', c="[X]" if checked else "[ ]")
inner += HTML.tag('p', class_='perm', c=span + ' ' + label)
else:
inner += tags.checkbox(self.name + '-' + key,
checked=checked, label=label)
rendered = True
if rendered:
html += HTML.tag('div', class_='group', c=inner)
if not html:
return "(none granted)"
return html
def render(self, **kwargs):
return self._render(**kwargs)
def render_readonly(self, **kwargs):
return self._render(readonly=True, **kwargs)
return PermissionsFieldRenderer

View file

@ -1,6 +1,11 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8 -*-
<%inherit file="/master/view.mako" /> <%inherit file="/master/view.mako" />
<%def name="head_tags()">
${parent.head_tags()}
${h.stylesheet_link(request.static_url('tailbone:static/css/perms.css'))}
</%def>
<%def name="context_menu_items()"> <%def name="context_menu_items()">
${parent.context_menu_items()} ${parent.context_menu_items()}
% if version_count is not Undefined and request.has_perm('user.versions.view'): % if version_count is not Undefined and request.has_perm('user.versions.view'):

View file

@ -32,6 +32,7 @@ from rattail.db.auth import has_permission, administrator_role, guest_role, auth
import formalchemy import formalchemy
from webhelpers.html import HTML, tags from webhelpers.html import HTML, tags
from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView from tailbone.views import MasterView
from tailbone.views.continuum import VersionView, version_defaults from tailbone.views.continuum import VersionView, version_defaults
@ -49,60 +50,6 @@ class PermissionsField(formalchemy.Field):
role.permissions = self.renderer.deserialize() role.permissions = self.renderer.deserialize()
def PermissionsFieldRenderer(permissions, *args, **kwargs):
class PermissionsFieldRenderer(formalchemy.FieldRenderer):
def deserialize(self):
perms = []
i = len(self.name) + 1
for key in self.params:
if key.startswith(self.name):
perms.append(key[i:])
return perms
def _render(self, readonly=False, **kwargs):
role = self.field.model
admin = administrator_role(Session())
if role is admin:
html = HTML.tag('p', c="This is the administrative role; "
"it has full access to the entire system.")
if not readonly:
html += tags.hidden(self.name, value='') # ugly hack..or good idea?
else:
html = ''
for groupkey in sorted(permissions, key=lambda k: permissions[k]['label'].lower()):
inner = HTML.tag('p', c=permissions[groupkey]['label'])
perms = permissions[groupkey]['perms']
rendered = False
for key in sorted(perms, key=lambda p: perms[p]['label'].lower()):
checked = has_permission(Session(), role, key,
include_guest=False,
include_authenticated=False)
if checked or not readonly:
label = perms[key]['label']
if readonly:
span = HTML.tag('span', c="[X]" if checked else "[ ]")
inner += HTML.tag('p', class_='perm', c=span + ' ' + label)
else:
inner += tags.checkbox(self.name + '-' + key,
checked=checked, label=label)
rendered = True
if rendered:
html += HTML.tag('div', class_='group', c=inner)
if not html:
return "(none granted)"
return html
def render(self, **kwargs):
return self._render(**kwargs)
def render_readonly(self, **kwargs):
return self._render(readonly=True, **kwargs)
return PermissionsFieldRenderer
class RolesView(MasterView): class RolesView(MasterView):
""" """
Master view for the Role model. Master view for the Role model.
@ -122,7 +69,7 @@ class RolesView(MasterView):
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.append(PermissionsField('permissions')) fs.append(PermissionsField('permissions'))
permissions = self.request.registry.settings.get('tailbone_permissions', {}) permissions = self.request.registry.settings.get('tailbone_permissions', {})
fs.permissions.set(renderer=PermissionsFieldRenderer(permissions)) fs.permissions.set(renderer=forms.renderers.PermissionsFieldRenderer(permissions))
fs.configure( fs.configure(
include=[ include=[
fs.name, fs.name,

View file

@ -35,10 +35,10 @@ import formalchemy
from formalchemy.fields import SelectFieldRenderer from formalchemy.fields import SelectFieldRenderer
from webhelpers.html import HTML, tags from webhelpers.html import HTML, tags
from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView from tailbone.views import MasterView
from tailbone.views.continuum import VersionView, version_defaults from tailbone.views.continuum import VersionView, version_defaults
from tailbone.forms import renderers
def unique_username(value, field): def unique_username(value, field):
@ -159,7 +159,7 @@ class UsersView(MasterView):
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.username.set(validate=unique_username) fs.username.set(validate=unique_username)
fs.person.set(options=[]) fs.person.set(options=[])
fs.person.set(renderer=renderers.PersonFieldLinkRenderer) fs.person.set(renderer=forms.renderers.PersonFieldLinkRenderer)
fs.append(PasswordField('password', label="Set Password")) fs.append(PasswordField('password', label="Set Password"))
fs.password.attrs(autocomplete='off') fs.password.attrs(autocomplete='off')
fs.append(formalchemy.Field('confirm_password', renderer=PasswordFieldRenderer)) fs.append(formalchemy.Field('confirm_password', renderer=PasswordFieldRenderer))
@ -177,6 +177,11 @@ class UsersView(MasterView):
if self.viewing: if self.viewing:
del fs.password del fs.password
del fs.confirm_password del fs.confirm_password
permissions = self.request.registry.settings.get('tailbone_permissions', {})
renderer = forms.renderers.PermissionsFieldRenderer(permissions,
include_guest=True,
include_authenticated=True)
fs.append(formalchemy.Field('permissions', renderer=renderer))
class UserVersionView(VersionView): class UserVersionView(VersionView):