-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[uss_qualifier] new resource for cleanly exposing the client identity
- Loading branch information
Showing
19 changed files
with
186 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
from .auth_adapter import AuthAdapterResource | ||
from .client_identity import ClientIdentityResource |
71 changes: 71 additions & 0 deletions
71
monitoring/uss_qualifier/resources/communications/client_identity.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from implicitdict import ImplicitDict | ||
|
||
from monitoring.monitorlib.infrastructure import AuthAdapter | ||
from monitoring.uss_qualifier.resources.communications import AuthAdapterResource | ||
from monitoring.uss_qualifier.resources.resource import Resource | ||
|
||
|
||
class ClientIdentitySpecification(ImplicitDict): | ||
""" | ||
Specification for a Client Identity resource: | ||
defines the audience and scope to use when a token is requested with the sole goal of | ||
discovering the identity under which the client is known to the DSS, and no other audience or scope | ||
are otherwise available in the context. | ||
This is mostly useful for determining the client identity upon setup of the qualifier, when no | ||
requests have yet been made to the DSS. | ||
""" | ||
|
||
whoami_audience: str | ||
"""Audience to request for the access token used to determine subscriber identity.""" | ||
|
||
whoami_scope: str | ||
"""Scope to request for the access token used to determine subscribe identity. Must be a scope that the client is | ||
authorized to obtain.""" | ||
|
||
|
||
class ClientIdentityResource(Resource[ClientIdentitySpecification]): | ||
|
||
specification: ClientIdentitySpecification | ||
|
||
_adapter: AuthAdapter | ||
|
||
def __init__( | ||
self, | ||
specification: ClientIdentitySpecification, | ||
auth_adapter: AuthAdapterResource, | ||
): | ||
self.specification = specification | ||
# Keep the adapter: we will only use it later at the moment it is required | ||
self._adapter = auth_adapter.adapter | ||
|
||
def subscriber(self) -> str: | ||
""" | ||
Return the subscriber identity as determined by the adapter: | ||
this will usually only trigger a token request if no token had been requested yet by the auth adapter. | ||
This is a function and not a field, to possibly profit from a token that would have been requested earlier | ||
""" | ||
|
||
sub = self._adapter.get_sub() | ||
if sub is None: | ||
# sub might be none because no authentication has happened yet: | ||
# we force one using the client identify audience and scopes | ||
|
||
# Do an initial token request so that adapter.get_sub() will return something | ||
token = self._adapter.issue_token( | ||
intended_audience=self.specification.whoami_audience, | ||
scopes=[self.specification.whoami_scope], | ||
) | ||
|
||
sub = self._adapter.get_sub() | ||
# Confirm we have a `sub` field available: if we don't, we bail | ||
if sub is None: | ||
raise ValueError( | ||
f"subscriber is None, meaning `sub` claim was not found in payload of token, " | ||
f"using {type(self._adapter).__name__} requesting {self.specification.whoami_scope} scope " | ||
f"for {self.specification.whoami_audience} audience: {token}" | ||
) | ||
|
||
return sub |
44 changes: 16 additions & 28 deletions
44
monitoring/uss_qualifier/resources/interuss/id_generator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,32 @@ | ||
from implicitdict import ImplicitDict | ||
import jwt | ||
|
||
from monitoring.prober.infrastructure import IDFactory | ||
from monitoring.uss_qualifier.resources.communications import AuthAdapterResource | ||
from monitoring.uss_qualifier.resources.communications import ClientIdentityResource | ||
from monitoring.uss_qualifier.resources.resource import Resource | ||
|
||
|
||
class IDGeneratorSpecification(ImplicitDict): | ||
"""Generated IDs contain the client's identity so the appropriate client can clean up any dangling resources. | ||
"""No fields required for the ID generator""" | ||
|
||
Note that this may not be necessary/important with the resolution of https://github.com/interuss/dss/issues/939 | ||
|
||
To determine the client's identity, an access token is retrieved and the subscriber is read from the obtained token. | ||
Therefore, the client running uss_qualifier must have the ability to obtain an access token via an auth adapter. | ||
""" | ||
|
||
whoami_audience: str | ||
"""Audience to request for the access token used to determine subscriber identity.""" | ||
|
||
whoami_scope: str | ||
"""Scope to request for the access token used to determine subscribe identity. Must be a scope that the client is | ||
authorized to obtain.""" | ||
class IDGeneratorResource(Resource[IDGeneratorSpecification]): | ||
|
||
_client_identity: ClientIdentityResource | ||
|
||
class IDGeneratorResource(Resource[IDGeneratorSpecification]): | ||
id_factory: IDFactory | ||
subscriber: str | ||
# Not initialised before it's actually used | ||
_id_factory: IDFactory = None | ||
|
||
def __init__( | ||
self, | ||
specification: IDGeneratorSpecification, | ||
auth_adapter: AuthAdapterResource, | ||
client_identity: ClientIdentityResource, | ||
): | ||
token = auth_adapter.adapter.issue_token( | ||
specification.whoami_audience, [specification.whoami_scope] | ||
) | ||
payload = jwt.decode(token, options={"verify_signature": False}) | ||
if "sub" not in payload: | ||
raise ValueError( | ||
f"`sub` claim not found in payload of token using {type(auth_adapter).__name__} requesting {specification.whoami_scope} scope for {specification.whoami_audience} audience: {token}" | ||
) | ||
self.subscriber = payload["sub"] | ||
self.id_factory = IDFactory(self.subscriber) | ||
self._client_identity = client_identity | ||
|
||
@property | ||
def id_factory(self) -> IDFactory: | ||
# Not thread safe, but the consequences here are acceptable | ||
if self._id_factory is None: | ||
self._id_factory = IDFactory(self._client_identity.subscriber()) | ||
|
||
return self._id_factory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.