Skip to content

Commit 2669489

Browse files
committed
Merge branch 'stand_alone_client' of https://github.com/IdentityPython/idpy-oidc into stand_alone_client
2 parents 63e1162 + 729507b commit 2669489

File tree

10 files changed

+359
-36
lines changed

10 files changed

+359
-36
lines changed

example/flask_rp/views.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,10 @@ def session_logout(op_identifier):
244244
@oidc_rp_views.route('/logout')
245245
def logout():
246246
logger.debug('logout')
247-
_info = current_app.rph.logout(state=session['state'])
248-
logger.debug('logout redirect to "{}"'.format(_info['url']))
249-
return redirect(_info['url'], 303)
247+
_request_info = current_app.rph.logout(state=session['state'])
248+
_url = _request_info["url"]
249+
logger.debug(f'logout redirect to "{_url}"')
250+
return redirect(_url, 303)
250251

251252

252253
@oidc_rp_views.route('/bc_logout/<op_identifier>', methods=['GET', 'POST'])

src/idpyoidc/client/current.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,14 @@ def get_set(
5656
) -> dict:
5757
"""
5858
59-
@param key: The key to a seet of current claims
59+
@param key: The key to a set of current claims
6060
@param message: A message class
6161
@param claim: A list of claims
6262
@return: Dictionary
63+
@raise KeyError if no such key
6364
"""
6465

65-
try:
66-
_current = self.get(key)
67-
except KeyError:
68-
return {}
66+
_current = self.get(key)
6967

7068
if message:
7169
_res = {k: _current[k] for k in message.c_param.keys() if k in _current}

src/idpyoidc/client/defaults.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@
9999
"token": "fragment",
100100
"code token": "fragment",
101101
"code id_token": "fragment",
102+
"id_token token": "fragment",
102103
"code id_token token": "fragment",
103104
}

src/idpyoidc/client/oauth2/stand_alone_client.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111
from idpyoidc.client.defaults import DEFAULT_RESPONSE_MODE
1212
from idpyoidc.client.exception import ConfigurationError
1313
from idpyoidc.client.exception import OidcServiceError
14+
from idpyoidc.client.exception import Unsupported
1415
from idpyoidc.client.oauth2 import Client
1516
from idpyoidc.client.oauth2 import dynamic_provider_info_discovery
1617
from idpyoidc.client.oauth2.utils import pick_redirect_uri
1718
from idpyoidc.exception import MessageException
1819
from idpyoidc.exception import MissingRequiredAttribute
1920
from idpyoidc.exception import NotForMe
2021
from idpyoidc.message import Message
21-
from idpyoidc.message.oauth2 import ResponseMessage
2222
from idpyoidc.message.oauth2 import is_error_message
23+
from idpyoidc.message.oauth2 import ResponseMessage
2324
from idpyoidc.message.oidc import AuthorizationRequest
2425
from idpyoidc.message.oidc import AuthorizationResponse
2526
from idpyoidc.message.oidc import Claims
@@ -193,12 +194,19 @@ def init_authorization(
193194
_context = self.get_context()
194195
_response_type = self._get_response_type(_context, req_args)
195196
_response_mode = self._get_response_mode(_context, _response_type, req_args)
196-
197-
request_args = {
198-
"redirect_uri": pick_redirect_uri(
197+
try:
198+
_redirect_uri = pick_redirect_uri(
199199
_context, request_args=req_args, response_type=_response_type,
200200
response_mode=_response_mode
201-
),
201+
)
202+
except KeyError:
203+
raise Unsupported(
204+
'Could not pick a redirect_uri based on the given response_type and response_mode')
205+
except [MissingRequiredAttribute, ValueError]:
206+
raise
207+
208+
request_args = {
209+
"redirect_uri": _redirect_uri,
202210
"response_type": _response_type,
203211
}
204212

@@ -247,21 +255,22 @@ def init_authorization(
247255
@staticmethod
248256
def get_client_authn_method(self, endpoint):
249257
"""
250-
Return the client authentication method a client wants to use a
258+
Return the client authentication method a client wants to use at a
251259
specific endpoint
252260
253261
:param endpoint: The endpoint at which the client has to authenticate
254262
:return: The client authentication method
255263
"""
256264
if endpoint == "token_endpoint":
257-
am = self.get_context().get_usage("token_endpoint_auth_method")
258-
if not am:
265+
auth_method = self.get_context().get_usage("token_endpoint_auth_method")
266+
if not auth_method:
259267
return ""
260268
else:
261-
if isinstance(am, str):
262-
return am
269+
if isinstance(auth_method, str):
270+
return auth_method
263271
else: # a list
264-
return am[0]
272+
return auth_method[0]
273+
return ""
265274

266275
def get_tokens(self, state):
267276
"""
@@ -431,7 +440,7 @@ def finalize_auth(
431440

432441
def get_access_and_id_token(
433442
self,
434-
authorization_response=None,
443+
authorization_response: Optional[Message] = None,
435444
state: Optional[str] = "",
436445
behaviour_args: Optional[dict] = None,
437446
):
@@ -663,10 +672,10 @@ def logout(
663672
else:
664673
request_args = {}
665674

666-
resp = srv.get_request_parameters(state=state, request_args=request_args)
675+
_info = srv.get_request_parameters(state=state, request_args=request_args)
667676

668-
logger.debug(f"EndSession Request: {resp}")
669-
return resp
677+
logger.debug(f"EndSession Request: {_info['request'].to_dict()}")
678+
return _info
670679

671680
def close(
672681
self, state: str, post_logout_redirect_uri: Optional[str] = ""

src/idpyoidc/client/oauth2/utils.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Optional
33
from typing import Union
44

5+
from idpyoidc.client.defaults import DEFAULT_RESPONSE_MODE
56
from idpyoidc.client.service import Service
67
from idpyoidc.exception import MissingParameter
78
from idpyoidc.exception import MissingRequiredAttribute
@@ -45,22 +46,25 @@ def pick_redirect_uri(
4546
try:
4647
redirect_uri = _redirect_uris["form_post"][0]
4748
except KeyError:
48-
redirect_uri = _redirect_uris["code"][0]
49-
elif response_type == "code" or response_type == ["code"]:
50-
redirect_uri = _redirect_uris["code"][0]
49+
redirect_uri = _redirect_uris["query"][0]
5150
else:
52-
redirect_uri = _redirect_uris["implicit"][0]
51+
redirect_uri = _redirect_uris[_response_mode]
5352
else:
5453
if not response_type:
5554
_conf_resp_types = context.get_usage("response_types", [])
5655
response_type = request_args.get("response_type")
5756
if not response_type and _conf_resp_types:
5857
response_type = _conf_resp_types[0]
5958

60-
if response_type == "code" or response_type == ["code"]:
61-
_response_mode = "query"
62-
else:
63-
_response_mode = "fragment"
59+
if isinstance(response_type, list):
60+
response_type.sort()
61+
response_type = " ".join(response_type)
62+
63+
try:
64+
_response_mode = DEFAULT_RESPONSE_MODE[response_type]
65+
except KeyError:
66+
raise ValueError(f"Unknown response_type: {response_type}")
67+
6468
redirect_uri = _redirect_uris[_response_mode][0]
6569

6670
logger.debug(

src/idpyoidc/client/rp_handler.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,12 @@ def state2issuer(self, state):
124124
:return: An Issuer ID
125125
"""
126126
for _rp in self.issuer2rp.values():
127-
_iss = _rp.get_context().cstate.get_set(state, claim=["iss"]).get("iss")
127+
try:
128+
_set = _rp.get_context().cstate.get_set(state, claim=["iss"])
129+
except KeyError:
130+
continue
131+
132+
_iss = _set.get("iss")
128133
if _iss:
129134
return _iss
130135
return None

tests/private/token_jwks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"keys": [{"kty": "oct", "use": "enc", "kid": "code", "k": "vSHDkLBHhDStkR0NWu8519rmV5zmnm5_"}, {"kty": "oct", "use": "enc", "kid": "refresh", "k": "ygvi663s6qysl0MvtSqO4EH6tBeDjOQ8"}]}
1+
{"keys": [{"kty": "oct", "use": "enc", "kid": "code", "k": "vSHDkLBHhDStkR0NWu8519rmV5zmnm5_"}, {"kty": "oct", "use": "enc", "kid": "refresh", "k": "ASSv_faXjb13FYcRMP7ht8f641jIWw3W"}]}

tests/test_client_12_client_auth.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def test_quote():
7171

7272
class TestClientSecretBasic(object):
7373
def test_construct(self, entity):
74+
entity.context.cstate.update("ABCDE", {'code': 'abcdefghijklmnopqrst'})
75+
7476
_token_service = entity.get_service("accesstoken")
7577
request = _token_service.construct(
7678
request_args={"redirect_uri": "http://example.com", "state": "ABCDE"}
@@ -234,6 +236,8 @@ def test_construct_with_request(self, entity):
234236

235237
class TestClientSecretPost(object):
236238
def test_construct(self, entity):
239+
entity.context.cstate.update("ABCDE", {'code': 'abcdefghijklmnopqrst'})
240+
237241
_token_service = entity.get_service("accesstoken")
238242
request = _token_service.construct(redirect_uri="http://example.com", state="ABCDE")
239243
csp = ClientSecretPost()
@@ -250,6 +254,8 @@ def test_construct(self, entity):
250254
assert http_args is None
251255

252256
def test_modify_1(self, entity):
257+
entity.context.cstate.update("ABCDE", {'code': 'abcdefghijklmnopqrst'})
258+
253259
token_service = entity.get_service("accesstoken")
254260
request = token_service.construct(redirect_uri="http://example.com", state="ABCDE")
255261
csp = ClientSecretPost()
@@ -259,6 +265,8 @@ def test_modify_1(self, entity):
259265
assert "client_secret" in request
260266

261267
def test_modify_2(self, entity):
268+
entity.context.cstate.update("ABCDE", {'code': 'abcdefghijklmnopqrst'})
269+
262270
token_service = entity.get_service("accesstoken")
263271
request = token_service.construct(redirect_uri="http://example.com", state="ABCDE")
264272
csp = ClientSecretPost()

0 commit comments

Comments
 (0)