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

Commit 0947b5c

Browse files
authored
Merge pull request #21 from peppelinux/master
lukewarm refactor of client_authn.py
2 parents bcf0f78 + 10f306d commit 0947b5c

File tree

4 files changed

+89
-98
lines changed

4 files changed

+89
-98
lines changed

src/oidcendpoint/client_authn.py

Lines changed: 42 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,13 @@ def verify(self, request, **kwargs):
136136
logger.info("%s" % sanitize(err))
137137
raise AuthnFailure("Could not verify client_assertion.")
138138

139-
try:
140-
logger.debug("authntoken: %s" % sanitize(ca_jwt.to_dict()))
141-
except AttributeError:
142-
logger.debug("authntoken: %s" % sanitize(ca_jwt))
139+
authtoken = sanitize(ca_jwt)
140+
if hasattr(ca_jwt, 'to_dict') and callable(ca_jwt, 'to_dict'):
141+
authtoken = sanitize(ca_jwt.to_dict())
142+
logger.debug("authntoken: {}".format(authtoken))
143143

144144
request[verified_claim_name("client_assertion")] = ca_jwt
145-
146-
try:
147-
client_id = kwargs["client_id"]
148-
except KeyError:
149-
client_id = ca_jwt["iss"]
145+
client_id = kwargs.get("client_id") or ca_jwt["iss"]
150146

151147
# I should be among the audience
152148
# could be either my issuer id or the token endpoint
@@ -244,51 +240,45 @@ def verify_client(
244240
else:
245241
raise UnknownOrNoAuthnMethod(authorization_info)
246242

247-
try:
248-
client_id = auth_info["client_id"]
249-
except KeyError:
250-
try:
251-
_token = auth_info["token"]
252-
except KeyError:
243+
client_id = auth_info.get("client_id")
244+
_token = auth_info.get("token")
245+
246+
if client_id:
247+
248+
if not client_id in endpoint_context.cdb:
249+
raise ValueError("Unknown Client ID")
250+
251+
_cinfo = endpoint_context.cdb[client_id]
252+
if isinstance(_cinfo, str):
253+
if not _cinfo in endpoint_context.cdb:
254+
raise ValueError("Unknown Client ID")
255+
256+
if not valid_client_info(_cinfo):
257+
logger.warning("Client registration has timed out")
258+
raise ValueError("Not valid client")
259+
260+
# store what authn method was used
261+
if auth_info.get("method"):
262+
if endpoint_context.cdb[client_id].get("auth_method") and \
263+
request.__class__.__name__ in endpoint_context.cdb[client_id]["auth_method"]:
264+
endpoint_context.cdb[client_id]["auth_method"][
265+
request.__class__.__name__
266+
] = auth_info["method"]
267+
else:
268+
endpoint_context.cdb[client_id]["auth_method"] = {
269+
request.__class__.__name__: auth_info["method"]
270+
}
271+
272+
elif not client_id and get_client_id_from_token:
273+
if not _token:
253274
logger.warning("No token")
254-
else:
255-
if get_client_id_from_token:
256-
try:
257-
_id = get_client_id_from_token(endpoint_context, _token, request)
258-
except KeyError:
259-
raise ValueError("Unknown token")
260-
261-
if _id:
262-
auth_info["client_id"] = _id
263-
else:
275+
raise ValueError("No token")
276+
264277
try:
265-
_cinfo = endpoint_context.cdb[client_id]
278+
# get_client_id_from_token is a callback... Do not abuse for code readability.
279+
auth_info["client_id"] = get_client_id_from_token(endpoint_context,
280+
_token, request)
266281
except KeyError:
267-
raise ValueError("Unknown Client ID")
268-
else:
269-
if isinstance(_cinfo, str):
270-
try:
271-
_cinfo = endpoint_context.cdb[_cinfo]
272-
except KeyError:
273-
raise ValueError("Unknown Client ID")
274-
275-
try:
276-
valid_client_info(_cinfo)
277-
except KeyError:
278-
logger.warning("Client registration has timed out")
279-
raise ValueError("Not valid client")
280-
else:
281-
# store what authn method was used
282-
try:
283-
endpoint_context.cdb[client_id]["auth_method"][
284-
request.__class__.__name__
285-
] = auth_info["method"]
286-
except KeyError:
287-
try:
288-
endpoint_context.cdb[client_id]["auth_method"] = {
289-
request.__class__.__name__: auth_info["method"]
290-
}
291-
except KeyError:
292-
pass
282+
raise ValueError("Unknown token")
293283

294284
return auth_info

src/oidcendpoint/in_memory_db.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ class InMemoryDataBase(object):
22
def __init__(self):
33
self.db = {}
44

5+
def __contains__(self, key):
6+
if self.db.get(key):
7+
return 1
8+
59
def set(self, key, value):
610
self.db[key] = value
711

812
def get(self, key):
9-
try:
10-
return self.db[key]
11-
except KeyError:
12-
return None
13+
return self.db.get(key, None)
1314

1415
def delete(self, key):
15-
del self.db[key]
16+
if self.db.get(key):
17+
del self.db[key]
1618

1719
def keys(self):
1820
return self.db.keys()

src/oidcendpoint/oidc/authorization.py

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
from oidcendpoint.user_authn.authn_context import pick_auth
3939
from oidcendpoint.user_info import SCOPE2CLAIMS
4040

41-
LOGGER = logging.getLogger(__name__)
41+
logger = logging.getLogger(__name__)
4242

4343
FORM_POST = """<html>
4444
<head>
@@ -71,7 +71,7 @@ def inputs(form_args):
7171

7272
def max_age(request):
7373
cn = verified_claim_name("request")
74-
return request.get(cn, {}).get("max_age") or request.get("max_age", 0)
74+
return request.get(cn, {}).get("max_age") or request.get("max_age", 0)
7575

7676

7777
def re_authenticate(request, authn):
@@ -108,7 +108,7 @@ def verify_uri(endpoint_context, request, uri_type, client_id=None):
108108
_cid = request.get("client_id", client_id)
109109

110110
if not _cid:
111-
LOGGER.error("No client id found")
111+
logger.error("No client id found")
112112
raise UnknownClient("No client_id provided")
113113

114114
_redirect_uri = unquote(request[uri_type])
@@ -185,23 +185,26 @@ def get_uri(endpoint_context, request, uri_type):
185185
:param uri_type: 'redirect_uri' or 'post_logout_redirect_uri'
186186
:return: redirect_uri
187187
"""
188+
uri = ""
189+
188190
if uri_type in request:
189191
verify_uri(endpoint_context, request, uri_type)
190192
uri = request[uri_type]
191193
else:
192-
try:
193-
_specs = endpoint_context.cdb[str(request["client_id"])][
194-
"{}s".format(uri_type)
195-
]
196-
except KeyError:
197-
raise ParameterError("Missing {} and none registered".format(uri_type))
198-
else:
194+
195+
uris = "{}s".format(uri_type)
196+
client_id = str(request["client_id"])
197+
if client_id in endpoint_context.cdb:
198+
_specs = endpoint_context.cdb[client_id].get(uris)
199+
if not _specs:
200+
raise ParameterError("Missing {} and none registered".format(uri_type))
201+
199202
if len(_specs) > 1:
200203
raise ParameterError(
201204
"Missing {} and more than one registered".format(uri_type)
202205
)
203-
else:
204-
uri = join_query(*_specs[0])
206+
207+
uri = join_query(*_specs[0])
205208

206209
return uri
207210

@@ -267,15 +270,15 @@ def create_authn_response(endpoint, request, sid):
267270
if "token" in rtype:
268271
_dic = _context.sdb.upgrade_to_token(issue_refresh=False, key=sid)
269272

270-
LOGGER.debug("_dic: %s" % sanitize(_dic))
273+
logger.debug("_dic: %s" % sanitize(_dic))
271274
for key, val in _dic.items():
272275
if key in aresp.parameters() and val is not None:
273276
aresp[key] = val
274277

275278
handled_response_type.append("token")
276279

277280
_access_token = aresp.get("access_token", None)
278-
281+
279282
if "id_token" in request["response_type"]:
280283
kwargs = {}
281284
if {"code", "id_token", "token"}.issubset(rtype):
@@ -291,7 +294,7 @@ def create_authn_response(endpoint, request, sid):
291294
try:
292295
id_token = _context.idtoken.make(request, _sinfo, **kwargs)
293296
except (JWEException, NoSuitableSigningKeys) as err:
294-
LOGGER.warning(str(err))
297+
logger.warning(str(err))
295298
resp = AuthorizationErrorResponse(
296299
error="invalid_request",
297300
error_description="Could not sign/encrypt id_token",
@@ -374,7 +377,7 @@ def _post_parse_request(self, request, client_id, endpoint_context, **kwargs):
374377
:return:
375378
"""
376379
if not request:
377-
LOGGER.debug("No AuthzRequest")
380+
logger.debug("No AuthzRequest")
378381
return AuthorizationErrorResponse(
379382
error="invalid_request", error_description="Can not parse AuthzRequest"
380383
)
@@ -383,7 +386,7 @@ def _post_parse_request(self, request, client_id, endpoint_context, **kwargs):
383386

384387
_cinfo = endpoint_context.cdb.get(client_id)
385388
if not _cinfo:
386-
LOGGER.error(
389+
logger.error(
387390
"Client ID ({}) not in client database".format(request["client_id"])
388391
)
389392
return AuthorizationErrorResponse(
@@ -414,7 +417,7 @@ def pick_authn_method(self, request, redirect_uri, acr=None, **kwargs):
414417
auth_id = kwargs.get("auth_method_id")
415418
if auth_id:
416419
return self.endpoint_context.authn_broker[auth_id]
417-
420+
418421
if acr:
419422
res = self.endpoint_context.authn_broker.pick(acr)
420423
else:
@@ -462,7 +465,7 @@ def setup_auth(self, request, redirect_uri,
462465
identity = None
463466
_ts = 0
464467
except ToOld:
465-
LOGGER.info("Too old authentication")
468+
logger.info("Too old authentication")
466469
identity = None
467470
_ts = 0
468471
else:
@@ -474,22 +477,16 @@ def setup_auth(self, request, redirect_uri,
474477
else:
475478
identity = json.loads(as_unicode(_id))
476479

477-
try:
478-
session = self.endpoint_context.sdb[identity["sid"]]
479-
except KeyError:
480+
session = self.endpoint_context.sdb[identity.get("sid")]
481+
if not session or "revoked" in session:
480482
identity = None
481-
else:
482-
if session is None:
483-
identity = None
484-
elif "revoked" in session:
485-
identity = None
486483

487484
authn_args = authn_args_gather(request, authn_class_ref,
488485
cinfo, **kwargs)
489486

490487
# To authenticate or Not
491488
if identity is None: # No!
492-
LOGGER.info("No active authentication")
489+
logger.info("No active authentication")
493490
if "prompt" in request and "none" in request["prompt"]:
494491
# Need to authenticate but not allowed
495492
return {
@@ -500,7 +497,7 @@ def setup_auth(self, request, redirect_uri,
500497
else:
501498
return {"function": authn, "args": authn_args}
502499
else:
503-
LOGGER.info("Active authentication")
500+
logger.info("Active authentication")
504501
if re_authenticate(request, authn):
505502
# demand re-authentication
506503
return {"function": authn, "args": authn_args}
@@ -516,7 +513,7 @@ def setup_auth(self, request, redirect_uri,
516513
sids[-1]
517514
).uid
518515
):
519-
LOGGER.debug("Wanted to be someone else!")
516+
logger.debug("Wanted to be someone else!")
520517
if "prompt" in request and "none" in request["prompt"]:
521518
# Need to authenticate but not allowed
522519
return {
@@ -610,7 +607,7 @@ def post_authentication(self, user, request, sid, **kwargs):
610607
response_info, "server_error", "{}".format(err.args)
611608
)
612609

613-
LOGGER.debug("response type: %s" % request["response_type"])
610+
logger.debug("response type: %s" % request["response_type"])
614611

615612
if self.endpoint_context.sdb.is_session_revoked(sid):
616613
return self.error_response(
@@ -694,7 +691,7 @@ def authz_part2(self, user, authn_event, request, **kwargs):
694691

695692
opbs = session_cookie[ec.cookie_name["session_management"]]
696693

697-
LOGGER.debug("compute_session_state: client_id=%s, origin=%s, opbs=%s, salt=%s",
694+
logger.debug("compute_session_state: client_id=%s, origin=%s, opbs=%s, salt=%s",
698695
request["client_id"], resp_info["return_uri"], opbs.value, salt)
699696

700697
_session_state = compute_session_state(
@@ -753,8 +750,8 @@ def process_request(self, request_info=None, **kwargs):
753750

754751
_function = info.get("function")
755752
if not _function:
756-
LOGGER.debug("- authenticated -")
757-
LOGGER.debug("AREQ keys: %s" % request_info.keys())
753+
logger.debug("- authenticated -")
754+
logger.debug("AREQ keys: %s" % request_info.keys())
758755
res = self.authz_part2(
759756
info["user"], info["authn_event"],
760757
request_info, cookie=cookie
@@ -768,5 +765,5 @@ def process_request(self, request_info=None, **kwargs):
768765
"return_uri": request_info["redirect_uri"],
769766
}
770767
except Exception as err:
771-
LOGGER.exception(err)
768+
logger.exception(err)
772769
return {"http_response": "Internal error: {}".format(err)}

src/oidcendpoint/session.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from oidcendpoint import token_handler
1414
from oidcendpoint.authn_event import AuthnEvent
1515
from oidcendpoint.in_memory_db import InMemoryDataBase
16-
from oidcendpoint.sso_db import SSODb
16+
from oidcendpoint.sso_db import (SSODb, KEY_FORMAT)
1717
from oidcendpoint.token_handler import AccessCodeUsed
1818
from oidcendpoint.token_handler import ExpiredToken
1919
from oidcendpoint.token_handler import UnknownToken
@@ -119,7 +119,7 @@ def dict_match(a, b):
119119

120120
class SessionDB(object):
121121
def __init__(self, db, handler, sso_db, userinfo=None, sub_func=None):
122-
# db must implement the InMemoryStateDataBase interface
122+
# db must implement the InMemoryDataBase interface
123123
self._db = db
124124
self.handler = handler
125125
self.sso_db = sso_db
@@ -224,13 +224,14 @@ def update_by_token(self, token, **kwargs):
224224
return self.update(_sid, **kwargs)
225225

226226
def map_kv2sid(self, key, value, sid):
227-
self._db.set("__{}__{}__".format(key, value), sid)
227+
""" KEY_FORMAT = "__{}__{}" """
228+
self._db.set(KEY_FORMAT.format(key, value), sid)
228229

229230
def delete_kv2sid(self, key, value):
230-
self._db.delete("__{}__{}__".format(key, value))
231+
self._db.delete(KEY_FORMAT.format(key, value))
231232

232233
def get_sid_by_kv(self, key, value):
233-
return self._db.get("__{}__{}__".format(key, value))
234+
return self._db.get(KEY_FORMAT.format(key, value))
234235

235236
def get_token(self, sid):
236237
_sess_info = self[sid]
@@ -241,7 +242,8 @@ def get_token(self, sid):
241242
return _sess_info["access_token"]
242243

243244
def do_sub(
244-
self, sid, uid, client_salt, sector_id="", subject_type="public", user_salt=""
245+
self, sid, uid, client_salt, sector_id="",
246+
subject_type="public", user_salt=""
245247
):
246248
"""
247249
Create and store a subject identifier

0 commit comments

Comments
 (0)