3
0
Fork 0

feat: add support for admin user to become / stop being root

This commit is contained in:
Lance Edgar 2024-08-05 14:21:54 -05:00
parent a2ba88ca8f
commit fc339ba81b
9 changed files with 335 additions and 22 deletions

View file

@ -137,3 +137,9 @@ class TestWuttaSecurityPolicy(TestCase):
self.user.roles.append(role)
self.session.commit()
self.assertTrue(self.policy.permits(self.request, None, 'baz.edit'))
# now let's try another perm - we won't grant it, but will
# confirm user is denied access unless they become root
self.assertFalse(self.policy.permits(self.request, None, 'some-root-perm'))
self.request.is_root = True
self.assertTrue(self.policy.permits(self.request, None, 'some-root-perm'))

View file

@ -18,40 +18,78 @@ class TestNewRequest(TestCase):
def setUp(self):
self.config = WuttaConfig()
self.request = self.make_request()
self.pyramid_config = testing.setUp(request=self.request, settings={
'wutta_config': self.config,
})
def tearDown(self):
testing.tearDown()
def make_request(self):
request = testing.DummyRequest()
request.registry.settings = {'wutta_config': self.config}
# request.registry.settings = {'wutta_config': self.config}
return request
def test_wutta_config(self):
request = self.make_request()
event = MagicMock(request=request)
event = MagicMock(request=self.request)
# request gets a new attr
self.assertFalse(hasattr(request, 'wutta_config'))
self.assertFalse(hasattr(self.request, 'wutta_config'))
subscribers.new_request(event)
self.assertTrue(hasattr(request, 'wutta_config'))
self.assertIs(request.wutta_config, self.config)
self.assertTrue(hasattr(self.request, 'wutta_config'))
self.assertIs(self.request.wutta_config, self.config)
def test_use_oruga_default(self):
request = self.make_request()
event = MagicMock(request=request)
event = MagicMock(request=self.request)
# request gets a new attr, false by default
self.assertFalse(hasattr(request, 'use_oruga'))
self.assertFalse(hasattr(self.request, 'use_oruga'))
subscribers.new_request(event)
self.assertFalse(request.use_oruga)
self.assertFalse(self.request.use_oruga)
def test_use_oruga_custom(self):
self.config.setdefault('wuttaweb.oruga_detector.spec', 'tests.test_subscribers:custom_oruga_detector')
request = self.make_request()
event = MagicMock(request=request)
event = MagicMock(request=self.request)
# request gets a new attr, which should be true
self.assertFalse(hasattr(request, 'use_oruga'))
self.assertFalse(hasattr(self.request, 'use_oruga'))
subscribers.new_request(event)
self.assertTrue(request.use_oruga)
self.assertTrue(self.request.use_oruga)
def test_get_referrer(self):
event = MagicMock(request=self.request)
def home(request):
pass
self.pyramid_config.add_route('home', '/')
self.pyramid_config.add_view(home, route_name='home')
self.assertFalse(hasattr(self.request, 'get_referrer'))
subscribers.new_request(event)
self.assertTrue(hasattr(self.request, 'get_referrer'))
# default if no referrer, is home route
url = self.request.get_referrer()
self.assertEqual(url, self.request.route_url('home'))
# can specify another default
url = self.request.get_referrer(default='https://wuttaproject.org')
self.assertEqual(url, 'https://wuttaproject.org')
# or referrer can come from user session
self.request.session['referrer'] = 'https://rattailproject.org'
self.assertIn('referrer', self.request.session)
url = self.request.get_referrer()
self.assertEqual(url, 'https://rattailproject.org')
# nb. referrer should also have been removed from user session
self.assertNotIn('referrer', self.request.session)
# or referrer can come from request params
self.request.params['referrer'] = 'https://kernel.org'
url = self.request.get_referrer()
self.assertEqual(url, 'https://kernel.org')
def custom_oruga_detector(request):
@ -97,6 +135,81 @@ class TestNewRequestSetUser(TestCase):
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIs(self.request.user, self.user)
def test_is_admin(self):
event = MagicMock(request=self.request)
# anonymous user
self.assertFalse(hasattr(self.request, 'user'))
self.assertFalse(hasattr(self.request, 'is_admin'))
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIsNone(self.request.user)
self.assertFalse(self.request.is_admin)
# reset
del self.request.is_admin
# authenticated user, but still not an admin
self.request.user = self.user
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIs(self.request.user, self.user)
self.assertFalse(self.request.is_admin)
# reset
del self.request.is_admin
# but if we make them an admin, it changes
auth = self.app.get_auth_handler()
admin = auth.get_role_administrator(self.session)
self.user.roles.append(admin)
self.session.commit()
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIs(self.request.user, self.user)
self.assertTrue(self.request.is_admin)
def test_is_root(self):
event = MagicMock(request=self.request)
# anonymous user
self.assertFalse(hasattr(self.request, 'user'))
self.assertFalse(hasattr(self.request, 'is_root'))
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIsNone(self.request.user)
self.assertFalse(self.request.is_root)
# reset
del self.request.is_admin
del self.request.is_root
# authenticated user, but still not an admin
self.request.user = self.user
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIs(self.request.user, self.user)
self.assertFalse(self.request.is_root)
# reset
del self.request.is_admin
del self.request.is_root
# even if we make them an admin, still not yet root
auth = self.app.get_auth_handler()
admin = auth.get_role_administrator(self.session)
self.user.roles.append(admin)
self.session.commit()
subscribers.new_request_set_user(event, db_session=self.session)
self.assertIs(self.request.user, self.user)
self.assertTrue(self.request.is_admin)
self.assertFalse(self.request.is_root)
# reset
del self.request.is_admin
del self.request.is_root
# root status flag lives in user session
self.request.session['is_root'] = True
subscribers.new_request_set_user(event, db_session=self.session)
self.assertTrue(self.request.is_admin)
self.assertTrue(self.request.is_root)
class TestBeforeRender(TestCase):

View file

@ -4,11 +4,12 @@ from unittest import TestCase
from unittest.mock import MagicMock
from pyramid import testing
from pyramid.httpexceptions import HTTPFound
from pyramid.httpexceptions import HTTPFound, HTTPForbidden
from wuttjamaican.conf import WuttaConfig
from wuttaweb.views import auth as mod
from wuttaweb.auth import WuttaSecurityPolicy
from wuttaweb.subscribers import new_request
class TestAuthView(TestCase):
@ -19,7 +20,9 @@ class TestAuthView(TestCase):
})
self.request = testing.DummyRequest(wutta_config=self.config, user=None)
self.pyramid_config = testing.setUp(request=self.request)
self.pyramid_config = testing.setUp(request=self.request, settings={
'wutta_config': self.config,
})
self.app = self.config.get_app()
auth = self.app.get_auth_handler()
@ -142,3 +145,46 @@ class TestAuthView(TestCase):
self.assertIn('form', context)
dform = context['form'].get_deform()
self.assertEqual(dform['new_password'].errormsg, "New password must be different from old password.")
def test_become_root(self):
event = MagicMock(request=self.request)
new_request(event) # add request.get_referrer()
view = mod.AuthView(self.request)
# GET not allowed
self.request.method = 'GET'
self.assertRaises(HTTPForbidden, view.become_root)
# non-admin users also not allowed
self.request.method = 'POST'
self.request.is_admin = False
self.assertRaises(HTTPForbidden, view.become_root)
# but admin users can become root
self.request.is_admin = True
self.assertNotIn('is_root', self.request.session)
redirect = view.become_root()
self.assertIsInstance(redirect, HTTPFound)
self.assertTrue(self.request.session['is_root'])
def test_stop_root(self):
event = MagicMock(request=self.request)
new_request(event) # add request.get_referrer()
view = mod.AuthView(self.request)
# GET not allowed
self.request.method = 'GET'
self.assertRaises(HTTPForbidden, view.stop_root)
# non-admin users also not allowed
self.request.method = 'POST'
self.request.is_admin = False
self.assertRaises(HTTPForbidden, view.stop_root)
# but admin users can stop being root
# (nb. there is no check whether user is currently root)
self.request.is_admin = True
self.assertNotIn('is_root', self.request.session)
redirect = view.stop_root()
self.assertIsInstance(redirect, HTTPFound)
self.assertFalse(self.request.session['is_root'])

View file

@ -3,7 +3,7 @@
from unittest import TestCase
from pyramid import testing
from pyramid.httpexceptions import HTTPFound
from pyramid.httpexceptions import HTTPFound, HTTPForbidden
from wuttjamaican.conf import WuttaConfig
from wuttaweb.views import base
@ -23,6 +23,10 @@ class TestView(TestCase):
self.assertIs(self.view.config, self.config)
self.assertIs(self.view.app, self.app)
def test_forbidden(self):
error = self.view.forbidden()
self.assertIsInstance(error, HTTPForbidden)
def test_make_form(self):
form = self.view.make_form()
self.assertIsInstance(form, Form)