add !service and !server scope filters

allows oauth clients to issue scopes that only grant access to the issuing service

e.g. access:service!service or access:servers!server

especially useful with custom scopes
This commit is contained in:
Min RK
2022-03-22 08:47:39 +01:00
parent b05a89a3e0
commit b6210dc225
6 changed files with 144 additions and 32 deletions

View File

@@ -682,7 +682,8 @@ class APIToken(Hashed, Base):
generated=True,
session_id=None,
expires_in=None,
client_id='jupyterhub',
client_id=None,
oauth_client=None,
return_orm=False,
):
"""Generate a new API token for a user or service"""
@@ -726,11 +727,20 @@ class APIToken(Hashed, Base):
orm_roles.append(role)
scopes = roles_to_scopes(orm_roles)
if oauth_client is None:
# lookup oauth client by identifier
if client_id is None:
# default: global 'jupyterhub' client
client_id = "jupyterhub"
oauth_client = db.query(OAuthClient).filter_by(identifier=client_id).one()
if client_id is None:
client_id = oauth_client.identifier
# avoid circular import
from .scopes import _check_scopes_exist, _check_token_scopes
_check_scopes_exist(scopes, who_for="token")
_check_token_scopes(scopes, owner=user or service)
_check_token_scopes(scopes, owner=user or service, oauth_client=oauth_client)
# two stages to ensure orm_token.generated has been set
# before token setter is called
@@ -760,7 +770,9 @@ class APIToken(Hashed, Base):
from .scopes import _check_scopes_exist, _check_token_scopes
_check_scopes_exist(new_scopes, who_for="token")
_check_token_scopes(new_scopes, owner=self.owner)
_check_token_scopes(
new_scopes, owner=self.owner, oauth_client=self.oauth_client
)
self.scopes = new_scopes