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 in [OIDCDiscover, UMADiscover]: # 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) resp_c.post_process(conv, _r[2], kwargs) 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()}) 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(MODULE2FACTORY) # 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_exta", 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 = MODULE2FACTORY[req.module]( req.request) except AttributeError: pass except KeyError: try: req.request = MODULE2FACTORY['oic.oic.message']( req.request) except AttributeError: pass if isinstance(req, (self.test_class.ReadResourceSet, self.test_class.DeleteResourceSet, self.test_class.UpdateResourceSet)): 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: if resp_c: _ctype = resp_c.ctype else: _ctype = "" response = None if resp_c: if resp_c.module: _mod = resp_c.module else: _mod = "oic.oic.message" try: _msg_factory = MODULE2FACTORY[_mod] except AttributeError: pass else: try: _resp = _msg_factory(resp_c.response) except Exception as err: pass else: response = request_and_return( conv, url, trace, _resp, _method, body, _ctype, **_kwargs) if response is None: response = ots.client.get_info(url, trace, _method, req, body) 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 resp_c and response is None: # bail out return self.err_response(session, "request_and_return", None) trace.response(response) try: LOGGER.info(response.to_dict()) except AttributeError: # Not a Message instance LOGGER.info(response) try: _ = resp_c.response except AttributeError: pass else: if response: resp_c.post_process(conv, response, kwargs) 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 inst, grp, spec = _tid.split("-", 2) resp = Redirect("%sopresult#%s" % (CONF.BASE, grp)) return resp(self.environ, self.start_response)
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)
def run_sequence(sequence_info, session, conv, ots, environ, start_response, trace, index): while index < len(sequence_info["sequence"]): session["index"] = index try: req_c, resp_c = sequence_info["sequence"][index] except (ValueError, TypeError): # Not a tuple ret = none_request_response(sequence_info, index, session, conv, environ, start_response) if ret: return ret else: 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 err_response(environ, start_response, session, "pre-test", err) conv.request_spec = req if req_c == TEST_FLOWS.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 logging.debug("Provider info: %s" % conv.last_content._dict) verify_support(conv, ots, session["graph"]) else: LOGGER.info("request: %s" % req.request) if req.request == "AuthorizationRequest": # New state for each request kwargs = {"request_args": {"state": rndstr()}} elif req.request in [ "AccessTokenRequest", "UserInfoRequest", "RefreshAccessTokenRequest" ]: kwargs = {"state": conv.AuthorizationRequest["state"]} else: kwargs = {} # Extra arguments outside the OIDC spec try: _extra = ots.config.CLIENT["extra"][req.request] except KeyError: pass except Exception as err: return err_response(environ, start_response, session, "config_exta", err) else: try: kwargs["request_args"].update(_extra) except KeyError: kwargs["request_args"] = _extra req.call_setup() try: url, body, ht_args = req.construct_request( ots.client, **kwargs) except PyoidcError as err: # A OIDC specific error return err_response(environ, start_response, session, "construct_request", err) if req.request == "AuthorizationRequest": session["response_type"] = req.request_args[ "response_type"] LOGGER.info("redirect.url: %s" % url) LOGGER.info("redirect.header: %s" % ht_args) resp = Redirect(str(url)) return resp(environ, start_response) else: _kwargs = {"http_args": ht_args} try: _kwargs["state"] = conv.AuthorizationRequest["state"] except AttributeError: pass try: response = request_and_return( conv, url, message_factory(resp_c.response), req.method, body, resp_c.ctype, **_kwargs) except PyoidcError as err: return err_response(environ, start_response, session, "request_and_return", err) trace.info(response.to_dict()) LOGGER.info(response.to_dict()) if resp_c.response == "RegistrationResponse" and \ isinstance(response, RegistrationResponse): ots.client.store_registration_info(response) else: # must be an ErrorResponse conv.test_output.append({ 'status': 4, "id": "*", 'message': 'Error response: %s' % (response.to_dict(), ) }) return opresult(environ, start_response, conv, session) try: post_tests(conv, req_c, resp_c) except Exception as err: return err_response(environ, start_response, session, "post_test", err) index += 1 _tid = session["testid"] 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", "")) conv.test_sequence(sequence_info["tests"]) except KeyError: pass except Exception as err: return err_response(environ, start_response, session, "post_test", err) _tid = session["testid"] 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(environ, start_response)
def run_sequence(self, sequence_info, session, conv, ots, trace, index): while index < len(sequence_info["sequence"]): logger.info("###{i}### {f} ###{i}###".format(f=session["testid"], i=index)) 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 isinstance(ret, basestring): session["ckey"] = ret elif ret: return ret else: if conv.protocol_response: # If last response was an error response, bail out. inst, txt = conv.protocol_response[-1] try: session["expect_error"] except KeyError: if isinstance(inst, ErrorResponse): return self.err_response(session, "", inst) try: kwargs = setup(_kwa, conv) except NotSupported: self.store_test_info(session) return self.opresult(conv, session) except Exception as err: return self.err_response(session, "function()", err) try: expect_error = _kwa["expect_error"] except KeyError: expect_error = None else: del _kwa["expect_error"] req = req_c(conv) try: _pt = req.tests["pre"] except KeyError: pass else: if _pt: try: conv.test_output.append((req.request, "pre")) conv.test_sequence(_pt) 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 try: _r = req.discover( ots.client, issuer=ots.config.CLIENT["srv_discovery_url"]) except ConnectionError: self.log_fault(session, "Connection Error", "discover_request", ERROR) conv.trace.info(END_TAG) return self.fini(session, conv) 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: conv.last_response = resp conv.last_content = resp.content 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: try: url = req.discover(**kwargs) except ConnectionError: self.log_fault(session, "Connection Error", "WebFinger_request", ERROR) conv.trace.info(END_TAG) return self.fini(session, conv) 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()}) 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(message_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() 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 == "AuthorizationRequest": session["response_type"] = kwargs["request_args"][ "response_type"] logger.info("redirect.url: %s" % url) logger.info("redirect.header: %s" % ht_args) conv.timestamp.append((url, utc_time_sans_frac())) 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: _method = kwargs["method"] except KeyError: _method = req.method try: _ctype = kwargs["ctype"] except KeyError: _ctype = resp_c.ctype self.dump_log(session, session["testid"]) try: response = request_and_return( conv, url, trace, message_factory(resp_c.response), _method, body, _ctype, **_kwargs) except MissingErrorResponse: self.log_fault(session, "Missing Error Response", "request_response", self.get_err_type(session)) conv.trace.info(END_TAG) return self.fini(session, conv) 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) except ConnectionError: self.log_fault(session, "Connection Error", "request", self.get_err_type(session)) conv.trace.info(END_TAG) return self.fini(session, conv) if response is None: # bail out self.log_fault(session, "Empty response", "request_response", self.get_err_type(session)) conv.trace.info(END_TAG) return self.fini(session, conv) trace.response(response) logger.info(response.to_dict()) if expect_error: session["expect_error"] = True if isinstance(response, ErrorResponse): if expect_error["stop"]: index = len(sequence_info["sequence"]) session["index"] = index continue else: trace.error("Expected error, didn't get it") return self.err_response( session, "expected error", None) else: if resp_c.response == "RegistrationResponse": if isinstance(response, RegistrationResponse): ots.client.store_registration_info( response) elif resp_c.response == "AccessTokenResponse": if "error" not in response: areq = conv.AuthorizationRequest.to_dict() try: del areq["acr_values"] except KeyError: pass 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) self.store_test_info(session) # 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) return self.fini(session, conv)
def run_sequence(self, sequence_info, session, conv, ots, trace, index): while index < len(sequence_info["sequence"]): logger.info("###{i}### {f} ###{i}###".format( f=session["testid"], i=index)) 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 isinstance(ret, basestring): session["ckey"] = ret elif ret: return ret else: if conv.protocol_response: # If last response was an error response, bail out. inst, txt = conv.protocol_response[-1] try: session["expect_error"] except KeyError: if isinstance(inst, ErrorResponse): return self.err_response(session,"", inst) try: kwargs = setup(_kwa, conv) except NotSupported: self.store_test_info(session) return self.opresult(conv, session) except Exception as err: return self.err_response(session, "function()", err) try: expect_error = _kwa["expect_error"] except KeyError: expect_error = None else: del _kwa["expect_error"] req = req_c(conv) try: _pt = req.tests["pre"] except KeyError: pass else: if _pt: try: conv.test_output.append((req.request, "pre")) conv.test_sequence(_pt) 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 try: _r = req.discover( ots.client, issuer=ots.config.CLIENT["srv_discovery_url"]) except ConnectionError: self.log_fault(session, "Connection Error", "discover_request", ERROR) conv.trace.info(END_TAG) return self.fini(session, conv) 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: conv.last_response = resp conv.last_content = resp.content 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: try: url = req.discover(**kwargs) except ConnectionError: self.log_fault(session, "Connection Error", "WebFinger_request", ERROR) conv.trace.info(END_TAG) return self.fini(session, conv) 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()}) 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(message_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() 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 == "AuthorizationRequest": session["response_type"] = kwargs["request_args"][ "response_type"] logger.info("redirect.url: %s" % url) logger.info("redirect.header: %s" % ht_args) conv.timestamp.append((url, utc_time_sans_frac())) 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: _method = kwargs["method"] except KeyError: _method = req.method try: _ctype = kwargs["ctype"] except KeyError: _ctype = resp_c.ctype self.dump_log(session, session["testid"]) try: response = request_and_return( conv, url, trace, message_factory( resp_c.response), _method, body, _ctype, **_kwargs) except MissingErrorResponse: self.log_fault(session, "Missing Error Response", "request_response", self.get_err_type(session)) conv.trace.info(END_TAG) return self.fini(session, conv) 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) except ConnectionError: self.log_fault(session, "Connection Error", "request", self.get_err_type(session)) conv.trace.info(END_TAG) return self.fini(session, conv) if response is None: # bail out self.log_fault(session, "Empty response", "request_response", self.get_err_type(session)) conv.trace.info(END_TAG) return self.fini(session, conv) trace.response(response) logger.info(response.to_dict()) if expect_error: session["expect_error"] = True if isinstance(response, ErrorResponse): if expect_error["stop"]: index = len(sequence_info["sequence"]) session["index"] = index continue else: trace.error("Expected error, didn't get it") return self.err_response(session, "expected error", None) else: if resp_c.response == "RegistrationResponse": if isinstance(response, RegistrationResponse): ots.client.store_registration_info(response) elif resp_c.response == "AccessTokenResponse": if "error" not in response: areq = conv.AuthorizationRequest.to_dict() try: del areq["acr_values"] except KeyError: pass 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) self.store_test_info(session) # 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) return self.fini(session, conv)
def run_sequence(sequence_info, session, conv, ots, environ, start_response, trace, index): while index < len(sequence_info["sequence"]): session["index"] = index try: req_c, resp_c = sequence_info["sequence"][index] except (ValueError, TypeError): # Not a tuple ret = none_request_response(sequence_info, index, session, conv, environ, start_response) if ret: return ret else: 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 err_response(environ, start_response, session, "pre-test", err) conv.request_spec = req if req_c == TEST_FLOWS.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 logging.debug("Provider info: %s" % conv.last_content._dict) verify_support(conv, ots, session["graph"]) else: LOGGER.info("request: %s" % req.request) if req.request == "AuthorizationRequest": # New state for each request kwargs = {"request_args": {"state": rndstr()}} elif req.request in ["AccessTokenRequest", "UserInfoRequest", "RefreshAccessTokenRequest"]: kwargs = {"state": conv.AuthorizationRequest["state"]} else: kwargs = {} # Extra arguments outside the OIDC spec try: _extra = ots.config.CLIENT["extra"][req.request] except KeyError: pass except Exception as err: return err_response(environ, start_response, session, "config_exta", err) else: try: kwargs["request_args"].update(_extra) except KeyError: kwargs["request_args"] = _extra req.call_setup() try: url, body, ht_args = req.construct_request(ots.client, **kwargs) except PyoidcError as err: # A OIDC specific error return err_response(environ, start_response, session, "construct_request", err) if req.request == "AuthorizationRequest": session["response_type"] = req.request_args["response_type"] LOGGER.info("redirect.url: %s" % url) LOGGER.info("redirect.header: %s" % ht_args) resp = Redirect(str(url)) return resp(environ, start_response) else: _kwargs = {"http_args": ht_args} try: _kwargs["state"] = conv.AuthorizationRequest["state"] except AttributeError: pass try: response = request_and_return( conv, url, message_factory(resp_c.response), req.method, body, resp_c.ctype, **_kwargs) except PyoidcError as err: return err_response(environ, start_response, session, "request_and_return", err) trace.info(response.to_dict()) LOGGER.info(response.to_dict()) if resp_c.response == "RegistrationResponse" and \ isinstance(response, RegistrationResponse): ots.client.store_registration_info(response) else: # must be an ErrorResponse conv.test_output.append( {'status': 4, "id": "*", 'message': 'Error response: %s' % (response.to_dict(),)}) return opresult(environ, start_response, conv, session) try: post_tests(conv, req_c, resp_c) except Exception as err: return err_response(environ, start_response, session, "post_test", err) index += 1 _tid = session["testid"] 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", "")) conv.test_sequence(sequence_info["tests"]) except KeyError: pass except Exception as err: return err_response(environ, start_response, session, "post_test", err) _tid = session["testid"] 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(environ, start_response)