Skip to content

Commit 6baf9a4

Browse files
committed
Moved metadata, usage and behaviour information into a class of its own.
1 parent 9ce30b0 commit 6baf9a4

32 files changed

+508
-331
lines changed

doc/client/config.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ RP/Client Configuration
55
-----------------------
66

77
As you may have guessed by now a lot of the work you have to do to use this
8-
packages lies in the RP configuration.
8+
packages lies in the RP/Client configuration.
9+
I'll use just RP in the rest of the document but everywhere you see RP you
10+
can also think Client (in the OAuth2 sense).
911

10-
The configuration parameters fall into 2 groups, one general that is the
11-
same for all RP/clients and one which is specific for a specific
12-
OP/AS
12+
The configuration parameters fall into 2 groups, one with basic information
13+
that are independent of which OpenID Provider (OP) that RP
1314

1415
General configuration parameters
1516
--------------------------------

src/idpyoidc/actor/client/oidc/registration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def add_client_behaviour_preference(self, request_args=None, **kwargs):
166166
continue
167167

168168
try:
169-
request_args[prop] = _context.behaviour[prop]
169+
request_args[prop] = _context.specs.behaviour[prop]
170170
except KeyError:
171171
try:
172172
request_args[prop] = _context.client_preferences[prop]

src/idpyoidc/client/client_auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def _get_user(service, **kwargs):
105105
try:
106106
user = kwargs["user"]
107107
except KeyError:
108-
user = service.client_get("service_context").get_metadata("client_id")
108+
user = service.client_get("service_context").get_client_id()
109109
return user
110110

111111
def _get_authentication_token(self, request, service, **kwargs):
@@ -140,7 +140,7 @@ def _with_or_without_client_id(request, service):
140140
):
141141
if "client_id" not in request:
142142
try:
143-
request["client_id"] = service.client_get("service_context").get_metadata("client_id")
143+
request["client_id"] = service.client_get("service_context").get_client_id()
144144
except AttributeError:
145145
pass
146146
else:
@@ -228,7 +228,7 @@ def modify_request(self, request, service, **kwargs):
228228
raise AuthnFailure("Missing client secret")
229229

230230
# Set the client_id in the the request
231-
request["client_id"] = _context.get_metadata("client_id")
231+
request["client_id"] = _context.get_client_id()
232232

233233
def construct(self, request, service=None, http_args=None, **kwargs):
234234
"""

src/idpyoidc/client/entity.py

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def __init__(
8383
services: Optional[dict] = None,
8484
jwks_uri: Optional[str] = "",
8585
httpc_params: Optional[dict] = None,
86+
client_type: Optional[str] = ""
8687
):
8788
self.extra = {}
8889
if httpc_params:
@@ -98,7 +99,8 @@ def __init__(
9899
_kj = None
99100

100101
self._service_context = ServiceContext(
101-
keyjar=keyjar, config=config, jwks_uri=jwks_uri, httpc_params=self.httpc_params
102+
keyjar=keyjar, config=config, jwks_uri=jwks_uri, httpc_params=self.httpc_params,
103+
client_type=client_type
102104
)
103105

104106
if config:
@@ -113,13 +115,6 @@ def __init__(
113115
metadata=config.conf.get("metadata", {}),
114116
usage=config.conf.get("usage", {}))
115117

116-
# MUST not overwrite service specific usage and metadata
117-
for key, val in config.conf.get("usage", {}).items():
118-
self.set_usage_value(key, val)
119-
120-
for key, val in config.conf.get("metadata", {}).items():
121-
self.set_metadata_value(key, val)
122-
123118
self.setup_client_authn_methods(config)
124119

125120
jwks_uri = jwks_uri or self.get_metadata_value("jwks_uri")
@@ -161,7 +156,7 @@ def get_entity(self):
161156
return self
162157

163158
def get_client_id(self):
164-
return self._service_context.get_metadata("client_id")
159+
return self._service_context.get_client_id()
165160

166161
def setup_client_authn_methods(self, config):
167162
self._service_context.client_authn_method = client_auth_setup(
@@ -172,32 +167,32 @@ def collect_metadata(self):
172167
res = {}
173168
for service in self._service.values():
174169
res.update(service.metadata)
175-
res.update(self._service_context.metadata)
170+
res.update(self._service_context.specs.get_all())
176171
return res
177172

178173
def collect_usage(self):
179174
res = {}
180175
for service in self._service.values():
181176
res.update(service.usage)
182-
res.update(self._service_context.usage)
177+
res.update(self._service_context.specs.usage)
183178
return res
184179

185180
def get_metadata_value(self, attribute, default=None):
186181
for service in self._service.values():
187182
if attribute in service.metadata_attributes:
188183
return service.get_metadata(attribute, default)
189184

190-
if attribute in self._service_context.metadata_attributes:
191-
return self._service_context.get_metadata(attribute, default)
185+
if attribute in self._service_context.specs.attributes:
186+
return self._service_context.specs.get_metadata(attribute, default)
192187

193-
raise KeyError(f"Unknown metadata attribute: {attribute}")
188+
raise KeyError(f"Unknown specs attribute: {attribute}")
194189

195190
def get_metadata_attributes(self):
196191
attr = []
197192
for service in self._service.values():
198193
attr.extend(list(service.metadata_attributes.keys()))
199194

200-
attr.extend(list(self._service_context.metadata_attributes.keys()))
195+
attr.extend(list(self._service_context.specs.attributes.keys()))
201196

202197
return attr
203198

@@ -212,8 +207,8 @@ def value_in_metadata_attribute(self, attribute, value):
212207
if value == _val:
213208
return True
214209

215-
if attribute in self._service_context.metadata_attributes.keys():
216-
_val = self._service_context.get_metadata(attribute)
210+
if attribute in self._service_context.specs.attributes.keys():
211+
_val = self._service_context.specs.get_metadata(attribute)
217212
if isinstance(_val, list):
218213
if value in _val:
219214
return True
@@ -229,8 +224,8 @@ def will_use(self, attribute):
229224
if service.usage.get(attribute):
230225
return True
231226

232-
if attribute in self._service_context.usage_rules.keys():
233-
if self._service_context.usage.get(attribute):
227+
if attribute in self._service_context.specs.rules.keys():
228+
if self._service_context.specs.get_usage(attribute):
234229
return True
235230
return False
236231

@@ -249,18 +244,18 @@ def set_metadata_value(self, attribute, value):
249244
service.metadata[attribute] = value
250245
return True
251246

252-
if attribute in self._service_context.metadata_attributes:
253-
_def_val = self._service_context.metadata_attributes[attribute]
247+
if attribute in self._service_context.specs.attributes:
248+
_def_val = self._service_context.specs.attributes[attribute]
254249
if _def_val is None:
255-
self._service_context.metadata[attribute] = value
250+
self._service_context.specs.set_metadata(attribute, value)
256251
return True
257252
else:
258-
if self._service_context.metadata[attribute] == _def_val:
259-
self._service_context.metadata[attribute] = value
253+
if self._service_context.specs.get_metadata(attribute, _def_val):
254+
self._service_context.specs.set_metadata(attribute, value)
260255
return True
261256
return True
262257

263-
logger.info(f"Unknown set metadata attribute: {attribute}")
258+
logger.info(f"Unknown set specs attribute: {attribute}")
264259
return False
265260

266261
def set_usage_value(self, attribute, value):
@@ -278,14 +273,14 @@ def set_usage_value(self, attribute, value):
278273
service.usage[attribute] = value
279274
return True
280275

281-
if attribute in self._service_context.usage_rules:
282-
_def_val = self._service_context.usage_rules[attribute]
276+
if attribute in self._service_context.specs.rules:
277+
_def_val = self._service_context.specs.rules[attribute]
283278
if _def_val is None:
284-
self._service_context.usage[attribute] = value
279+
self._service_context.specs.set_usage(attribute, value)
285280
return True
286281
else:
287-
if self._service_context.usage[attribute] == _def_val:
288-
self._service_context.usage[attribute] = value
282+
if self._service_context.specs.usage[attribute] == _def_val:
283+
self._service_context.specs.set_usage(attribute, value)
289284
return True
290285

291286
logger.info(f"Unknown set usage attribute: {attribute}")
@@ -299,9 +294,10 @@ def get_usage_value(self, attribute, default=None):
299294
else:
300295
return default
301296

302-
if attribute in self._service_context.usage_rules:
303-
if attribute in self._service_context.usage:
304-
return self._service_context.usage[attribute]
297+
if attribute in self._service_context.specs.rules:
298+
_val = self._service_context.specs.get_usage(attribute)
299+
if _val:
300+
return _val
305301
else:
306302
return default
307303

@@ -319,10 +315,10 @@ def construct_uris(self, issuer, hash_seed, callback):
319315
for service in self._service.values():
320316
service.construct_uris(_base_url, _hex)
321317

322-
if not self._service_context.get_metadata("redirect_uris"):
323-
self._service_context.construct_redirect_uris(_base_url, _hex, callback)
318+
if not self._service_context.specs.get_metadata("redirect_uris"):
319+
self._service_context.specs.construct_redirect_uris(_base_url, _hex, callback)
324320

325-
self._service_context.construct_uris(_base_url, _hex)
321+
self._service_context.specs.construct_uris(_base_url, _hex)
326322

327323
def backward_compatibility(self, config):
328324
_uris = config.get("redirect_uris")
@@ -357,14 +353,14 @@ def config_args(self):
357353
"usage": service.usage_rules
358354
}
359355
res[""] = {
360-
"metadata": self._service_context.metadata_attributes,
361-
"usage": self._service_context.usage_rules
356+
"metadata": self._service_context.specs.attributes,
357+
"usage": self._service_context.specs.rules
362358
}
363359
return res
364360

365361
def get_callback_uris(self):
366362
res = []
367363
for service in self._service.values():
368364
res.extend(service.callback_uris)
369-
res.extend(self._service_context.callback_uris)
365+
res.extend(self._service_context.specs.callback_uris)
370366
return res

src/idpyoidc/client/oauth2/utils.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ def pick_redirect_uri(
3636
if "redirect_uri" in request_args:
3737
return request_args["redirect_uri"]
3838

39-
if context.callback:
39+
if context.specs.callback:
4040
if not response_type:
41-
_conf_resp_types = context.behaviour.get("response_types", [])
41+
_conf_resp_types = context.specs.behaviour.get("response_types", [])
4242
response_type = request_args.get("response_type")
4343
if not response_type and _conf_resp_types:
4444
response_type = _conf_resp_types[0]
4545

4646
_response_mode = request_args.get("response_mode")
4747

4848
if _response_mode == "form_post" or response_type == ["form_post"]:
49-
redirect_uri = context.callback["form_post"]
49+
redirect_uri = context.specs.callback["form_post"]
5050
elif response_type == "code" or response_type == ["code"]:
51-
redirect_uri = context.callback["code"]
51+
redirect_uri = context.specs.callback["code"]
5252
else:
53-
redirect_uri = context.callback["implicit"]
53+
redirect_uri = context.specs.callback["implicit"]
5454

5555
logger.debug(
5656
f"pick_redirect_uris: response_type={response_type}, response_mode={_response_mode}, "
@@ -71,9 +71,7 @@ def pre_construct_pick_redirect_uri(
7171
request_args: Optional[Union[Message, dict]] = None, service: Optional[Service] = None,
7272
**kwargs
7373
):
74-
_context = service.client_get("service_context")
75-
_redirect_uris = service.client_get("entity").get_metadata_value("redirect_uris")
76-
request_args["redirect_uri"] = pick_redirect_uri(_context,
74+
request_args["redirect_uri"] = pick_redirect_uri(service.client_get("service_context"),
7775
entity=service.client_get("entity"),
7876
request_args=request_args)
7977
return request_args, {}

src/idpyoidc/client/oidc/access_token.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def gather_verify_arguments(
5555
except KeyError:
5656
pass
5757

58-
_verify_args = _context.behaviour.get("verify_args")
58+
_verify_args = _context.specs.behaviour.get("verify_args")
5959
if _verify_args:
6060
if _verify_args:
6161
kwargs.update(_verify_args)
@@ -83,7 +83,8 @@ def update_service_context(self, resp, key="", **kwargs):
8383
_state_interface.store_item(resp, "token_response", key)
8484

8585
def get_authn_method(self):
86+
_specs = self.client_get("service_context").specs
8687
try:
87-
return self.client_get("service_context").behaviour["token_endpoint_auth_method"]
88+
return _specs.behaviour["token_endpoint_auth_method"]
8889
except KeyError:
8990
return self.default_authn_method

src/idpyoidc/client/oidc/authorization.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def oidc_pre_construct(self, request_args=None, post_args=None, **kwargs):
9393
try:
9494
_response_types = [request_args["response_type"]]
9595
except KeyError:
96-
_response_types = _context.behaviour.get("response_types")
96+
_response_types = _context.specs.behaviour.get("response_types")
9797
if _response_types:
9898
request_args["response_type"] = _response_types[0]
9999
else:
@@ -151,8 +151,9 @@ def get_request_object_signing_alg(self, **kwargs):
151151
break
152152

153153
if not alg:
154+
_context = self.client_get("service_context")
154155
try:
155-
alg = self.client_get("service_context").behaviour["request_object_signing_alg"]
156+
alg = _context.specs.behaviour["request_object_signing_alg"]
156157
except KeyError: # Use default
157158
alg = "RS256"
158159
return alg
@@ -195,7 +196,7 @@ def construct_request_parameter(
195196
# This is the issuer of the JWT, that is me !
196197
_issuer = kwargs.get("issuer")
197198
if _issuer is None:
198-
kwargs["issuer"] = _srv_cntx.get_metadata("client_id")
199+
kwargs["issuer"] = _srv_cntx.get_client_id()
199200

200201
if kwargs.get("recv") is None:
201202
try:
@@ -254,15 +255,15 @@ def oidc_post_construct(self, req, **kwargs):
254255
if _request_param:
255256
del kwargs["request_param"]
256257
else:
257-
if _context.get_usage("request_uri"):
258+
if _context.specs.get_usage("request_uri"):
258259
_request_param = "request_uri"
259-
elif _context.get_usage("request_parameter"):
260+
elif _context.specs.get_usage("request_parameter"):
260261
_request_param = "request"
261262

262263
_req = None # just a flag
263264
if _request_param == "request_uri":
264265
kwargs["base_path"] = _context.get("base_url") + "/" + "requests"
265-
kwargs["local_dir"] = _context.config.conf.get("requests_dir", "./requests")
266+
kwargs["local_dir"] = _context.specs.get("requests_dir", "./requests")
266267
_req = self.construct_request_parameter(req, _request_param, **kwargs)
267268
req["request_uri"] = self.store_request_on_file(_req, **kwargs)
268269
elif _request_param == "request":
@@ -295,7 +296,7 @@ def gather_verify_arguments(
295296
"skew": _context.clock_skew,
296297
}
297298

298-
_client_id = _context.get_metadata("client_id")
299+
_client_id = _context.get_client_id()
299300
if _client_id:
300301
kwargs["client_id"] = _client_id
301302

@@ -312,7 +313,7 @@ def gather_verify_arguments(
312313
except KeyError:
313314
pass
314315

315-
_verify_args = _context.behaviour.get("verify_args")
316+
_verify_args = _context.specs.behaviour.get("verify_args")
316317
if _verify_args:
317318
kwargs.update(_verify_args)
318319

src/idpyoidc/client/oidc/provider_info_discovery.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def match_preferences(self, pcr=None, issuer=None):
9999

100100
regreq = oidc.RegistrationRequest
101101

102-
_behaviour = _context.behaviour
102+
_behaviour = _context.specs.behaviour
103103

104104
for _pref, _prov in PREFERENCE2PROVIDER.items():
105105
if _pref in ["scope"]:
@@ -168,5 +168,5 @@ def match_preferences(self, pcr=None, issuer=None):
168168
if key not in PREFERENCE2PROVIDER:
169169
_behaviour[key] = val
170170

171-
_context.behaviour = _behaviour
171+
_context.specs.behaviour = _behaviour
172172
logger.debug("service_context behaviour: {}".format(_behaviour))

src/idpyoidc/client/oidc/refresh_access_token.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class RefreshAccessToken(refresh_access_token.RefreshAccessToken):
88
error_msg = oidc.ResponseMessage
99

1010
def get_authn_method(self):
11+
_specs = self.client_get("service_context").specs
1112
try:
12-
return self.client_get("service_context").behaviour["token_endpoint_auth_method"]
13+
return _specs.behaviour["token_endpoint_auth_method"]
1314
except KeyError:
1415
return self.default_authn_method

0 commit comments

Comments
 (0)