Skip to content
This repository was archived by the owner on Jun 23, 2023. It is now read-only.

Commit 11194bc

Browse files
authored
Merge pull request #185 from IdentityPython/develop
v2.4.1
2 parents 8de3acf + 59c1ba7 commit 11194bc

File tree

8 files changed

+63
-42
lines changed

8 files changed

+63
-42
lines changed

example/flask_op/views.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import werkzeug
1919

2020
from oidcop.exception import FailedAuthentication
21-
from oidcop.exception import InvalidClient
22-
from oidcop.exception import UnknownClient
21+
from oidcop.exception import ClientAuthenticationError
22+
from oidcop.exception import TokenAuthenticationError
2323
from oidcop.oidc.token import Token
2424

2525
# logger = logging.getLogger(__name__)
@@ -224,12 +224,18 @@ def service_endpoint(endpoint):
224224
if request.method == 'GET':
225225
try:
226226
req_args = endpoint.parse_request(request.args.to_dict(), http_info=http_info)
227-
except (InvalidClient, UnknownClient) as err:
227+
except ClientAuthenticationError as err:
228228
_log.error(err)
229229
return make_response(json.dumps({
230230
'error': 'unauthorized_client',
231231
'error_description': str(err)
232-
}), 400)
232+
}), 401)
233+
except TokenAuthenticationError as err:
234+
_log.error(err)
235+
return make_response(json.dumps({
236+
'error': 'invalid_token',
237+
'error_description': str(err)
238+
}), 401)
233239
except Exception as err:
234240
_log.error(err)
235241
return make_response(json.dumps({

src/oidcop/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import secrets
22

3-
__version__ = "2.4.0"
3+
__version__ = "2.4.1"
44

55
DEF_SIGN_ALG = {
66
"id_token": "RS256",

src/oidcop/client_authn.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from oidcop import JWT_BEARER
2020
from oidcop import sanitize
2121
from oidcop.endpoint_context import EndpointContext
22+
from oidcop.exception import BearerTokenAuthenticationError
2223
from oidcop.exception import InvalidClient
2324
from oidcop.exception import MultipleUsage
2425
from oidcop.exception import NotForMe
@@ -406,15 +407,15 @@ def verify_client(
406407
elif not client_id and get_client_id_from_token:
407408
if not _token:
408409
logger.warning("No token")
409-
raise ValueError("No token")
410+
raise BearerTokenAuthenticationError("No token")
410411

411412
try:
412413
# get_client_id_from_token is a callback... Do not abuse for code readability.
413414
auth_info["client_id"] = get_client_id_from_token(endpoint_context, _token, request)
414415
except ToOld:
415-
raise ValueError("Expired token")
416+
raise BearerTokenAuthenticationError("Expired token")
416417
except KeyError:
417-
raise ValueError("Unknown token")
418+
raise BearerTokenAuthenticationError("Unknown token")
418419

419420
return auth_info
420421

src/oidcop/endpoint.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ def parse_request(
175175
req = self.request_cls()
176176

177177
# Verify that the client is allowed to do this
178-
_client_id = ""
179178
auth_info = self.client_authentication(req, http_info, endpoint=self, **kwargs)
180179

181180
if "client_id" in auth_info:
@@ -206,14 +205,6 @@ def parse_request(
206205
request=req, client_id=_client_id, http_info=http_info, **kwargs
207206
)
208207

209-
def get_client_id_from_token(
210-
self,
211-
endpoint_context: EndpointContext,
212-
token: str,
213-
request: Optional[Union[Message, dict]] = None,
214-
):
215-
return ""
216-
217208
def client_authentication(self, request: Message, http_info: Optional[dict] = None, **kwargs):
218209
"""
219210
Do client authentication
@@ -230,7 +221,7 @@ def client_authentication(self, request: Message, http_info: Optional[dict] = No
230221
endpoint_context=self.server_get("endpoint_context"),
231222
request=request,
232223
http_info=http_info,
233-
get_client_id_from_token=self.get_client_id_from_token,
224+
get_client_id_from_token=getattr(self, "get_client_id_from_token", None),
234225
**kwargs
235226
)
236227

src/oidcop/exception.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,23 @@ class RedirectURIError(OidcEndpointError):
5858
pass
5959

6060

61-
class UnknownClient(OidcEndpointError):
61+
class ClientAuthenticationError(OidcEndpointError):
6262
pass
6363

6464

65-
class InvalidClient(OidcEndpointError):
65+
class UnknownClient(ClientAuthenticationError):
6666
pass
6767

6868

69-
class UnAuthorizedClient(OidcEndpointError):
69+
class InvalidClient(ClientAuthenticationError):
70+
pass
71+
72+
73+
class UnAuthorizedClient(ClientAuthenticationError):
74+
pass
75+
76+
77+
class BearerTokenAuthenticationError(OidcEndpointError):
7078
pass
7179

7280

src/oidcop/oauth2/add_on/extra_args.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
from oidcmsg.oauth2 import AccessTokenResponse
2+
from oidcmsg.oauth2 import AuthorizationResponse
3+
from oidcmsg.oauth2 import TokenExchangeResponse
4+
from oidcmsg.oauth2 import TokenIntrospectionResponse
5+
from oidcmsg.oidc import OpenIDSchema
6+
7+
18
def pre_construct(response_args, request, endpoint_context, **kwargs):
29
"""
310
Add extra arguments to the request.
@@ -11,12 +18,25 @@ def pre_construct(response_args, request, endpoint_context, **kwargs):
1118

1219
_extra = endpoint_context.add_on.get("extra_args")
1320
if _extra:
14-
for arg, _param in _extra.items():
15-
_val = endpoint_context.get(_param)
21+
if isinstance(response_args, AuthorizationResponse):
22+
_args = _extra.get("authorization", {})
23+
elif isinstance(response_args, AccessTokenResponse):
24+
_args = _extra.get('accesstoken', {})
25+
elif isinstance(response_args, TokenExchangeResponse):
26+
_args = _extra.get('token_exchange', {})
27+
elif isinstance(response_args, TokenIntrospectionResponse):
28+
_args = _extra.get('token_introspection', {})
29+
elif isinstance(response_args, OpenIDSchema):
30+
_args = _extra.get('userinfo', {})
31+
else:
32+
_args = {}
33+
34+
for arg, _param in _args.items():
35+
_val = getattr(endpoint_context, _param)
1636
if _val:
17-
request[arg] = _val
37+
response_args[arg] = _val
1838

19-
return request
39+
return response_args
2040

2141

2242
def add_support(endpoint, **kwargs):

tests/test_26_oidc_userinfo_endpoint.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from oidcop.configure import OPConfiguration
1313
from oidcop.cookie_handler import CookieHandler
1414
from oidcop.exception import ImproperlyConfigured
15+
from oidcop.exception import BearerTokenAuthenticationError
1516
from oidcop.oidc import userinfo
1617
from oidcop.oidc.authorization import Authorization
1718
from oidcop.oidc.provider_config import ProviderConfiguration
@@ -513,11 +514,8 @@ def mock():
513514

514515
monkeypatch.setattr("oidcop.token.utc_time_sans_frac", mock)
515516

516-
_req = self.endpoint.parse_request({}, http_info=http_info)
517-
518-
assert _req.to_dict() == {
519-
"error": "invalid_token", "error_description": "Expired token"
520-
}
517+
with pytest.raises(BearerTokenAuthenticationError):
518+
self.endpoint.parse_request({}, http_info=http_info)
521519

522520
def test_userinfo_claims(self):
523521
_acr = "https://refeds.org/profile/mfa"

tests/test_61_add_on.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import os
2+
from urllib.parse import urlparse
23

34
from cryptojwt.jwk.ec import ECKey
45
from cryptojwt.jwk.ec import new_ec_key
56
from cryptojwt.jws.jws import factory
67
from cryptojwt.key_jar import init_key_jar
78
from oidcmsg.oauth2 import AccessTokenRequest
89
from oidcmsg.oauth2 import AuthorizationRequest
10+
from oidcmsg.oauth2 import AuthorizationResponse
911
from oidcmsg.time_util import utc_time_sans_frac
1012

1113
from oidcop.authn_event import create_authn_event
@@ -155,15 +157,10 @@ def test_process_request(self):
155157
_context = self.endpoint.server_get("endpoint_context")
156158
assert _context.add_on["extra_args"] == {'authorization': {'iss': 'issuer'}}
157159

158-
_pr_resp = self.endpoint.parse_request(AUTH_REQ.to_dict())
159-
_resp = self.endpoint.process_request(_pr_resp)
160-
assert set(_resp.keys()) == {
161-
"response_args",
162-
"fragment_enc",
163-
"return_uri",
164-
"cookie",
165-
"session_id",
166-
}
167-
168-
assert 'iss' in _resp["response_args"]
169-
assert _resp["response_args"]["iss"] == _context.issuer
160+
_pr_resp = self.endpoint.parse_request(AUTH_REQ)
161+
_args = self.endpoint.process_request(_pr_resp)
162+
_resp = self.endpoint.do_response(request=AUTH_REQ, **_args)
163+
parse_res = urlparse(_resp["response"])
164+
_payload = AuthorizationResponse().from_urlencoded(parse_res.query)
165+
assert 'iss' in _payload
166+
assert _payload["iss"] == _context.issuer

0 commit comments

Comments
 (0)