From fc339ba81bbacca8490841c4e2a98836422ebfec Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 5 Aug 2024 14:21:54 -0500 Subject: [PATCH] feat: add support for admin user to become / stop being root --- src/wuttaweb/auth.py | 6 +- src/wuttaweb/subscribers.py | 51 ++++++++++- src/wuttaweb/templates/base.mako | 35 +++++++- src/wuttaweb/views/auth.py | 54 ++++++++++++ src/wuttaweb/views/base.py | 8 ++ tests/test_auth.py | 6 ++ tests/test_subscribers.py | 141 ++++++++++++++++++++++++++++--- tests/views/test_auth.py | 50 ++++++++++- tests/views/test_base.py | 6 +- 9 files changed, 335 insertions(+), 22 deletions(-) diff --git a/src/wuttaweb/auth.py b/src/wuttaweb/auth.py index 0c2f26d..de9b868 100644 --- a/src/wuttaweb/auth.py +++ b/src/wuttaweb/auth.py @@ -138,9 +138,13 @@ class WuttaSecurityPolicy: return self.session_helper.forget(request, **kw) def permits(self, request, context, permission): + + # nb. root user can do anything + if getattr(request, 'is_root', False): + return True + config = request.registry.settings['wutta_config'] app = config.get_app() auth = app.get_auth_handler() - user = self.identity(request) return auth.has_permission(self.db_session, user, permission) diff --git a/src/wuttaweb/subscribers.py b/src/wuttaweb/subscribers.py index eebefb4..1b711e3 100644 --- a/src/wuttaweb/subscribers.py +++ b/src/wuttaweb/subscribers.py @@ -63,6 +63,16 @@ def new_request(event): Reference to the app :term:`config object`. + .. method:: request.get_referrer(default=None) + + Request method to get the "canonical" HTTP referrer value. + This has logic to check for referrer in the request params, + user session etc. + + :param default: Optional default URL if none is found in + request params/session. If no default is specified, + the ``'home'`` route is used. + .. attribute:: request.use_oruga Flag indicating whether the frontend should be displayed using @@ -75,6 +85,19 @@ def new_request(event): request.wutta_config = config + def get_referrer(default=None): + if request.params.get('referrer'): + return request.params['referrer'] + if request.session.get('referrer'): + return request.session.pop('referrer') + referrer = getattr(request, 'referrer', None) + if (not referrer or referrer == request.current_route_url() + or not referrer.startswith(request.host_url)): + referrer = default or request.route_url('home') + return referrer + + request.get_referrer = get_referrer + def use_oruga(request): spec = config.get('wuttaweb.oruga_detector.spec') if spec: @@ -104,22 +127,44 @@ def new_request_set_user(event, db_session=None): :class:`~wuttjamaican:wuttjamaican.db.model.auth.User` instance (if logged in), or ``None``. - :param db_session: Optional :term:`db session` to use, instead of - :class:`wuttaweb.db.Session`. Probably only useful for tests. + .. attribute:: request.is_admin + + Flag indicating whether current user is a member of the + Administrator role. + + .. attribute:: request.is_root + + Flag indicating whether user is currently elevated to root + privileges. This is only possible if :attr:`request.is_admin` + is also true. """ request = event.request config = request.registry.settings['wutta_config'] app = config.get_app() - model = app.model def user(request): uuid = request.authenticated_userid if uuid: session = db_session or Session() + model = app.model return session.get(model.User, uuid) request.set_property(user, reify=True) + def is_admin(request): + auth = app.get_auth_handler() + return auth.user_is_admin(request.user) + + request.set_property(is_admin, reify=True) + + def is_root(request): + if request.is_admin: + if request.session.get('is_root', False): + return True + return False + + request.set_property(is_root, reify=True) + def before_render(event): """ diff --git a/src/wuttaweb/templates/base.mako b/src/wuttaweb/templates/base.mako index dd51690..b04c980 100644 --- a/src/wuttaweb/templates/base.mako +++ b/src/wuttaweb/templates/base.mako @@ -314,8 +314,29 @@ <%def name="render_user_menu()"> % if request.user: