mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-18 15:33:02 +00:00
add 'admin-ui' scope for access to the admin ui
This commit is contained in:
@@ -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.
|
||||
|
@@ -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}',
|
||||
|
@@ -31,6 +31,7 @@ def get_default_roles():
|
||||
'name': 'admin',
|
||||
'description': 'Elevated privileges (can do anything)',
|
||||
'scopes': [
|
||||
'admin-ui',
|
||||
'admin:users',
|
||||
'admin:servers',
|
||||
'tokens',
|
||||
|
@@ -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'],
|
||||
|
@@ -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(
|
||||
|
@@ -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 %}
|
||||
|
Reference in New Issue
Block a user