Add auditable superuser mode (#824)

* Remove is_superuser everywhere

* Session handling

* List of sessions, relative timeout

* Absolute timeout

* Optionally pseudo-force audit comments

* Fix failing tests

* Add tests

* Add docs

* Rebsae migration

* Typos

* Fix tests
This commit is contained in:
Raphael Michel
2018-03-28 14:16:58 +02:00
committed by GitHub
parent 558c920181
commit a284e0c2f7
56 changed files with 965 additions and 130 deletions

View File

@@ -1,4 +1,7 @@
from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.http import urlquote
from django.utils.translation import ugettext as _
@@ -18,8 +21,7 @@ def event_permission_required(permission):
raise PermissionDenied()
allowed = (
request.user.is_superuser
or request.user.has_event_permission(request.organizer, request.event, permission)
request.user.has_event_permission(request.organizer, request.event, permission, request=request)
)
if allowed:
return function(request, *args, **kw)
@@ -57,10 +59,7 @@ def organizer_permission_required(permission):
# just a double check, should not ever happen
raise PermissionDenied()
allowed = (
request.user.is_superuser
or request.user.has_organizer_permission(request.organizer, permission)
)
allowed = request.user.has_organizer_permission(request.organizer, permission, request=request)
if allowed:
return function(request, *args, **kw)
@@ -85,14 +84,33 @@ class OrganizerPermissionRequiredMixin:
def administrator_permission_required():
"""
This view decorator rejects all requests with a 403 response which are not from
users with the is_superuser flag.
users with a current staff member session.
"""
def decorator(function):
def wrapper(request, *args, **kw):
if not request.user.is_authenticated: # NOQA
# just a double check, should not ever happen
raise PermissionDenied()
if not request.user.is_superuser:
if not request.user.has_active_staff_session(request.session.session_key):
if request.user.is_staff:
return redirect(reverse('control:user.sudo') + '?next=' + urlquote(request.path))
raise PermissionDenied(_('You do not have permission to view this content.'))
return function(request, *args, **kw)
return wrapper
return decorator
def staff_member_required():
"""
This view decorator rejects all requests with a 403 response which are not staff
members (but do not need to have an active session).
"""
def decorator(function):
def wrapper(request, *args, **kw):
if not request.user.is_authenticated: # NOQA
# just a double check, should not ever happen
raise PermissionDenied()
if not request.user.is_staff:
raise PermissionDenied(_('You do not have permission to view this content.'))
return function(request, *args, **kw)
return wrapper
@@ -108,3 +126,14 @@ class AdministratorPermissionRequiredMixin:
def as_view(cls, **initkwargs):
view = super(AdministratorPermissionRequiredMixin, cls).as_view(**initkwargs)
return administrator_permission_required()(view)
class StaffMemberRequiredMixin:
"""
This mixin is equivalent to the staff_memer_required view decorator but
is in a form suitable for class-based views.
"""
@classmethod
def as_view(cls, **initkwargs):
view = super(StaffMemberRequiredMixin, cls).as_view(**initkwargs)
return staff_member_required()(view)