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

Commit fe8f38f

Browse files
committed
Refactor introspection
1 parent ab03158 commit fe8f38f

File tree

5 files changed

+91
-156
lines changed

5 files changed

+91
-156
lines changed

src/oidcendpoint/jwt_token.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
from typing import Optional
44

55
from cryptojwt import JWT
6+
from cryptojwt.jws.exception import JWSException
67

78
from oidcendpoint.exception import ToOld
89
from oidcendpoint.token_handler import Token
910
from oidcendpoint.token_handler import is_expired
11+
from oidcendpoint.token_handler import UnknownToken
1012
from oidcendpoint.user_info import scope2claims
1113

1214

@@ -94,7 +96,10 @@ def info(self, token):
9496
:return: tuple of token type and session id
9597
"""
9698
verifier = JWT(key_jar=self.key_jar, allowed_sign_algs=[self.alg])
97-
_payload = verifier.unpack(token)
99+
try:
100+
_payload = verifier.unpack(token)
101+
except JWSException:
102+
raise UnknownToken()
98103

99104
if is_expired(_payload["exp"]):
100105
raise ToOld("Token has expired")

src/oidcendpoint/oauth2/introspection.py

Lines changed: 18 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
"""Implements RFC7662"""
22
import logging
33

4-
from cryptojwt import JWT
5-
from cryptojwt.jws.jws import factory
64
from oidcmsg import oauth2
75
from oidcmsg.time_util import utc_time_sans_frac
86

@@ -11,18 +9,6 @@
119
LOGGER = logging.getLogger(__name__)
1210

1311

14-
def before(t1, t2, range):
15-
if t1 < (t2 - range):
16-
return True
17-
return False
18-
19-
20-
def after(t1, t2, range):
21-
if t1 > (t2 + range):
22-
return True
23-
return False
24-
25-
2612
class Introspection(Endpoint):
2713
"""Implements RFC 7662"""
2814

@@ -49,49 +35,30 @@ def get_client_id_from_token(self, endpoint_context, token, request=None):
4935
sinfo = endpoint_context.sdb[token]
5036
return sinfo["authn_req"]["client_id"]
5137

52-
def do_jws(self, token):
53-
_jwt = JWT(key_jar=self.endpoint_context.keyjar)
54-
38+
def _introspect(self, token):
5539
try:
56-
_jwt_info = _jwt.unpack(token)
57-
except Exception as err:
58-
return None
59-
60-
return _jwt_info
61-
62-
def do_access_token(self, token):
63-
try:
64-
_info = self.endpoint_context.sdb[token]
40+
info = self.endpoint_context.sdb[token]
6541
except KeyError:
6642
return None
6743

68-
_revoked = _info.get("revoked", False)
69-
if _revoked:
44+
# Make sure that the token is an access_token or a refresh_token
45+
if token not in info.get("access_token") and token != info.get(
46+
"refresh_token"
47+
):
7048
return None
7149

72-
_eat = _info.get("expires_at")
73-
if _eat < utc_time_sans_frac():
50+
eat = info.get("expires_at")
51+
if eat and eat < utc_time_sans_frac():
7452
return None
7553

76-
if _info: # Now what can be returned ?
77-
_ret = {
78-
"sub": _info["sub"],
79-
"client_id": _info["client_id"],
80-
"token_type": "bearer",
81-
"iss": self.endpoint_context.issuer
82-
}
83-
_authn = _info.get("authn_event")
84-
if _authn:
85-
_ret["authn_info"] = _authn["authn_info"]
86-
_ret["authn_time"] = _authn["authn_time"]
87-
88-
_scope = _info.get("scope")
89-
if not _scope:
90-
_ret["scope"] = " ".join(_info["authn_req"]["scope"])
91-
92-
return _ret
93-
else:
94-
return _info
54+
if info: # Now what can be returned ?
55+
ret = info.to_dict()
56+
ret["iss"] = self.endpoint_context.issuer
57+
58+
if "scope" not in ret:
59+
ret["scope"] = " ".join(info["authn_req"]["scope"])
60+
61+
return ret
9562

9663
def process_request(self, request=None, **kwargs):
9764
"""
@@ -107,29 +74,8 @@ def process_request(self, request=None, **kwargs):
10774
_token = _introspect_request["token"]
10875
_resp = self.response_cls(active=False)
10976

110-
if factory(_token):
111-
_info = self.do_jws(_token)
112-
if _info is None:
113-
return {"response_args": _resp}
114-
_now = utc_time_sans_frac()
115-
116-
# Time checks
117-
if "exp" in _info:
118-
if after(_now, _info["exp"], self.offset):
119-
return {"response_args": _resp}
120-
if 'iat' in _info:
121-
if after(_info["iat"], _now, self.offset):
122-
return {"response_args": _resp}
123-
if 'nbf' in _info:
124-
if before(_now, _info["nbf"], self.offset):
125-
return {"response_args": _resp}
126-
else:
127-
# A non-jws access token
128-
_info = self.do_access_token(_token)
129-
if _info is None:
130-
return {"response_args": _resp}
131-
132-
if not _info:
77+
_info = self._introspect(_token)
78+
if _info is None:
13379
return {"response_args": _resp}
13480

13581
if "release" in self.kwargs:

src/oidcendpoint/session.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,8 @@ def revoke_session(self, sid="", token=""):
461461
_sinfo = self[sid]
462462
for token_type in self.handler.keys():
463463
_sinfo.pop(token_type, None)
464-
465-
self.update(sid, revoked=True)
464+
_sinfo["revoked"] = True
465+
self[sid] = _sinfo
466466

467467
def get_client_id_for_session(self, sid):
468468
return self[sid]["client_id"]

src/oidcendpoint/token_handler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from cryptojwt.key_jar import init_key_jar
88
from cryptojwt.utils import as_bytes
99
from cryptojwt.utils import as_unicode
10+
from cryptojwt.exception import BadSyntax
1011
from oidcmsg.time_util import time_sans_frac
1112

1213
from oidcendpoint import rndstr
@@ -218,7 +219,8 @@ def info(self, item, order=None):
218219
for typ in order:
219220
try:
220221
return self.handler[typ].info(item)
221-
except (KeyError, WrongTokenType, InvalidToken, UnknownToken):
222+
except (KeyError, WrongTokenType, InvalidToken, UnknownToken,
223+
BadSyntax):
222224
pass
223225

224226
logger.info("Unknown token format")

0 commit comments

Comments
 (0)