Skip to content

Commit b432b8a

Browse files
committed
Make usage of upstream_get more consistent.
1 parent dddbc05 commit b432b8a

File tree

17 files changed

+144
-88
lines changed

17 files changed

+144
-88
lines changed

src/idpyoidc/client/client_auth.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,7 @@ def _get_audience_and_algorithm(self, context, keyjar, **kwargs):
520520

521521
def _construct_client_assertion(self, service, **kwargs):
522522
_context = service.upstream_get("context")
523-
_entity = service.upstream_get("entity")
524-
if _entity is None:
525-
_entity = service.upstream_get("unit")
523+
_entity = service.upstream_get("unit")
526524

527525
_keyjar = service.upstream_get("attribute", "keyjar")
528526
audience, algorithm = self._get_audience_and_algorithm(_context, _keyjar, **kwargs)

src/idpyoidc/client/entity.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ def __init__(
145145
)
146146

147147
self.setup_client_authn_methods(config)
148-
149148
self.upstream_get = upstream_get
150149

151150
def get_services(self, *arg):
@@ -170,8 +169,8 @@ def get_service_by_endpoint_name(self, endpoint_name, *arg):
170169

171170
return None
172171

173-
def get_entity(self):
174-
return self
172+
# def get_entity(self):
173+
# return self
175174

176175
def get_client_id(self):
177176
_val = self.context.claims.get_usage("client_id")

src/idpyoidc/client/oauth2/add_on/dpop.py

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
from typing import Optional
55

66
from cryptojwt.jwk.jwk import key_from_jwk_dict
7-
from cryptojwt.jws.jws import JWS
87
from cryptojwt.jws.jws import factory
8+
from cryptojwt.jws.jws import JWS
99
from cryptojwt.key_bundle import key_by_alg
1010

11+
from idpyoidc.client.client_auth import BearerHeader
12+
from idpyoidc.client.client_auth import find_token_info
1113
from idpyoidc.client.service_context import ServiceContext
14+
from idpyoidc.message import Message
1215
from idpyoidc.message import SINGLE_OPTIONAL_STRING
1316
from idpyoidc.message import SINGLE_REQUIRED_INT
1417
from idpyoidc.message import SINGLE_REQUIRED_JSON
1518
from idpyoidc.message import SINGLE_REQUIRED_STRING
16-
from idpyoidc.message import Message
1719
from idpyoidc.metadata import get_signing_algs
1820
from idpyoidc.time_util import utc_time_sans_frac
1921

@@ -91,13 +93,13 @@ def verify_header(self, dpop_header) -> Optional["DPoPProof"]:
9193

9294

9395
def dpop_header(
94-
service_context: ServiceContext,
95-
service_endpoint: str,
96-
http_method: str,
97-
headers: Optional[dict] = None,
98-
token: Optional[str] = "",
99-
nonce: Optional[str] = "",
100-
**kwargs
96+
service_context: ServiceContext,
97+
service_endpoint: str,
98+
http_method: str,
99+
headers: Optional[dict] = None,
100+
token: Optional[str] = "",
101+
nonce: Optional[str] = "",
102+
**kwargs
101103
) -> dict:
102104
"""
103105
@@ -159,7 +161,7 @@ def dpop_header(
159161
return headers
160162

161163

162-
def add_support(services, dpop_signing_alg_values_supported):
164+
def add_support(services, dpop_signing_alg_values_supported, with_dpop_header=None):
163165
"""
164166
Add the necessary pieces to make pushed authorization happen.
165167
@@ -185,3 +187,53 @@ def add_support(services, dpop_signing_alg_values_supported):
185187
_userinfo_service = services.get("userinfo")
186188
if _userinfo_service:
187189
_userinfo_service.construct_extra_headers.append(dpop_header)
190+
# To be backward compatible
191+
if with_dpop_header is None:
192+
with_dpop_header = ["userinfo"]
193+
194+
# Add dpop HTTP header to these
195+
for _srv in with_dpop_header:
196+
if _srv == "accesstoken":
197+
continue
198+
_service = services.get(_srv)
199+
if _service:
200+
_service.construct_extra_headers.append(dpop_header)
201+
202+
203+
class DPoPClientAuth(BearerHeader):
204+
tag = "dpop_client_auth"
205+
206+
def construct(self, request=None, service=None, http_args=None, **kwargs):
207+
"""
208+
Constructing the Authorization header. The value of
209+
the Authorization header is "Bearer <access_token>".
210+
211+
:param request: Request class instance
212+
:param service: The service this authentication method applies to.
213+
:param http_args: HTTP header arguments
214+
:param kwargs: extra keyword arguments
215+
:return:
216+
"""
217+
218+
_token_type = "access_token"
219+
220+
_token_info = find_token_info(request, _token_type, service, **kwargs)
221+
222+
if not _token_info:
223+
raise KeyError("No bearer token available")
224+
225+
# The authorization value starts with the token_type
226+
# if _token_info["token_type"].to_lower() != "bearer":
227+
_bearer = f"DPoP {_token_info[_token_type]}"
228+
229+
# Add 'Authorization' to the headers
230+
if http_args is None:
231+
http_args = {"headers": {}}
232+
http_args["headers"]["Authorization"] = _bearer
233+
else:
234+
try:
235+
http_args["headers"]["Authorization"] = _bearer
236+
except KeyError:
237+
http_args["headers"] = {"Authorization": _bearer}
238+
239+
return http_args

src/idpyoidc/client/oauth2/server_metadata.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def get_endpoint(self):
3838
:return: Service endpoint
3939
"""
4040
try:
41-
_iss = self.upstream_get("context").issuer
41+
_iss = self.upstream_get("attribute","issuer")
4242
except AttributeError:
4343
_iss = self.endpoint
4444

@@ -72,13 +72,16 @@ def _verify_issuer(self, resp, issuer):
7272

7373
# In some cases we can live with the two URLs not being
7474
# the same. But this is an excepted that has to be explicit
75-
try:
76-
self.upstream_get("context").allow["issuer_mismatch"]
77-
except KeyError:
78-
if _issuer != _pcr_issuer:
79-
raise OidcServiceError(
80-
"provider info issuer mismatch '%s' != '%s'" % (_issuer, _pcr_issuer)
81-
)
75+
_allow = self.upstream_get("attribute", "allow")
76+
if _allow:
77+
_allowed = _allow.get("issuer_mismatch", None)
78+
if _allowed:
79+
return _issuer
80+
81+
if _issuer != _pcr_issuer:
82+
raise OidcServiceError(
83+
"provider info issuer mismatch '%s' != '%s'" % (_issuer, _pcr_issuer)
84+
)
8285
return _issuer
8386

8487
def _set_endpoints(self, resp):
@@ -131,9 +134,10 @@ def _update_service_context(self, resp):
131134
# is loaded not necessarily that any keys are fetched.
132135
if "jwks_uri" in resp:
133136
LOGGER.debug(f"'jwks_uri' in provider info: {resp['jwks_uri']}")
134-
_hp = self.upstream_get('entity').httpc_params
135-
if "verify" in _hp and "verify" not in _keyjar.httpc_params:
136-
_keyjar.httpc_params["verify"] = _hp["verify"]
137+
_hp = self.upstream_get("attribute","httpc_params")
138+
if _hp:
139+
if "verify" in _hp and "verify" not in _keyjar.httpc_params:
140+
_keyjar.httpc_params["verify"] = _hp["verify"]
137141
_keyjar.load_keys(_pcr_issuer, jwks_uri=resp["jwks_uri"])
138142
_loaded = True
139143
elif "jwks" in resp:

src/idpyoidc/client/oidc/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ def __init__(
9494
jwks_uri: Optional[str] = "",
9595
**kwargs
9696
):
97-
self.upstream_get = upstream_get
9897
if services:
9998
_srvs = services
10099
else:

src/idpyoidc/client/oidc/access_token.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def gather_verify_arguments(
4242
:return: dictionary with arguments to the verify call
4343
"""
4444
_context = self.upstream_get("context")
45-
_entity = self.upstream_get("entity")
45+
_entity = self.upstream_get("unit")
4646

4747
kwargs = {
4848
"client_id": _entity.get_client_id(),

src/idpyoidc/client/oidc/authorization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def update_service_context(self, resp, key="", **kwargs):
9090
_context.cstate.update(key, resp)
9191

9292
def get_request_from_response(self, response):
93-
_context = self.upstream_get("service_context")
93+
_context = self.upstream_get("context")
9494
return _context.cstate.get_set(response["state"], message=oauth2.AuthorizationRequest)
9595

9696
def post_parse_response(self, response, **kwargs):

src/idpyoidc/client/oidc/provider_info_discovery.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def add_redirect_uris(request_args, service=None, **kwargs):
2525
:param kwargs: Possible extra keyword arguments
2626
:return: A possibly augmented set of request arguments.
2727
"""
28-
_work_environment = service.upstream_get("context").claims
28+
_work_environment = service.upstream_get("attribute", "claims")
2929
if "redirect_uris" not in request_args:
3030
# Callbacks is a dictionary with callback type 'code', 'implicit',
3131
# 'form_post' as keys.

src/idpyoidc/node.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ def get_unit(self, *args):
181181
def topmost_unit(unit):
182182
if hasattr(unit, "upstream_get"):
183183
if unit.upstream_get:
184-
next_unit = unit.upstream_get("unit")
185-
if next_unit:
186-
unit = topmost_unit(next_unit)
184+
superior = unit.upstream_get("unit")
185+
if superior:
186+
unit = topmost_unit(superior)
187187

188188
return unit
189189

src/idpyoidc/server/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ def __init__(
6767
issuer_id=self.issuer,
6868
)
6969

70-
self.upstream_get = upstream_get
7170
if isinstance(conf, OPConfiguration) or isinstance(conf, ASConfiguration):
7271
self.conf = conf
7372
else:

0 commit comments

Comments
 (0)