def run_sequence(self, sequence_info, session, conv, ots, trace, index): while index < len(sequence_info["sequence"]): session["index"] = index try: (req_c, resp_c), _kwa = sequence_info["sequence"][index] except (ValueError, TypeError): # Not a tuple ret = self.none_request_response(sequence_info, index, session, conv) self.dump_log(session) if ret: return ret else: try: kwargs = setup(_kwa, conv) except NotSupported: return self.opresult(conv, session) except Exception as err: return self.err_response(session, "function()", err) req = req_c(conv) try: if req.tests["pre"]: conv.test_output.append((req.request, "pre")) conv.test_sequence(req.tests["pre"]) except KeyError: pass except Exception as err: return self.err_response(session, "pre-test", err) conv.request_spec = req conv.trace.info("------------ %s ------------" % req_c.request) if req_c == Discover: # Special since it's just a GET on a URL _r = req.discover( ots.client, issuer=ots.config.CLIENT["srv_discovery_url"]) conv.position, conv.last_response, conv.last_content = _r if conv.last_response.status >= 400: return self.err_response(session, "discover", conv.last_response.text) for x in ots.client.keyjar[ ots.client.provider_info["issuer"]]: try: resp = ots.client.http_request(x.source) except Exception as err: return self.err_response(session, "jwks_fetch", str(err)) else: if resp.status_code < 300: trace.info( "JWKS: %s" % pprint_json(resp.content)) else: return self.err_response(session, "jwks_fetch", resp.content) elif req_c == Webfinger: url = req.discover(**kwargs) if url: conv.trace.request(url) conv.test_output.append( {"id": "-", "status": OK, "message": "Found discovery URL: %s" % url}) else: conv.test_output.append( {"id": "-", "status": ERROR, "message": "Failed to find discovery URL"}) else: try: endp = req.endpoint except AttributeError: pass else: if not endpoint_support(conv.client, endp): conv.test_output.append( {"id": "-", "status": ERROR, "message": "%s not supported" % req.endpoint}) return self.opresult(conv, session) LOGGER.info("request: %s" % req.request) if req.request == "AuthorizationRequest": # New state for each request kwargs["request_args"].update({"state": rndstr(), "nonce": rndstr()}) if "acr_values" not in kwargs["request_args"]: kwargs["request_args"][ "acr_values"] = ots.config.CLIENT[ "behaviour"]["default_acr_values"] try: kwargs["request_args"] = run_func( kwargs["filter"], conv, kwargs["request_args"]) except KeyError: pass if not ots.client.provider_info: return self.err_response(session, req.request, "No provider info") elif req.request in ["AccessTokenRequest", "UserInfoRequest", "RefreshAccessTokenRequest"]: kwargs.update( {"state": conv.AuthorizationRequest["state"]}) if not ots.client.provider_info: return self.err_response(session, req.request, "No provider info") req.rm_nonstandard_args(factory) # Extra arguments outside the OIDC spec try: _extra = ots.config.CLIENT["extra"][req.request] except KeyError: pass except Exception as err: return self.err_response(session, "config_extra", err) else: try: kwargs["request_args"].update(_extra) except KeyError: kwargs["request_args"] = _extra req.call_setup() req.request_txt = req.request if req.request: try: req.request = factory(req.request) except AttributeError: pass if req.request_txt == "ResourceSetDescription": req.kw_args["endpoint"] += "/" + kwargs["rsid"] try: url, body, ht_args = req.construct_request(ots.client, **kwargs) except PyoidcError as err: # A OIDC specific error return self.err_response(session, "construct_request", err) if req.request_txt == "AuthorizationRequest": session["response_type"] = kwargs["request_args"][ "response_type"] LOGGER.info("redirect.url: %s" % url) LOGGER.info("redirect.header: %s" % ht_args) resp = Redirect(str(url)) return resp(self.environ, self.start_response) else: _kwargs = {"http_args": ht_args} if conv.AuthorizationRequest: _kwargs["state"] = conv.AuthorizationRequest[ "state"] try: try: _method = kwargs["method"] except KeyError: _method = req.method try: _ctype = kwargs["ctype"] except KeyError: _ctype = resp_c.ctype response = request_and_return( conv, url, trace, factory(resp_c.response), _method, body, _ctype, **_kwargs) except PyoidcError as err: return self.err_response(session, "request_and_return", err) except JWKESTException as err: return self.err_response(session, "request_and_return", err) if response is None: # bail out return self.err_response(session, "request_and_return", None) trace.response(response) LOGGER.info(response.to_dict()) if resp_c.response in ["ClientInfoResponse", "RegistrationResponse"]: if isinstance(response, RegistrationResponse): ots.client.oidc_registration_info = response ots.client.store_registration_info(response) elif isinstance(response, ClientInfoResponse): ots.client.uma_registration_info = response ots.client.store_registration_info(response) try: post_tests(conv, req_c, resp_c) except Exception as err: return self.err_response(session, "post_test", err) index += 1 _tid = session["testid"] self.dump_log(session, _tid) session["test_info"][_tid] = {"trace": conv.trace, "test_output": conv.test_output} # wrap it up # Any after the fact tests ? try: if sequence_info["tests"]: conv.test_output.append(("After completing the test flow", "")) conv.test_sequence(sequence_info["tests"]) except KeyError: pass except Exception as err: return self.err_response(session, "post_test", err) _tid = session["testid"] self.dump_log(session, _tid) session["test_info"][_tid] = {"trace": conv.trace, "test_output": conv.test_output} session["node"].complete = True resp = Redirect("%sopresult#%s" % (CONF.BASE, _tid[3])) return resp(self.environ, self.start_response)
query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return oprp.sorry_response(oprp.conf.BASE, "missing fragment ?!") _ctype = "urlencoded" elif resp_c.where == "url": info = environ["QUERY_STRING"] _ctype = "urlencoded" else: # resp_c.where == "body" info = get_post(environ) LOGGER.info("Response: %s" % info) conv.trace.reply(info) resp_cls = factory(resp_c.response) algs = ots.client.sign_enc_algs("id_token") try: response = ots.client.parse_response( resp_cls, info, _ctype, conv.AuthorizationRequest["state"], keyjar=ots.client.keyjar, algs=algs) except ResponseError as err: return oprp.err_response(session, "run_sequence", err) except Exception as err: return oprp.err_response(session, "run_sequence", err) LOGGER.info("Parsed response: %s" % response.to_dict()) conv.protocol_response.append((response, info)) conv.trace.response(response)