Skip to content

Commit 7b42590

Browse files
authored
Merge pull request #14 from IdentityPython/develop
The server was not using the fact that it knew in advance which type of token it was handling.
2 parents 332cabd + c69c3cc commit 7b42590

22 files changed

+187
-79
lines changed

doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Contents:
1111
:maxdepth: 2
1212

1313
intro
14+
move
1415
message/index
1516
server/index
1617
client/index

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
77

88
[metadata]
99
name = "idpyoidc"
10-
version = "1.0.9"
10+
version = "1.0.10"
1111
author = "Roland Hedberg"
1212
author_email = "[email protected]"
1313
description = "Everything OAuth2 and OIDC"

src/idpyoidc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__author__ = "Roland Hedberg"
2-
__version__ = "1.0.9"
2+
__version__ = "1.0.10"
33

44
import os
55
from typing import Dict

src/idpyoidc/server/oauth2/authorization.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,10 @@ def _unwrap_identity(self, identity):
528528
except BadSyntax:
529529
return identity
530530
else:
531-
_id = b64d(as_bytes(identity))
531+
try:
532+
_id = b64d(as_bytes(identity))
533+
except BadSyntax:
534+
return identity
532535

533536
return json.loads(as_unicode(_id))
534537

src/idpyoidc/server/oauth2/token.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
from idpyoidc.message import Message
88
from idpyoidc.message.oauth2 import AccessTokenResponse
99
from idpyoidc.message.oauth2 import ResponseMessage
10+
from idpyoidc.message.oauth2 import TokenExchangeRequest
1011
from idpyoidc.message.oidc import TokenErrorResponse
1112
from idpyoidc.server.endpoint import Endpoint
1213
from idpyoidc.server.exception import ProcessError
1314
from idpyoidc.server.oauth2.token_helper import AccessTokenHelper
1415
from idpyoidc.server.oauth2.token_helper import RefreshTokenHelper
16+
from idpyoidc.server.session.token import TOKEN_TYPES_MAPPING
1517
from idpyoidc.util import importer
1618

1719
logger = logging.getLogger(__name__)
@@ -125,8 +127,14 @@ def process_request(self, request: Optional[Union[Message, dict]] = None, **kwar
125127

126128
_access_token = response_args["access_token"]
127129
_context = self.server_get("endpoint_context")
130+
131+
if isinstance(request, TokenExchangeRequest):
132+
_handler_key = TOKEN_TYPES_MAPPING[request["requested_token_type"]]
133+
else:
134+
_handler_key = "access_token"
135+
128136
_session_info = _context.session_manager.get_session_info_by_token(
129-
_access_token, grant=True
137+
_access_token, grant=True, handler_key=_handler_key
130138
)
131139

132140
_cookie = _context.new_cookie(

src/idpyoidc/server/oauth2/token_helper.py

Lines changed: 25 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 cryptojwt import BadSyntax
56
from cryptojwt.exception import JWKESTException
67

78
from idpyoidc.exception import ImproperlyConfigured
@@ -120,7 +121,9 @@ def process_request(self, req: Union[Message, dict], **kwargs):
120121
except KeyError: # Missing code parameter - absolutely fatal
121122
return self.error_cls(error="invalid_request", error_description="Missing code")
122123

123-
_session_info = _mngr.get_session_info_by_token(_access_code, grant=True)
124+
_session_info = _mngr.get_session_info_by_token(
125+
_access_code, grant=True, handler_key="authorization_code"
126+
)
124127
client_id = _session_info["client_id"]
125128
if client_id != req["client_id"]:
126129
logger.debug("{} owner of token".format(client_id))
@@ -208,7 +211,9 @@ def post_parse_request(
208211

209212
_mngr = self.endpoint.server_get("endpoint_context").session_manager
210213
try:
211-
_session_info = _mngr.get_session_info_by_token(request["code"], grant=True)
214+
_session_info = _mngr.get_session_info_by_token(
215+
request["code"], grant=True, handler_key="authorization_code"
216+
)
212217
except (KeyError, UnknownToken):
213218
logger.error("Access Code invalid")
214219
return self.error_cls(error="invalid_grant", error_description="Unknown code")
@@ -241,7 +246,9 @@ def process_request(self, req: Union[Message, dict], **kwargs):
241246
return self.error_cls(error="invalid_request", error_description="Wrong grant_type")
242247

243248
token_value = req["refresh_token"]
244-
_session_info = _mngr.get_session_info_by_token(token_value, grant=True)
249+
_session_info = _mngr.get_session_info_by_token(
250+
token_value, grant=True, handler_key="refresh_token"
251+
)
245252
logger.debug("Session info: {}".format(_session_info))
246253

247254
if _session_info["client_id"] != req["client_id"]:
@@ -335,7 +342,9 @@ def post_parse_request(
335342

336343
_mngr = _context.session_manager
337344
try:
338-
_session_info = _mngr.get_session_info_by_token(request["refresh_token"], grant=True)
345+
_session_info = _mngr.get_session_info_by_token(
346+
request["refresh_token"], grant=True, handler_key="refresh_token"
347+
)
339348
except (KeyError, UnknownToken):
340349
logger.error("Refresh token invalid")
341350
return self.error_cls(error="invalid_grant", error_description="Invalid refresh token")
@@ -414,13 +423,18 @@ def post_parse_request(self, request, client_id="", **kwargs):
414423

415424
_mngr = _context.session_manager
416425
try:
417-
_session_info = _mngr.get_session_info_by_token(request["subject_token"], grant=True)
418-
except (KeyError, UnknownToken):
419-
logger.error("Subject token invalid.")
426+
# token exchange is about minting one token based on another
427+
_handler_key = self.token_types_mapping[request["subject_token_type"]]
428+
_session_info = _mngr.get_session_info_by_token(
429+
request["subject_token"], grant=True, handler_key=_handler_key
430+
)
431+
except (KeyError, UnknownToken, BadSyntax) as err:
432+
logger.error(f"Subject token invalid ({err}).")
420433
return self.error_cls(
421434
error="invalid_request", error_description="Subject token invalid"
422435
)
423436

437+
# Find the token instance based on the token value
424438
token = _mngr.find_token(_session_info["session_id"], request["subject_token"])
425439
if token.is_active() is False:
426440
return self.error_cls(
@@ -511,7 +525,10 @@ def process_request(self, request, **kwargs):
511525
_context = self.endpoint.server_get("endpoint_context")
512526
_mngr = _context.session_manager
513527
try:
514-
_session_info = _mngr.get_session_info_by_token(request["subject_token"], grant=True)
528+
_handler_key = self.token_types_mapping[request["subject_token_type"]]
529+
_session_info = _mngr.get_session_info_by_token(
530+
request["subject_token"], grant=True, handler_key=_handler_key
531+
)
515532
except ToOld:
516533
logger.error("Subject token has expired.")
517534
return self.error_cls(

src/idpyoidc/server/oidc/add_on/pkce.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def post_token_parse(request, client_id, endpoint_context, **kwargs):
9999

100100
try:
101101
_session_info = endpoint_context.session_manager.get_session_info_by_token(
102-
request["code"], grant=True
102+
request["code"], grant=True, handler_key="authorization_code"
103103
)
104104
except KeyError:
105105
return TokenErrorResponse(error="invalid_grant", error_description="Unknown access grant")

src/idpyoidc/server/oidc/token_helper.py

Lines changed: 16 additions & 6 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 cryptojwt import BadSyntax
56
from cryptojwt.jwe.exception import JWEException
67
from cryptojwt.jws.exception import NoSuitableSigningKeys
78
from cryptojwt.jwt import utc_time_sans_frac
@@ -29,7 +30,9 @@ def _get_session_info(self, request, session_manager):
2930
except KeyError: # Missing code parameter - absolutely fatal
3031
return self.error_cls(error="invalid_request", error_description="Missing code")
3132

32-
_session_info = session_manager.get_session_info_by_token(_access_code, grant=True)
33+
_session_info = session_manager.get_session_info_by_token(
34+
_access_code, grant=True, handler_key="authorization_code"
35+
)
3336
logger.debug(f"Session info: {_session_info}")
3437
return _session_info, _access_code
3538

@@ -174,7 +177,9 @@ def post_parse_request(
174177

175178
_mngr = self.endpoint.server_get("endpoint_context").session_manager
176179
try:
177-
_session_info = _mngr.get_session_info_by_token(request["code"], grant=True)
180+
_session_info = _mngr.get_session_info_by_token(
181+
request["code"], grant=True, handler_key="authorization_code"
182+
)
178183
except (KeyError, UnknownToken):
179184
logger.error("Access Code invalid")
180185
return self.error_cls(error="invalid_grant", error_description="Unknown code")
@@ -211,7 +216,10 @@ def process_request(self, req: Union[Message, dict], **kwargs):
211216
return self.error_cls(error="invalid_request", error_description="Wrong grant_type")
212217

213218
token_value = req["refresh_token"]
214-
_session_info = _mngr.get_session_info_by_token(token_value, grant=True)
219+
220+
_session_info = _mngr.get_session_info_by_token(
221+
token_value, handler_key="refresh_token", grant=True
222+
)
215223
if _session_info["client_id"] != req["client_id"]:
216224
logger.debug("{} owner of token".format(_session_info["client_id"]))
217225
logger.warning("{} using token it was not given".format(req["client_id"]))
@@ -299,7 +307,7 @@ def process_request(self, req: Union[Message, dict], **kwargs):
299307
):
300308
revoke_refresh = _context.cdb[req["client_id"]].get("revoke_refresh_on_issue")
301309
else:
302-
revoke_refresh = revoke_refresh = self.endpoint.revoke_refresh_on_issue
310+
revoke_refresh = self.endpoint.revoke_refresh_on_issue
303311

304312
if revoke_refresh:
305313
token.revoke()
@@ -328,8 +336,10 @@ def post_parse_request(
328336

329337
_mngr = _context.session_manager
330338
try:
331-
_session_info = _mngr.get_session_info_by_token(request["refresh_token"], grant=True)
332-
except (KeyError, UnknownToken):
339+
_session_info = _mngr.get_session_info_by_token(
340+
request["refresh_token"], handler_key="refresh_token", grant=True
341+
)
342+
except (KeyError, UnknownToken, BadSyntax):
333343
logger.error("Refresh token invalid")
334344
return self.error_cls(error="invalid_grant", error_description="Invalid refresh token")
335345

src/idpyoidc/server/oidc/userinfo.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ def __init__(self, server_get: Callable, add_claims_by_scope: Optional[bool] = T
4848
self.allowed_targets.append("")
4949

5050
def get_client_id_from_token(self, endpoint_context, token, request=None):
51-
_info = endpoint_context.session_manager.get_session_info_by_token(token)
51+
_info = endpoint_context.session_manager.get_session_info_by_token(
52+
token, handler_key="access_token"
53+
)
5254
return _info["client_id"]
5355

5456
def do_response(
@@ -113,7 +115,9 @@ def do_response(
113115
def process_request(self, request=None, **kwargs):
114116
_mngr = self.server_get("endpoint_context").session_manager
115117
try:
116-
_session_info = _mngr.get_session_info_by_token(request["access_token"], grant=True)
118+
_session_info = _mngr.get_session_info_by_token(
119+
request["access_token"], grant=True, handler_key="access_token"
120+
)
117121
except (KeyError, ValueError):
118122
return self.error_cls(error="invalid_token", error_description="Invalid Token")
119123

src/idpyoidc/server/session/manager.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from idpyoidc.server.authn_event import AuthnEvent
1515
from idpyoidc.server.exception import ConfigurationError
1616
from idpyoidc.server.session.database import NoSuchClientSession
17+
from idpyoidc.server.token import Token
1718
from idpyoidc.util import rndstr
1819

1920
from ..token import UnknownToken
@@ -559,13 +560,18 @@ def _compatible_sid(self, sid):
559560
def get_session_info_by_token(
560561
self,
561562
token_value: str,
562-
user_session_info: bool = False,
563-
client_session_info: bool = False,
564-
grant: bool = False,
565-
authentication_event: bool = False,
566-
authorization_request: bool = False,
563+
user_session_info: Optional[bool] = False,
564+
client_session_info: Optional[bool] = False,
565+
grant: Optional[bool] = False,
566+
authentication_event: Optional[bool] = False,
567+
authorization_request: Optional[bool] = False,
568+
handler_key: Optional[str] = "",
567569
) -> dict:
568-
_token_info = self.token_handler.info(token_value)
570+
if handler_key:
571+
_token_info = self.token_handler.handler[handler_key].info(token_value)
572+
else:
573+
_token_info = self.token_handler.info(token_value)
574+
569575
sid = _token_info.get("sid")
570576
# If the token is an ID Token then the sid will not be in the
571577
# _token_info

0 commit comments

Comments
 (0)