add 'admin-ui' scope for access to the admin ui

This commit is contained in:
Min RK
2022-04-29 11:45:58 +02:00
parent ec2c90c73f
commit debac715bf
6 changed files with 25 additions and 8 deletions

View File

@@ -1391,6 +1391,9 @@ components:
inherit:
Everything that the token-owning entity can access _(metascope
for tokens)_
admin-ui:
Access the admin page. Permission to take actions via the admin
page granted separately.
admin:users:
Read, write, create and delete users and their authentication
state, not including their servers or tokens.

View File

@@ -454,15 +454,14 @@ class AdminHandler(BaseHandler):
@web.authenticated
# stacked decorators: all scopes must be present
# note: keep in sync with admin link condition in page.html
@needs_scope('admin:users')
@needs_scope('admin:servers')
@needs_scope('admin-ui')
async def get(self):
auth_state = await self.current_user.get_auth_state()
html = await self.render_template(
'admin.html',
current_user=self.current_user,
auth_state=auth_state,
admin_access=self.settings.get('admin_access', False),
admin_access=True,
allow_named_servers=self.allow_named_servers,
named_server_limit_per_user=self.named_server_limit_per_user,
server_version=f'{__version__} {self.version_hash}',

View File

@@ -31,6 +31,7 @@ def get_default_roles():
'name': 'admin',
'description': 'Elevated privileges (can do anything)',
'scopes': [
'admin-ui',
'admin:users',
'admin:servers',
'tokens',

View File

@@ -42,6 +42,10 @@ scope_definitions = {
'description': 'Anything you have access to',
'doc_description': 'Everything that the token-owning entity can access _(metascope for tokens)_',
},
'admin-ui': {
'description': 'Access the admin page.',
'doc_description': 'Access the admin page. Permission to take actions via the admin page granted separately.',
},
'admin:users': {
'description': 'Read, write, create and delete users and their authentication state, not including their servers or tokens.',
'subscopes': ['admin:auth_state', 'users', 'read:roles:users', 'delete:users'],

View File

@@ -1105,17 +1105,27 @@ async def test_bad_oauth_get(app, params):
[
(["users"], False),
(["admin:users"], False),
(["users", "admin:users", "admin:servers"], True),
(["users", "admin:users", "admin:servers"], False),
(["admin-ui"], True),
],
)
async def test_admin_page_access(app, scopes, has_access, create_user_with_scopes):
user = create_user_with_scopes(*scopes)
cookies = await app.login_user(user.name)
r = await get_page("/admin", app, cookies=cookies)
home_resp = await get_page("/home", app, cookies=cookies)
admin_resp = await get_page("/admin", app, cookies=cookies)
assert home_resp.status_code == 200
soup = BeautifulSoup(home_resp.text, "html.parser")
nav = soup.find("div", id="thenavbar")
links = [a["href"] for a in nav.find_all("a")]
admin_url = app.base_url + "hub/admin"
if has_access:
assert r.status_code == 200
assert admin_resp.status_code == 200
assert admin_url in links
else:
assert r.status_code == 403
assert admin_resp.status_code == 403
assert admin_url not in links
async def test_oauth_page_scope_appearance(

View File

@@ -122,7 +122,7 @@
{% block nav_bar_left_items %}
<li><a href="{{base_url}}home">Home</a></li>
<li><a href="{{base_url}}token">Token</a></li>
{% if 'admin:users' in parsed_scopes and 'admin:servers' in parsed_scopes %}
{% if 'admin-ui' in parsed_scopes %}
<li><a href="{{base_url}}admin">Admin</a></li>
{% endif %}
{% if services %}