mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-09 19:13:03 +00:00
Clarify some function names in rbac utils
This commit is contained in:
@@ -336,7 +336,7 @@ class UserTokenListAPIHandler(APIHandler):
|
|||||||
# couldn't identify requester
|
# couldn't identify requester
|
||||||
raise web.HTTPError(403)
|
raise web.HTTPError(403)
|
||||||
self._jupyterhub_user = requester
|
self._jupyterhub_user = requester
|
||||||
self._resolve_scopes()
|
self._resolve_roles_and_scopes()
|
||||||
user = self.find_user(user_name)
|
user = self.find_user(user_name)
|
||||||
kind = 'user' if isinstance(requester, User) else 'service'
|
kind = 'user' if isinstance(requester, User) else 'service'
|
||||||
scope_filter = self.get_scope_filter('users:tokens')
|
scope_filter = self.get_scope_filter('users:tokens')
|
||||||
|
@@ -87,7 +87,7 @@ class BaseHandler(RequestHandler):
|
|||||||
except Exception:
|
except Exception:
|
||||||
self.log.exception("Failed to get current user")
|
self.log.exception("Failed to get current user")
|
||||||
self._jupyterhub_user = None
|
self._jupyterhub_user = None
|
||||||
self._resolve_scopes()
|
self._resolve_roles_and_scopes()
|
||||||
return await maybe_future(super().prepare())
|
return await maybe_future(super().prepare())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -416,7 +416,7 @@ class BaseHandler(RequestHandler):
|
|||||||
self.log.exception("Error getting current user")
|
self.log.exception("Error getting current user")
|
||||||
return self._jupyterhub_user
|
return self._jupyterhub_user
|
||||||
|
|
||||||
def _resolve_scopes(self):
|
def _resolve_roles_and_scopes(self):
|
||||||
self.raw_scopes = set()
|
self.raw_scopes = set()
|
||||||
app_log.debug("Loading and parsing scopes")
|
app_log.debug("Loading and parsing scopes")
|
||||||
if self.current_user:
|
if self.current_user:
|
||||||
|
@@ -108,7 +108,7 @@ class Scope(Enum):
|
|||||||
ALL = True
|
ALL = True
|
||||||
|
|
||||||
|
|
||||||
def _intersect_scopes(scopes_a, scopes_b):
|
def _intersect_expanded_scopes(scopes_a, scopes_b):
|
||||||
"""Intersect two sets of expanded scopes by comparing their permissions
|
"""Intersect two sets of expanded scopes by comparing their permissions
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@@ -192,7 +192,7 @@ def _intersect_scopes(scopes_a, scopes_b):
|
|||||||
|
|
||||||
|
|
||||||
def get_scopes_for(orm_object):
|
def get_scopes_for(orm_object):
|
||||||
"""Find scopes for a given user or token and resolve permissions
|
"""Find scopes for a given user or token from their roles and resolve permissions
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
orm_object: orm object or User wrapper
|
orm_object: orm object or User wrapper
|
||||||
@@ -225,7 +225,7 @@ def get_scopes_for(orm_object):
|
|||||||
token_scopes.remove('all')
|
token_scopes.remove('all')
|
||||||
token_scopes |= owner_scopes
|
token_scopes |= owner_scopes
|
||||||
|
|
||||||
intersection = _intersect_scopes(token_scopes, owner_scopes)
|
intersection = _intersect_expanded_scopes(token_scopes, owner_scopes)
|
||||||
discarded_token_scopes = token_scopes - intersection
|
discarded_token_scopes = token_scopes - intersection
|
||||||
|
|
||||||
# Not taking symmetric difference here because token owner can naturally have more scopes than token
|
# Not taking symmetric difference here because token owner can naturally have more scopes than token
|
||||||
@@ -263,7 +263,7 @@ def _check_user_in_expanded_scope(handler, user_name, scope_group_names):
|
|||||||
return bool(set(scope_group_names) & group_names)
|
return bool(set(scope_group_names) & group_names)
|
||||||
|
|
||||||
|
|
||||||
def _check_scope(api_handler, req_scope, **kwargs):
|
def _check_scope_access(api_handler, req_scope, **kwargs):
|
||||||
"""Check if scopes satisfy requirements
|
"""Check if scopes satisfy requirements
|
||||||
Returns True for (potentially restricted) access, False for refused access
|
Returns True for (potentially restricted) access, False for refused access
|
||||||
"""
|
"""
|
||||||
@@ -375,7 +375,7 @@ def needs_scope(*scopes):
|
|||||||
s_kwargs[resource] = resource_value
|
s_kwargs[resource] = resource_value
|
||||||
for scope in scopes:
|
for scope in scopes:
|
||||||
app_log.debug("Checking access via scope %s", scope)
|
app_log.debug("Checking access via scope %s", scope)
|
||||||
has_access = _check_scope(self, scope, **s_kwargs)
|
has_access = _check_scope_access(self, scope, **s_kwargs)
|
||||||
if has_access:
|
if has_access:
|
||||||
return func(self, *args, **kwargs)
|
return func(self, *args, **kwargs)
|
||||||
try:
|
try:
|
||||||
|
@@ -9,8 +9,8 @@ from tornado.httputil import HTTPServerRequest
|
|||||||
from .. import orm
|
from .. import orm
|
||||||
from .. import roles
|
from .. import roles
|
||||||
from ..handlers import BaseHandler
|
from ..handlers import BaseHandler
|
||||||
from ..scopes import _check_scope
|
from ..scopes import _check_scope_access
|
||||||
from ..scopes import _intersect_scopes
|
from ..scopes import _intersect_expanded_scopes
|
||||||
from ..scopes import get_scopes_for
|
from ..scopes import get_scopes_for
|
||||||
from ..scopes import needs_scope
|
from ..scopes import needs_scope
|
||||||
from ..scopes import parse_scopes
|
from ..scopes import parse_scopes
|
||||||
@@ -49,37 +49,39 @@ def test_scope_precendence():
|
|||||||
|
|
||||||
def test_scope_check_present():
|
def test_scope_check_present():
|
||||||
handler = get_handler_with_scopes(['read:users'])
|
handler = get_handler_with_scopes(['read:users'])
|
||||||
assert _check_scope(handler, 'read:users')
|
assert _check_scope_access(handler, 'read:users')
|
||||||
assert _check_scope(handler, 'read:users', user='maeby')
|
assert _check_scope_access(handler, 'read:users', user='maeby')
|
||||||
|
|
||||||
|
|
||||||
def test_scope_check_not_present():
|
def test_scope_check_not_present():
|
||||||
handler = get_handler_with_scopes(['read:users!user=maeby'])
|
handler = get_handler_with_scopes(['read:users!user=maeby'])
|
||||||
assert _check_scope(handler, 'read:users')
|
assert _check_scope_access(handler, 'read:users')
|
||||||
with pytest.raises(web.HTTPError):
|
with pytest.raises(web.HTTPError):
|
||||||
_check_scope(handler, 'read:users', user='gob')
|
_check_scope_access(handler, 'read:users', user='gob')
|
||||||
with pytest.raises(web.HTTPError):
|
with pytest.raises(web.HTTPError):
|
||||||
_check_scope(handler, 'read:users', user='gob', server='server')
|
_check_scope_access(handler, 'read:users', user='gob', server='server')
|
||||||
|
|
||||||
|
|
||||||
def test_scope_filters():
|
def test_scope_filters():
|
||||||
handler = get_handler_with_scopes(
|
handler = get_handler_with_scopes(
|
||||||
['read:users', 'read:users!group=bluths', 'read:users!user=maeby']
|
['read:users', 'read:users!group=bluths', 'read:users!user=maeby']
|
||||||
)
|
)
|
||||||
assert _check_scope(handler, 'read:users', group='bluth')
|
assert _check_scope_access(handler, 'read:users', group='bluth')
|
||||||
assert _check_scope(handler, 'read:users', user='maeby')
|
assert _check_scope_access(handler, 'read:users', user='maeby')
|
||||||
|
|
||||||
|
|
||||||
def test_scope_multiple_filters():
|
def test_scope_multiple_filters():
|
||||||
handler = get_handler_with_scopes(['read:users!user=george_michael'])
|
handler = get_handler_with_scopes(['read:users!user=george_michael'])
|
||||||
assert _check_scope(handler, 'read:users', user='george_michael', group='bluths')
|
assert _check_scope_access(
|
||||||
|
handler, 'read:users', user='george_michael', group='bluths'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_scope_parse_server_name():
|
def test_scope_parse_server_name():
|
||||||
handler = get_handler_with_scopes(
|
handler = get_handler_with_scopes(
|
||||||
['users:servers!server=maeby/server1', 'read:users!user=maeby']
|
['users:servers!server=maeby/server1', 'read:users!user=maeby']
|
||||||
)
|
)
|
||||||
assert _check_scope(handler, 'users:servers', user='maeby', server='server1')
|
assert _check_scope_access(handler, 'users:servers', user='maeby', server='server1')
|
||||||
|
|
||||||
|
|
||||||
class MockAPIHandler:
|
class MockAPIHandler:
|
||||||
@@ -828,10 +830,10 @@ async def test_resolve_token_permissions(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_intersect_scopes(left, right, expected, should_warn, recwarn):
|
def test_intersect_expanded_scopes(left, right, expected, should_warn, recwarn):
|
||||||
# run every test in both directions, to ensure symmetry of the inputs
|
# run every test in both directions, to ensure symmetry of the inputs
|
||||||
for a, b in [(left, right), (right, left)]:
|
for a, b in [(left, right), (right, left)]:
|
||||||
intersection = _intersect_scopes(set(left), set(right))
|
intersection = _intersect_expanded_scopes(set(left), set(right))
|
||||||
assert intersection == set(expected)
|
assert intersection == set(expected)
|
||||||
|
|
||||||
if should_warn:
|
if should_warn:
|
||||||
|
Reference in New Issue
Block a user