Coverage for benefits/oauth/client.py: 100%
24 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-19 00:56 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-19 00:56 +0000
1"""
2The oauth application: helpers for working with OAuth clients.
3"""
5import logging
7from authlib.integrations.django_client import OAuth
9from benefits.core import models
11logger = logging.getLogger(__name__)
13oauth = OAuth()
16def _client_kwargs(scope=None):
17 """
18 Generate the OpenID Connect client_kwargs, with optional extra scope(s).
20 `scope` should be a space-separated list of scopes to add.
21 """
22 scopes = ["openid", scope] if scope else ["openid"]
23 return {"code_challenge_method": "S256", "scope": " ".join(scopes), "prompt": "login"}
26def _server_metadata_url(authority):
27 """
28 Generate the OpenID Connect server_metadata_url for an OAuth authority server.
30 `authority` should be a fully qualified HTTPS domain name, e.g. https://example.com.
31 """
32 return f"{authority}/.well-known/openid-configuration"
35def _authorize_params(scheme):
36 if scheme is not None:
37 params = {"scheme": scheme}
38 else:
39 params = None
41 return params
44def _register_provider(oauth_registry: OAuth, flow: models.EnrollmentFlow):
45 """
46 Register OAuth clients into the given registry, using configuration from ClaimsProvider and EnrollmentFlow models.
48 Adapted from https://stackoverflow.com/a/64174413.
49 """
50 logger.debug(f"Registering OAuth client: {flow.claims_provider.client_name}")
52 client = oauth_registry.register(
53 flow.claims_provider.client_name,
54 client_id=flow.claims_provider.client_id,
55 server_metadata_url=_server_metadata_url(flow.claims_provider.authority),
56 client_kwargs=_client_kwargs(flow.claims_scope),
57 authorize_params=_authorize_params(flow.claims_scheme),
58 )
60 return client
63def create_client(oauth_registry: OAuth, flow: models.EnrollmentFlow):
64 """
65 Returns an OAuth client, registering it if needed.
66 """
67 client = oauth_registry.create_client(flow.claims_provider.client_name)
69 if client is None:
70 client = _register_provider(oauth_registry, flow)
72 return client