def parse_request(self, environ): def rebuild_header_name(environ_key): """Construct the HTTP header name from a WSGI environ variable. """ header_name = environ_key[5:] # strip 'HTTP_' name_parts = header_name.split("_") header_name = "-".join(part.capitalize() for part in name_parts) return header_name request = {} request["host"] = environ.get("HTTP_HOST", None) request["path"] = environ.get("PATH_INFO", None) request["query"] = dict(parse_qsl(environ.get("QUERY_STRING", None))) request["method"] = environ.get("REQUEST_METHOD", None) request["headers"] = {} for key in environ: if key.startswith("HTTP_"): header_name = rebuild_header_name(key) request["headers"][header_name] = environ[key] if "CONTENT_TYPE" in environ: request["headers"]["Content-Type"] = environ["CONTENT_TYPE"] if "CONTENT_LENGTH" in environ: request["headers"]["Content-Length"] = environ["CONTENT_LENGTH"] if environ["CONTENT_LENGTH"]: request["body"] = get_post(environ) return request
def _register_client(self, context): http_authz = context.wsgi_environ.get("HTTP_AUTHORIZATION") try: post_body = get_post(context.wsgi_environ) http_resp = self.OP.register_client(http_authz, post_body) except OIDCFederationError as e: satosa_logging(LOGGER, logging.ERROR, "OIDCFederation frontend error: {}".format(str(e)), context.state) return Response(str(e)) if not isinstance(http_resp, Created): return http_resp return self._fixup_registration_response(http_resp)
def app(environ, start_response): if environ['REQUEST_METHOD'] != 'POST': start_response('405 Not Allowed', [('Content-Type', 'text/plain')]) return ['Only POST is supported.'.encode('utf-8')] post_data = get_post(environ) parsed_data = dict(parse_qsl(post_data)) start_response('200 OK', [('Content-Type', 'application/json')]) try: verified_token = verify_signed_id_token(**parsed_data) except IDTokenVerificationError as e: return [json.dumps({"error": str(e)}).encode('utf-8')] return [verified_token.encode('utf-8')]
def wrapper(environ, start_response): data = get_post(environ) kwargs = dict(urlparse.parse_qsl(data)) kwargs["state"] = json.loads(urlparse.unquote(kwargs["state"])) val, completed = verifier.verify(**kwargs) if not completed: return val(environ, start_response) if val: set_cookie, cookie_value = verifier.create_cookie(val, "auth") cookie_value += "; path=/" url = "{base_url}?{query_string}".format(base_url="/authorization", query_string=kwargs["state"]["query"]) response = SeeOther(url, headers=[(set_cookie, cookie_value)]) return response(environ, start_response) else: # Unsuccessful authentication url = "{base_url}?{query_string}".format(base_url="/authorization", query_string=kwargs["state"]["query"]) response = SeeOther(url) return response(environ, start_response)
def set_profile(self, environ): info = parse_qs(get_post(environ)) try: cp = self.sh.session["profile"].split(".") cp[0] = info["rtype"][0] crsu = [] for name, cs in list(CRYPTSUPPORT.items()): try: if info[name] == ["on"]: crsu.append(cs) except KeyError: pass if len(cp) == 3: if len(crsu) == 3: pass else: cp.append("".join(crsu)) else: # len >= 4 cp[3] = "".join(crsu) try: if info["extra"] == ['on']: if len(cp) == 3: cp.extend(["", "+"]) elif len(cp) == 4: cp.append("+") elif len(cp) == 5: cp[4] = "+" else: if len(cp) == 5: cp = cp[:-1] except KeyError: if len(cp) == 5: cp = cp[:-1] # reset all test flows self.sh.reset_session(profile=".".join(cp)) return self.io.flow_list(self.sh.session) except Exception as err: return self.io.err_response(self.sh.session, "profile", err)
def do(self, path, environ, permission=None, user=""): """ """ method = environ["REQUEST_METHOD"] if method == "GET": if "QUERY_STRING" in environ and environ["QUERY_STRING"]: method = "QUERY" # Verify that the permission is sufficient allowed = False if user: _pat = "%s%s" % (self.base, user) if path.startswith(_pat) or path == _pat: allowed = True elif permission and self.check_permission(permission, method): allowed = True if not allowed: return ErrorResponse(error="Unauthorized") if method in ["PUT", "POST", "PATCH"]: info = get_post(environ) else: info = "" if method == "GET": return self.do_get(path) elif method == "QUERY": return self.do_query(path, environ["QUERY_STRING"]) elif method == "DELETE": return self.do_delete(path) elif method == "PUT": return self.do_put(path, info) elif method == "POST": return self.do_post(path, info, user) elif method == "PATCH": return self.do_patch(path, info) else: return ErrorResponse(error="unsupported_method")
def wrapper(environ, start_response): data = get_post(environ) kwargs = dict(urlparse.parse_qsl(data)) kwargs["state"] = json.loads(urlparse.unquote(kwargs["state"])) val, completed = verifier.verify(**kwargs) if not completed: return val(environ, start_response) if val: set_cookie, cookie_value = verifier.create_cookie(val, "auth") cookie_value += "; path=/" url = "{base_url}?{query_string}".format( base_url="/authorization", query_string=kwargs["state"]["query"]) response = SeeOther(url, headers=[(set_cookie, cookie_value)]) return response(environ, start_response) else: # Unsuccessful authentication url = "{base_url}?{query_string}".format( base_url="/authorization", query_string=kwargs["state"]["query"]) response = SeeOther(url) return response(environ, start_response)
def application(environ, start_response): """ :param environ: The HTTP application environment :param start_response: The application to run when the handling of the request is done :return: The response as a list of lines """ path = environ.get('PATH_INFO', '').lstrip('/') if path == "": return registration(environ, start_response) elif path == "generate_client_credentials": post_data = get_post(environ) query_params = json.loads(post_data) client_id, client_secret = generate_static_client_credentials( query_params) resp = Response(json.dumps({ "client_id": client_id, "client_secret": client_secret }), headers=[('Content-Type', "application/json")]) return resp(environ, start_response) return NotFound("'/" + path + "' not found")(environ, start_response)
def application(self, environ, start_response): logger.info("Connection from: %s" % environ["REMOTE_ADDR"]) session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') logger.info("path: %s" % path) self.events.store(EV_REQUEST, path) try: sh = session['session_info'] except KeyError: sh = SessionHandler(**self.kwargs) sh.session_init() session['session_info'] = sh inut = WebIO(session=sh, **self.kwargs) inut.environ = environ inut.start_response = start_response tester = WebTester(inut, sh, **self.kwargs) if path == "robots.txt": return static_mime("static/robots.txt", environ, start_response) elif path.startswith("static/"): return static_mime(path, environ, start_response) elif path == "list": try: qs = parse_qs(get_post(environ)) except Exception as err: pass else: sh['test_conf'] = dict([(k,v[0]) for k,v in qs.items()]) self.session_conf[sh['sid']] = sh return tester.display_test_list() elif path == '' or path == 'config': sid = rndstr(24) sh['sid'] = sid try: args = sh['test_conf'] except: args = {} return tester.do_config(sid, **args) elif path in self.kwargs['flows'].keys(): # Run flow try: _ = tester.sh['test_conf'] except KeyError: resp = SeeOther('/') return resp(environ, start_response) try: _sid = tester.sh['sid'] except KeyError: _sid = rndstr(24) tester.sh['sid'] = _sid self.session_conf[_sid] = sh resp = tester.run(path, sid=_sid, **self.kwargs) if isinstance(resp, requests.Response): loc = resp.headers['location'] #tester.conv.events.store('Cookie', resp.headers['set-cookie']) if loc.startswith(tester.base_url): path = loc[len(tester.base_url):] else: return resp elif resp is True or resp is False or resp is None: return tester.display_test_list() else: return resp(environ, start_response) elif path == 'display': return inut.flow_list() elif path == "opresult": resp = SeeOther( "/display#{}".format(self.pick_grp(sh['conv'].test_id))) return resp(environ, start_response) elif path.startswith("test_info"): p = path.split("/") try: return inut.test_info(p[1]) except KeyError: return inut.not_found() elif path == 'all': for test_id in sh['flow_names']: resp = tester.run(test_id, **self.kwargs) if resp is True or resp is False: continue elif resp: return resp(environ, start_response) else: resp = ServiceError('Unkown service error') return resp(environ, start_response) return tester.display_test_list() # Whatever gets here should be of the form <session_id>/<path> try: sid, _path = path.split('/', 1) except ValueError: pass else: if _path.startswith("static/"): return static_mime(_path, environ, start_response) try: _sh = self.session_conf[sid] except KeyError: resp = ServiceError("Unknown session") return resp(environ, start_response) tester.sh = _sh if 'HTTP_AUTHORIZATION' in environ: _sh['conv'].events.store('HTTP_AUTHORIZATION', environ['HTTP_AUTHORIZATION']) _p = _path.split('?') if _p[0] in _sh['conv'].entity.endpoints(): resp = self.handle(environ, tester, sid, *_p) self.session_conf[sid] = tester.sh return resp(environ, start_response) for endpoint, service in self.endpoints.items(): if _path == endpoint: logger.info("service: {}".format(service)) try: resp = self.handle(environ, tester, sid, service) return resp(environ, start_response) except Exception as err: print("%s" % err) message = traceback.format_exception(*sys.exc_info()) print(message) logger.exception("%s" % err) resp = ServiceError("%s" % err) return resp(environ) logger.debug("unknown side: %s" % path) resp = NotFound("Couldn't find the side you asked for!") return resp(environ, start_response)
def application(environ, start_response): LOGGER.info("Connection from: %s" % environ["REMOTE_ADDR"]) session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') LOGGER.info("path: %s" % path) oprp = OPRP(**RP_ARGS) oprp.environ = environ oprp.start_response = start_response if path == "robots.txt": return oprp.static("static/robots.txt") elif path == "favicon.ico": return oprp.static("static/favicon.ico") elif path.startswith("static/"): return oprp.static(path) elif path.startswith("export/"): return oprp.static(path) if path == "": # list try: if oprp.session_init(session): return oprp.flow_list(session) else: try: resp = Redirect("%sopresult#%s" % (oprp.conf.BASE, session["testid"][0])) except KeyError: return oprp.flow_list(session) else: return resp(environ, start_response) except Exception as err: return oprp.err_response(session, "session_setup", err) elif path == "logs": return oprp.display_log("log", issuer="", profile="", testid="") elif path.startswith("log"): if path == "log" or path == "log/": _cc = oprp.conf.CLIENT try: _iss = _cc["srv_discovery_url"] except KeyError: _iss = _cc["provider_info"]["issuer"] parts = [quote_plus(_iss)] else: parts = [] while path != "log": head, tail = os.path.split(path) # tail = tail.replace(":", "%3A") # if tail.endswith("%2F"): # tail = tail[:-3] parts.insert(0, tail) path = head return oprp.display_log("log", *parts) elif path.startswith("tar"): path = path.replace(":", "%3A") return oprp.static(path) elif "flow_names" not in session: oprp.session_init(session) if path == "reset": oprp.reset_session(session) return oprp.flow_list(session) elif path == "pedit": try: return oprp.profile_edit(session) except Exception as err: return oprp.err_response(session, "pedit", err) elif path == "profile": info = parse_qs(get_post(environ)) try: cp = session["profile"].split(".") cp[0] = info["rtype"][0] crsu = [] for name, cs in list(CRYPTSUPPORT.items()): try: if info[name] == ["on"]: crsu.append(cs) except KeyError: pass if len(cp) == 3: if len(crsu) == 3: pass else: cp.append("".join(crsu)) else: # len >= 4 cp[3] = "".join(crsu) try: if info["extra"] == ['on']: if len(cp) == 3: cp.extend(["", "+"]) elif len(cp) == 4: cp.append("+") elif len(cp) == 5: cp[4] = "+" else: if len(cp) == 5: cp = cp[:-1] except KeyError: if len(cp) == 5: cp = cp[:-1] # reset all test flows RP_ARGS["test_profile"] = ".".join(cp) oprp.reset_session(session, ".".join(cp)) return oprp.flow_list(session) except Exception as err: return oprp.err_response(session, "profile", err) elif path.startswith("test_info"): p = path.split("/") try: return oprp.test_info(p[1], session) except KeyError: return oprp.not_found() elif path == "continue": try: sequence_info = session["seq_info"] except KeyError: # Cookie delete broke session query = parse_qs(environ["QUERY_STRING"]) path = query["path"][0] index = int(query["index"][0]) conv, sequence_info, ots, trace, index = oprp.session_setup( session, path, index) try: conv = RP_ARGS["cache"][query["ckey"][0]] except KeyError: pass else: ots.client = conv.client session["conv"] = conv except Exception as err: return oprp.err_response(session, "session_setup", err) else: index = session["index"] ots = session["ots"] conv = session["conv"] index += 1 try: return oprp.run_sequence(sequence_info, session, conv, ots, conv.trace, index) except Exception as err: return oprp.err_response(session, "run_sequence", err) elif path == "opresult": try: conv = session["conv"] except KeyError as err: homepage = "" return oprp.sorry_response(homepage, err) return oprp.opresult(conv, session) # expected path format: /<testid>[/<endpoint>] elif path in session["flow_names"]: LOGGER.info("<=<=<=<=< %s >=>=>=>=>" % path) conv, sequence_info, ots, trace, index = oprp.session_setup( session, path) session["node"].complete = False try: return oprp.run_sequence(sequence_info, session, conv, ots, trace, index) except Exception as err: return oprp.err_response(session, "run_sequence", err) elif path in ["authz_cb", "authz_post"]: try: sequence_info = session["seq_info"] index = session["index"] ots = session["ots"] conv = session["conv"] except KeyError as err: # Todo: find out which port I'm listening on return oprp.sorry_response(oprp.conf.BASE, err) (req_c, resp_c), _ = sequence_info["sequence"][index] try: response_mode = conv.AuthorizationRequest["response_mode"] except KeyError: response_mode = None if path == "authz_cb": if response_mode == "form_post": pass elif session["response_type"] and not \ session["response_type"] == ["code"]: # but what if it's all returned as a query ? try: qs = environ["QUERY_STRING"] except KeyError: pass else: session["conv"].trace.response("QUERY_STRING:%s" % qs) session["conv"].query_component = qs return oprp.opresult_fragment() if resp_c: # None in cases where no OIDC response is expected _ctype = resp_c.ctype # parse the response if response_mode == "form_post": info = parse_qs(get_post(environ)) _ctype = "dict" elif path == "authz_post": 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 = message_factory(resp_c.response) kwargs = { "algs": ots.client.sign_enc_algs("id_token"), "keyjar": ots.client.keyjar } if "issuer_mismatch" in ots.client.allow: kwargs["sender"] = ots.client.provider_info["issuer"] try: response = ots.client.parse_response( resp_cls, info, _ctype, conv.AuthorizationRequest["state"], **kwargs) 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) try: post_tests(conv, req_c, resp_c) except Exception as err: return oprp.err_response(session, "post_test", err) index += 1 try: return oprp.run_sequence(sequence_info, session, conv, ots, conv.trace, index) except Exception as err: return oprp.err_response(session, "run_sequence", err) else: resp = BadRequest() return resp(environ, start_response)
def application(self, environ, start_response): logger.info("Connection from: %s" % environ["REMOTE_ADDR"]) path = environ.get('PATH_INFO', '').lstrip('/') logger.info("path: %s" % path) _io = IO(rest=self.rest, environ=environ, start_response=start_response, lookup=self.lookup, baseurl=self.baseurl) if path == "robots.txt": return _io.static("static/robots.txt") elif path == "favicon.ico": return _io.static("static/favicon.ico") elif path.startswith("static/"): return _io.static(path) elif path.startswith("export/"): return _io.static(path) if path == '': return _io.main() if path == 'new': return _io.new_iss() if path == 'entity': return _io.list_iss() elif path.startswith('entity/'): p = path.split('/') while p[-1] == '': p = p[:-1] if len(p) == 2: return _io.list_tag(p[1]) elif len(p) == 3: return _io.show_tag(p) elif len(p) == 4: _com = p[-1] if _com == 'action': _qs = parse_qs(environ.get('QUERY_STRING')) try: _act = _qs['action'][0] except KeyError: resp = BadRequest('missing query parameter') return resp(environ, start_response) if _act == 'delete': return _io.delete_instance(p[1:3], pid=self.get_pid(p[1:3]), app=self) elif _act == 'restart': return _io.restart_instance(self, p[1:3]) elif _act == 'configure': return _io.update_instance(*p[1:3]) else: resp = BadRequest('Unknown action') return resp(environ, start_response) elif path.startswith('form/'): return self.form_handling(path, _io) elif path == 'create': loc = self.basic_entity_configuration(_io) resp = SeeOther(loc) return resp(_io.environ, _io.start_response) elif path.startswith('run/'): _iss, _tag = get_iss_and_tag(path) if _iss == '' or _tag == '': resp = BadRequest('Path must be of the form /run/<iss>/<tag>') return resp(environ, start_response) _qiss = quote_plus(_iss) _qtag = quote_plus(_tag) _info = parse_qs(get_post(environ)) ent_conf = expand_dict(_info) if not verify_config(ent_conf): resp = BadRequest('Incorrect configuration') else: self.rest.write(_qiss, _qtag, ent_conf) resp = self.run_test_instance(_qiss, _qtag) if not isinstance(resp, Response): resp = SeeOther(resp) return resp(_io.environ, _io.start_response) elif path.startswith('model/'): p = path.split('/') prof = p[1] if verify_profile(prof): info = create_model(prof) if info: res = Response(json.dumps(info), content='applicaton/json') else: res = ServiceError() else: res = BadRequest('Syntax error in profile specification') return res(environ, start_response) elif path.startswith('register/'): _iss, _tag = get_iss_and_tag(path) _qiss = quote_plus(_iss) _qtag = quote_plus(_tag) _met = environ.get('REQUEST_METHOD') if _met == 'GET': return self.assigned_ports.register_port(_qiss, _qtag) elif _met == 'DELETE': return self.return_port(_qiss, _qtag) else: # check if this a REST request _iss, _tag = get_iss_and_tag(path) _qiss = quote_plus(_iss) _qtag = quote_plus(_tag) _path = '/{}/{}'.format(_qiss, _qtag) _met = environ.get('REQUEST_METHOD') if _met == 'GET': resp = self.rest.read(_qiss, _qtag, _path) elif _met == 'POST': resp = self.rest.replace(_qiss, _qtag, get_post(environ), _path) elif _met == 'PUT': resp = self.rest.store(_qiss, _qtag, get_post(environ)) elif _met == 'DELETE': resp = self.rest.delete(_qiss, _qtag) else: resp = BadRequest('Unsupported request method') return resp(environ, start_response)
def application(self, environ, start_response): b_session = environ['beaker.session'] jlog = JLog(LOGGER, b_session.id) path = environ.get('PATH_INFO', '').lstrip('/') try: jlog.info({'cookie': environ['HTTP_COOKIE'].split(';'), 'path': path}) except KeyError: jlog.info({'path': path}) if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) elif '/static/' in path: pre, post = path.split('static') return static(environ, start_response, LOGGER, 'static' + post) query = parse_qs(environ["QUERY_STRING"]) try: session = b_session['session_info'] except KeyError: session = self.find_session(**query) if session: b_session['session_info'] = session else: session = {} b_session['session_info'] = session self.session[b_session.id] = session if path == '': if 'access_token' not in session: return opchoice(environ, start_response, self.clients) else: client = self.clients[session["op"]] # check_session_iframe_url = None try: # check_session_iframe_url = client.provider_info[ # "check_session_iframe"] session["session_management"] = { "session_state": query["session_state"][0], "client_id": client.client_id, "issuer": client.provider_info["issuer"] } except KeyError: pass kwargs = dict( [(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if p in session]) return opresult(environ, start_response, **kwargs) elif path == "rp": # After having chosen which OP to authenticate at if "uid" in query: try: client = self.clients.dynamic_client(userid=query["uid"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) elif 'issuer' in query: try: client = self.clients[query["issuer"][0]] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) else: client = self.clients[query["op"][0]] return self.init_client(client, session, query, environ, start_response) elif path.endswith('authz_post'): try: _iss = session['op'] except KeyError: jlog.error({'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR']}) return opchoice(environ, start_response, self.clients) else: client = self.clients[_iss] query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return sorry_response(environ, start_response, self.base, "missing fragment ?!") if info == ['x']: return sorry_response(environ, start_response, self.base, "Expected fragment didn't get one ?!") jlog.info({'fragment': info}) try: result = client.callback(info, session, 'urlencoded') if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception as err: raise else: session.update(result) res = SeeOther(self.conf['base_url']) return res(environ, start_response) elif path in self.clients.return_paths(): # After having # authenticated at the OP jlog.info({'query': query}) _client = None for cli in self.clients.client.values(): if query['state'][0] in cli.authz_req: _client = cli break if not _client: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR'], 'state': query['state'][0] }) return opchoice(environ, start_response, self.clients) if 'error' in query: # something amiss if query['error'][0] == 'access_denied': # Try reregistering _iss = _client.provider_info['issuer'] del self.clients[_iss] try: client = self.clients[_iss] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) return self.init_client(client, session, query, environ, start_response) try: _iss = query['iss'][0] except KeyError: pass else: if _iss != _client.provider_info['issuer']: jlog.error({'reason': 'Got response from wrong OP'}) return opchoice(environ, start_response, self.clients) _response_type = _client.behaviour["response_type"] try: _response_mode = _client.authz_req[session['state']][ 'response_mode'] except KeyError: _response_mode = '' jlog.info({ "response_type": _response_type, "response_mode": _response_mode}) if _response_type and _response_type != "code": # Fall through if it's a query response anyway if query: pass elif _response_mode: # form_post encoded pass else: return opresult_fragment(environ, start_response) try: result = _client.callback(query, session) if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception: raise else: session.update(result) res = SeeOther(self.conf['base_url']) return res(environ, start_response) elif path == "logout": # After the user has pressed the logout button try: _iss = session['op'] except KeyError: jlog.error( {'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR']}) return opchoice(environ, start_response, self.clients) client = self.clients[_iss] try: del client.authz_req[session['state']] except KeyError: pass logout_url = client.end_session_endpoint try: # Specify to which URL the OP should return the user after # log out. That URL must be registered with the OP at client # registration. logout_url += "?" + urlencode( {"post_logout_redirect_uri": client.registration_response[ "post_logout_redirect_uris"][0]}) except KeyError: pass else: # If there is an ID token send it along as a id_token_hint _idtoken = get_id_token(client, session) if _idtoken: logout_url += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt(client, _idtoken, "HS256")}) # Also append the ACR values logout_url += "&" + urlencode({"acr_values": self.acr_values}, True) session.delete() resp = SeeOther(str(logout_url)) return resp(environ, start_response) elif path == "logout_success": # post_logout_redirect_uri return Response("Logout successful!")(environ, start_response) elif path == "session_iframe": # session management kwargs = session["session_management"] resp = Response(mako_template="rp_session_iframe.mako", template_lookup=LOOKUP) return resp(environ, start_response, session_change_url="{}session_change".format( self.conf["base_url"]), **kwargs) elif path == "session_change": try: _iss = session['op'] except KeyError: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR']}) return opchoice(environ, start_response, self.clients) try: client = self.clients[_iss] except KeyError: return Response("No valid session.")(environ, start_response) kwargs = {"prompt": "none"} # If there is an ID token send it along as a id_token_hint idt = get_id_token(client, session) if idt: kwargs["id_token_hint"] = id_token_as_signed_jwt(client, idt, "HS256") resp = client.create_authn_request(session, self.acr_values, **kwargs) return resp(environ, start_response) return opchoice(environ, start_response, self.clients)
def application(environ, start_response): LOGGER.info("Connection from: %s" % environ["REMOTE_ADDR"]) session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') LOGGER.info("path: %s" % path) oprp = UMAoprp(**RP_ARGS) oprp.environ = environ oprp.start_response = start_response if path == "robots.txt": return oprp.static("static/robots.txt") elif path == "favicon.ico": return oprp.static("static/favicon.ico") if path.startswith("static/"): return oprp.static(path) if path.startswith("export/"): return oprp.static(path) if path == "": # list try: if oprp.session_init(session): return oprp.flow_list(session) else: try: resp = Redirect("%sopresult#%s" % ( oprp.conf.BASE, session["testid"][0])) except KeyError: return oprp.flow_list(session) else: return resp(environ, start_response) except Exception as err: return oprp.err_response(session, "session_setup", err) elif path == "logs": return oprp.display_log("log", "log") elif path.startswith("log"): if path == "log": path = os.path.join( path, quote_plus(oprp.conf.CLIENT["srv_discovery_url"])) tail = path else: head, tail = os.path.split(path) return oprp.display_log(path, tail) elif "flow_names" not in session: oprp.session_init(session) if path == "reset": oprp.reset_session(session) return oprp.flow_list(session) elif path == "pedit": return oprp.profile_edit(session) elif path == "profile": info = parse_qs(get_post(environ)) cp = session["profile"].split(".") cp[0] = info["rtype"][0] crsu = [] for name, cs in CRYPTSUPPORT.items(): try: if info[name] == ["on"]: crsu.append(cs) except KeyError: pass if len(cp) == 3: if len(crsu) == 3: pass else: cp.append("".join(crsu)) else: # len >= 4 cp[3] = "".join(crsu) try: if info["extra"] == ['on']: if len(cp) == 3: cp.extend(["", "+"]) elif len(cp) == 4: cp.append("+") elif len(cp) == 5: cp[4] = "+" else: if len(cp) == 5: cp = cp[:-1] except KeyError: if len(cp) == 5: cp = cp[:-1] # reset all testsflows oprp.reset_session(session, ".".join(cp)) return oprp.flow_list(session) elif path.startswith("test_info"): p = path.split("/") try: return oprp.test_info(p[1], session) except KeyError: return oprp.not_found() elif path == "continue": try: sequence_info = session["seq_info"] except KeyError: # Cookie delete broke session query = parse_qs(environ["QUERY_STRING"]) path = query["path"][0] index = int(query["index"][0]) conv, sequence_info, ots, trace, index = oprp.session_setup( session, path, index) try: conv.cache_key = query["key"][0] except KeyError: pass except Exception as err: return oprp.err_response(session, "session_setup", err) else: index = session["index"] ots = session["ots"] conv = session["conv"] index += 1 try: return oprp.run_sequence(sequence_info, session, conv, ots, conv.trace, index) except Exception, err: return oprp.err_response(session, "run_sequence", err)
def _key_rollover(self): # expects a post containing the necessary information _jwks = json.loads(get_post(request.environ)) self.provider.do_key_rollover(_jwks, "key_%d_%%d" % int(time.time())) return Response("OK")
exception_trace("run_sequence", err, trace) return test_error(environ, start_response, conv, err) else: if path != "authz_post": if not session["response_type"] == ["code"]: return opresult_fragment(environ, start_response, session) sequence_info = session["seq_info"] index = session["index"] ots = session["ots"] conv = session["conv"] req_c, resp_c = sequence_info["sequence"][index] if resp_c: # None in cases where no OIDC response is expected # parse the response if path == "authz_post": query = parse_qs(get_post(environ)) info = query["fragment"][0] elif resp_c.where == "url": info = environ["QUERY_STRING"] else: # resp_c.where == "body" info = get_post(environ) LOGGER.info("Response: %s" % info) resp_cls = factory(resp_c.response) response = ots.client.parse_response(resp_cls, info, resp_c.ctype, session["state"], keyjar=ots.client.keyjar) LOGGER.info("Parsed response: %s" % response.to_dict())
def application(environ, start_response): session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') try: _cli = session["client"] except KeyError: _cli = session["client"] = Client( client_authn_method=CLIENT_AUTHN_METHOD, keyjar=KEYJAR) _cli.kid = KIDD #_cli.allow["issuer_mismatch"] = True _cli.jwks_uri = JWKS_URI for arg, val in CONF.CLIENT_INFO.items(): setattr(_cli, arg, val) session["done"] = [] if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) elif path.startswith("export/"): return static(environ, start_response, LOGGER, path) if path == "": # list return flow_list(environ, start_response, FLOWS.FLOWS, session["done"]) elif path in FLOWS.FLOWS.keys(): session["flow"] = FLOWS.FLOWS[path] session["index"] = 0 session["item"] = path session["test_id"] = path try: resp = run_flow(_cli, session["index"], session, path) except Exception as err: resp = ServiceError("%s" % err) return resp(environ, start_response) else: if resp: return resp(environ, start_response) else: return flow_list(environ, start_response, FLOWS.FLOWS, session["done"]) elif path in ["authz_cb", "authz_post"]: if path != "authz_post": args = session["flow"]["flow"][session["index"]-1]["args"] if args["response_type"] != ["code"]: return opresult_fragment(environ, start_response) # Got a real Authn response ctype = "urlencoded" if path == "authz_post": query = parse_qs(get_post(environ)) info = query["fragment"][0] else: info = environ["QUERY_STRING"] LOGGER.info("Response: %s" % info) try: _cli = session["client"] response = _cli.parse_response(AuthorizationResponse, info, ctype, session["state"], keyjar=_cli.keyjar) except ResponseError as err: LOGGER.error("%s" % err) resp = ServiceError("%s" % err) return resp(environ, start_response) except Exception as err: _spec = session["flow"]["flow"][session["index"]-1] try: assert isinstance(err, _spec["error"]) except KeyError: raise else: pass try: resp = run_flow(_cli, session["index"], session, session["test_id"]) except Exception as err: LOGGER.error("%s" % err) resp = ServiceError("%s" % err) return resp(environ, start_response) else: if resp: return resp(environ, start_response) else: return flow_list(environ, start_response, FLOWS.FLOWS, session["done"]) else: LOGGER.debug("unknown side: %s" % path) resp = NotFound("Couldn't find the side you asked for!") return resp(environ, start_response)
def parse_response(self, path, io, message_factory): _ctype = self.response_type _conv = self.conv if self.csi is None: url, body, ht_args, csi = _conv.entity.request_info( self.request, method=self.method, request_args=self.req_args, **self.op_args) self.csi = csi try: response_mode = self.csi["response_mode"] except KeyError: response_mode = None if self.request_cls == "AuthorizationRequest": try: _rt = self.csi["response_type"] except KeyError: response_where = "" else: if _rt == ["code"]: response_where = "url" elif _rt == [""]: response_where = "" else: response_where = "fragment" else: response_where = self.response_where # parse the response if response_mode == "form_post": info = parse_qs(get_post(io.environ)) _ctype = "dict" elif response_where == "url": info = io.environ["QUERY_STRING"] _ctype = "urlencoded" elif response_where == "fragment": query = parse_qs(get_post(io.environ)) try: info = query["fragment"][0] except KeyError: return io.sorry_response(io.conf.BASE, "missing fragment ?!") elif response_where == "": info = io.environ["QUERY_STRING"] _ctype = "urlencoded" else: # resp_c.where == "body" info = get_post(io.environ) logger.info("Response: %s" % info) _conv.trace.reply(info) ev_index = _conv.events.store('reply', info) resp_cls = message_factory(self.response_cls) algs = _conv.entity.sign_enc_algs("id_token") try: response = _conv.entity.parse_response( resp_cls, info, _ctype, self.csi["state"], keyjar=_conv.entity.keyjar, algs=algs) except ResponseError as err: return io.err_response(self.sh.session, "run_sequence", err) except Exception as err: return io.err_response(self.sh.session, "run_sequence", err) logger.info("Parsed response: %s" % response.to_dict()) _conv.trace.response(response) _conv.events.store('response', response, ref=ev_index) if self.expect_error: self.expected_error_response(response) else: if isinstance(response, ErrorResponse): raise Break("Unexpected error response")
def key_rollover(environ, start_response, _): # expects a post containing the necessary information _jwks = json.loads(get_post(environ)) OAS.do_key_rollover(_jwks, "key_%d_%%d" % int(time.time())) resp = Response("OK") return resp(environ, start_response)
def application(environ, start_response): session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') try: _cli = session["client"] except KeyError: _cli = session["client"] = Client( client_authn_method=CLIENT_AUTHN_METHOD, keyjar=KEYJAR) _cli.kid = KIDD #_cli.allow["issuer_mismatch"] = True _cli.jwks_uri = JWKS_URI for arg, val in CONF.CLIENT_INFO.items(): setattr(_cli, arg, val) session["done"] = [] if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) elif path.startswith("export/"): return static(environ, start_response, LOGGER, path) if path == "": # list return flow_list(environ, start_response, FLOWS.FLOWS, session["done"]) elif path in FLOWS.FLOWS.keys(): session["flow"] = FLOWS.FLOWS[path] session["index"] = 0 session["item"] = path session["test_id"] = path try: resp = run_flow(_cli, session["index"], session, path) except Exception as err: resp = ServiceError("%s" % err) return resp(environ, start_response) else: if resp: return resp(environ, start_response) else: return flow_list(environ, start_response, FLOWS.FLOWS, session["done"]) elif path in ["authz_cb", "authz_post"]: if path != "authz_post": args = session["flow"]["flow"][session["index"] - 1]["args"] if args["response_type"] != ["code"]: return opresult_fragment(environ, start_response) # Got a real Authn response ctype = "urlencoded" if path == "authz_post": query = parse_qs(get_post(environ)) info = query["fragment"][0] else: info = environ["QUERY_STRING"] LOGGER.info("Response: %s" % info) try: _cli = session["client"] response = _cli.parse_response(AuthorizationResponse, info, ctype, session["state"], keyjar=_cli.keyjar) except ResponseError as err: LOGGER.error("%s" % err) resp = ServiceError("%s" % err) return resp(environ, start_response) except Exception as err: _spec = session["flow"]["flow"][session["index"] - 1] try: assert isinstance(err, _spec["error"]) except KeyError: raise else: pass try: resp = run_flow(_cli, session["index"], session, session["test_id"]) except Exception as err: LOGGER.error("%s" % err) resp = ServiceError("%s" % err) return resp(environ, start_response) else: if resp: return resp(environ, start_response) else: return flow_list(environ, start_response, FLOWS.FLOWS, session["done"]) else: LOGGER.debug("unknown side: %s" % path) resp = NotFound("Couldn't find the side you asked for!") return resp(environ, start_response)
def application(environ, start_response): LOGGER.info("Connection from: %s" % environ["REMOTE_ADDR"]) session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') LOGGER.info("path: %s" % path) oprp = OPRP(**RP_ARGS) oprp.environ = environ oprp.start_response = start_response if path == "robots.txt": return oprp.static("static/robots.txt") elif path == "favicon.ico": return oprp.static("static/favicon.ico") elif path.startswith("static/"): return oprp.static(path) elif path.startswith("export/"): return oprp.static(path) if path == "": # list try: if oprp.session_init(session): return oprp.flow_list(session) else: try: resp = Redirect("%sopresult#%s" % ( oprp.conf.BASE, session["testid"][0])) except KeyError: return oprp.flow_list(session) else: return resp(environ, start_response) except Exception as err: return oprp.err_response(session, "session_setup", err) elif path == "logs": return oprp.display_log("log", issuer="", profile="", testid="") elif path.startswith("log"): if path == "log" or path == "log/": _cc = oprp.conf.CLIENT try: _iss = _cc["srv_discovery_url"] except KeyError: _iss = _cc["provider_info"]["issuer"] parts = [quote_plus(_iss)] else: parts = [] while path != "log": head, tail = os.path.split(path) # tail = tail.replace(":", "%3A") # if tail.endswith("%2F"): # tail = tail[:-3] parts.insert(0, tail) path = head return oprp.display_log("log", *parts) elif path.startswith("tar"): path = path.replace(":", "%3A") return oprp.static(path) elif "flow_names" not in session: oprp.session_init(session) if path == "reset": oprp.reset_session(session) return oprp.flow_list(session) elif path == "pedit": try: return oprp.profile_edit(session) except Exception as err: return oprp.err_response(session, "pedit", err) elif path == "profile": info = parse_qs(get_post(environ)) try: cp = session["profile"].split(".") cp[0] = info["rtype"][0] crsu = [] for name, cs in list(CRYPTSUPPORT.items()): try: if info[name] == ["on"]: crsu.append(cs) except KeyError: pass if len(cp) == 3: if len(crsu) == 3: pass else: cp.append("".join(crsu)) else: # len >= 4 cp[3] = "".join(crsu) try: if info["extra"] == ['on']: if len(cp) == 3: cp.extend(["", "+"]) elif len(cp) == 4: cp.append("+") elif len(cp) == 5: cp[4] = "+" else: if len(cp) == 5: cp = cp[:-1] except KeyError: if len(cp) == 5: cp = cp[:-1] # reset all test flows oprp.reset_session(session, ".".join(cp)) return oprp.flow_list(session) except Exception as err: return oprp.err_response(session, "profile", err) elif path.startswith("test_info"): p = path.split("/") try: return oprp.test_info(p[1], session) except KeyError: return oprp.not_found() elif path == "continue": try: sequence_info = session["seq_info"] except KeyError: # Cookie delete broke session query = parse_qs(environ["QUERY_STRING"]) path = query["path"][0] index = int(query["index"][0]) conv, sequence_info, ots, trace, index = oprp.session_setup( session, path, index) try: conv = RP_ARGS["cache"][query["ckey"][0]] except KeyError: pass else: ots.client = conv.client session["conv"] = conv except Exception as err: return oprp.err_response(session, "session_setup", err) else: index = session["index"] ots = session["ots"] conv = session["conv"] index += 1 try: return oprp.run_sequence(sequence_info, session, conv, ots, conv.trace, index) except Exception as err: return oprp.err_response(session, "run_sequence", err) elif path == "opresult": try: conv = session["conv"] except KeyError as err: homepage = "" return oprp.sorry_response(homepage, err) return oprp.opresult(conv, session) # expected path format: /<testid>[/<endpoint>] elif path in session["flow_names"]: LOGGER.info("<=<=<=<=< %s >=>=>=>=>" % path) conv, sequence_info, ots, trace, index = oprp.session_setup(session, path) session["node"].complete = False try: return oprp.run_sequence(sequence_info, session, conv, ots, trace, index) except Exception as err: return oprp.err_response(session, "run_sequence", err) elif path in ["authz_cb", "authz_post"]: try: sequence_info = session["seq_info"] index = session["index"] ots = session["ots"] conv = session["conv"] except KeyError as err: # Todo: find out which port I'm listening on return oprp.sorry_response(oprp.conf.BASE, err) (req_c, resp_c), _ = sequence_info["sequence"][index] try: response_mode = conv.AuthorizationRequest["response_mode"] except KeyError: response_mode = None if path == "authz_cb": if response_mode == "form_post": pass elif session["response_type"] and not \ session["response_type"] == ["code"]: # but what if it's all returned as a query ? try: qs = environ["QUERY_STRING"] except KeyError: pass else: session["conv"].trace.response("QUERY_STRING:%s" % qs) session["conv"].query_component = qs return oprp.opresult_fragment() if resp_c: # None in cases where no OIDC response is expected _ctype = resp_c.ctype # parse the response if response_mode == "form_post": info = parse_qs(get_post(environ)) _ctype = "dict" elif path == "authz_post": 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 = message_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) try: post_tests(conv, req_c, resp_c) except Exception as err: return oprp.err_response(session, "post_test", err) index += 1 try: return oprp.run_sequence(sequence_info, session, conv, ots, conv.trace, index) except Exception as err: return oprp.err_response(session, "run_sequence", err) else: resp = BadRequest() return resp(environ, start_response)
def application(self, environ, start_response): logger.info("Connection from: %s" % environ["REMOTE_ADDR"]) path = environ.get('PATH_INFO', '').lstrip('/') logger.info("path: %s" % path) _io = IO(rest=self.rest, environ=environ, start_response=start_response, lookup=self.lookup) if path == "robots.txt": return _io.static("static/robots.txt") elif path == "favicon.ico": return _io.static("static/favicon.ico") elif path.startswith("static/"): return _io.static(path) elif path.startswith("export/"): return _io.static(path) if path == '': return _io.get_iss() elif path.startswith('form/'): return self.form_handling(path, _io) elif path == 'create': loc = self.basic_entity_configuration(_io) resp = SeeOther(loc) return resp(_io.environ, _io.start_response) elif path.startswith('run/'): _iss, _tag = get_iss_and_tag(path) if _iss == '' or _tag == '': resp = BadRequest('Path must be of the form /run/<iss>/<tag>') return resp(environ, start_response) _qiss = quote_plus(_iss) _qtag = quote_plus(_tag) _info = parse_qs(get_post(environ)) ent_conf = expand_dict(_info) self.rest.write(_qiss, _qtag, ent_conf) resp = self.run_test_instance(_qiss, _qtag) if not isinstance(resp, Response): resp = SeeOther(resp) return resp(_io.environ, _io.start_response) elif path.startswith('model/'): p = path.split('/') prof = p[1] if verify_profile(prof): info = create_model(prof) if info: res = Response(json.dumps(info), content='applicaton/json') else: res = ServiceError() else: res = BadRequest('Syntax error in profile specification') return res(environ, start_response) else: # check if this a REST request _iss, _tag = get_iss_and_tag(path) _qiss = quote_plus(_iss) _qtag = quote_plus(_tag) _path = '/{}/{}'.format(_qiss, _qtag) _met = environ.get('REQUEST_METHOD') if _met == 'GET': resp = self.rest.read(_qiss, _qtag, _path) elif _met == 'POST': resp = self.rest.replace(_qiss, _qtag, get_post(environ), _path) elif _met == 'PUT': resp = self.rest.store(_qiss, _qtag, get_post(environ)) elif _met == 'DELETE': resp = self.rest.delete(_qiss, _qtag) else: resp = BadRequest('Unsupported request method') return resp(environ, start_response)
def application(environ, start_response): LOGGER.info("Connection from: %s" % environ["REMOTE_ADDR"]) session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') LOGGER.info("path: %s" % path) oprp = GSMAoprp(**RP_ARGS) oprp.environ = environ oprp.start_response = start_response if path == "robots.txt": return oprp.static("static/robots.txt") elif path == "favicon.ico": return oprp.static("static/favicon.ico") if path.startswith("static/"): return oprp.static(path) if path.startswith("export/"): return oprp.static(path) if path == "": # list try: if oprp.session_init(session): return oprp.flow_list(session) else: try: resp = Redirect("%sopresult#%s" % ( oprp.conf.BASE, session["testid"][0])) except KeyError: return oprp.flow_list(session) else: return resp(environ, start_response) except Exception as err: return oprp.err_response(session, "session_setup", err) elif path == "logs": return oprp.display_log("log", "log") elif path.startswith("log"): if path == "log": try: _id = oprp.conf.CLIENT["srv_discovery_url"] except KeyError: _id = oprp.conf.CLIENT["service_id"] path = os.path.join(path, quote_plus(_id)) tail = path else: head, tail = os.path.split(path) return oprp.display_log(path, tail) elif "flow_names" not in session: oprp.session_init(session) if path == "reset": oprp.reset_session(session) return oprp.flow_list(session) elif path == "pedit": return oprp.profile_edit(session) elif path == "profile": info = parse_qs(get_post(environ)) cp = session["profile"].split(".") cp[0] = info["rtype"][0] crsu = [] for name, cs in CRYPTSUPPORT.items(): try: if info[name] == ["on"]: crsu.append(cs) except KeyError: pass if len(cp) == 3: if len(crsu) == 3: pass else: cp.append("".join(crsu)) else: # len >= 4 cp[3] = "".join(crsu) try: if info["extra"] == ['on']: if len(cp) == 3: cp.extend(["", "+"]) elif len(cp) == 4: cp.append("+") elif len(cp) == 5: cp[4] = "+" else: if len(cp) == 5: cp = cp[:-1] except KeyError: if len(cp) == 5: cp = cp[:-1] # reset all testsflows oprp.reset_session(session, ".".join(cp)) return oprp.flow_list(session) elif path.startswith("test_info"): p = path.split("/") try: return oprp.test_info(p[1], session) except KeyError: return oprp.not_found() elif path == "continue": try: sequence_info = session["seq_info"] except KeyError: # Cookie delete broke session query = parse_qs(environ["QUERY_STRING"]) path = query["path"][0] index = int(query["index"][0]) conv, sequence_info, ots, trace, index = oprp.session_setup( session, path, index) try: conv.cache_key = query["key"][0] except KeyError: pass except Exception as err: return oprp.err_response(session, "session_setup", err) else: index = session["index"] ots = session["ots"] conv = session["conv"] index += 1 try: return oprp.run_sequence(sequence_info, session, conv, ots, conv.trace, index) except Exception, err: return oprp.err_response(session, "run_sequence", err)
qs = environ["QUERY_STRING"] except KeyError: qs = "" if qs: session["conv"].trace.response("QUERY_STRING:%s" % qs) session["conv"].info( "Didn't expect response as query parameters") return oprp.opresult_fragment() if resp_c: # None in cases where no OIDC response is expected _ctype = resp_c.ctype # parse the response if response_mode == "form_post": info = parse_qs(get_post(environ)) _ctype = "dict" elif path == "authz_post": 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)
def application(self, environ, start_response): logger.info("Connection from: %s" % environ["REMOTE_ADDR"]) session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') logger.info("path: %s" % path) self.events.store(EV_REQUEST, path) try: sh = session['session_info'] except KeyError: sh = SessionHandler(**self.kwargs) sh.session_init() session['session_info'] = sh inut = WebIO(session=sh, **self.kwargs) inut.environ = environ inut.start_response = start_response tester = WebTester(inut, sh, **self.kwargs) if path == "robots.txt": return static_mime("static/robots.txt", environ, start_response) elif path.startswith("static/"): return static_mime(path, environ, start_response) elif path == "list": try: qs = parse_qs(get_post(environ)) except Exception as err: pass else: sh['test_conf'] = dict([(k, v[0]) for k, v in qs.items()]) self.session_conf[sh['sid']] = sh return tester.display_test_list() elif path == '' or path == 'config': sid = rndstr(24) sh['sid'] = sid try: args = sh['test_conf'] except: args = {} return tester.do_config(sid, **args) elif path in self.kwargs['flows'].keys(): # Run flow try: _ = tester.sh['test_conf'] except KeyError: resp = SeeOther('/') return resp(environ, start_response) try: _sid = tester.sh['sid'] except KeyError: _sid = rndstr(24) tester.sh['sid'] = _sid self.session_conf[_sid] = sh resp = tester.run(path, sid=_sid, **self.kwargs) if isinstance(resp, requests.Response): loc = resp.headers['location'] #tester.conv.events.store('Cookie', resp.headers['set-cookie']) if loc.startswith(tester.base_url): path = loc[len(tester.base_url):] else: return resp elif resp is True or resp is False or resp is None: return tester.display_test_list() else: return resp(environ, start_response) elif path == 'display': return inut.flow_list() elif path == "opresult": resp = SeeOther("/display#{}".format( self.pick_grp(sh['conv'].test_id))) return resp(environ, start_response) elif path.startswith("test_info"): p = path.split("/") try: return inut.test_info(p[1]) except KeyError: return inut.not_found() elif path == 'all': for test_id in sh['flow_names']: resp = tester.run(test_id, **self.kwargs) if resp is True or resp is False: continue elif resp: return resp(environ, start_response) else: resp = ServiceError('Unkown service error') return resp(environ, start_response) return tester.display_test_list() # Whatever gets here should be of the form <session_id>/<path> try: sid, _path = path.split('/', 1) except ValueError: pass else: if _path.startswith("static/"): return static_mime(_path, environ, start_response) try: _sh = self.session_conf[sid] except KeyError: resp = ServiceError("Unknown session") return resp(environ, start_response) tester.sh = _sh if 'HTTP_AUTHORIZATION' in environ: _sh['conv'].events.store('HTTP_AUTHORIZATION', environ['HTTP_AUTHORIZATION']) _p = _path.split('?') if _p[0] in _sh['conv'].entity.endpoints(): resp = self.handle(environ, tester, sid, *_p) self.session_conf[sid] = tester.sh return resp(environ, start_response) for endpoint, service in self.endpoints.items(): if _path == endpoint: logger.info("service: {}".format(service)) try: resp = self.handle(environ, tester, sid, service) return resp(environ, start_response) except Exception as err: print("%s" % err) message = traceback.format_exception(*sys.exc_info()) print(message) logger.exception("%s" % err) resp = ServiceError("%s" % err) return resp(environ) logger.debug("unknown side: %s" % path) resp = NotFound("Couldn't find the side you asked for!") return resp(environ, start_response)
def parse_response(self, path, inut, message_factory): _ctype = self.response_type _conv = self.conv if self.csi is None: url, body, ht_args, csi = _conv.entity.request_info( self.request, method=self.method, request_args=self.req_args, **self.op_args) self.csi = csi try: response_mode = self.csi["response_mode"] except KeyError: response_mode = None if self.request_cls == "AuthorizationRequest": try: _rt = self.csi["response_type"] except KeyError: response_where = "" else: if _rt == ["code"]: response_where = "url" elif _rt == [""]: response_where = "" else: response_where = "fragment" else: response_where = self.response_where # parse the response if response_mode == "form_post": info = parse_qs(get_post(inut.environ)) _ctype = "dict" elif response_where == "url": info = inut.environ["QUERY_STRING"] _ctype = "urlencoded" elif response_where == "fragment": query = parse_qs(get_post(inut.environ)) try: info = query["fragment"][0] except KeyError: return inut.sorry_response(inut.conf.BASE, "missing fragment ?!") elif response_where == "": info = inut.environ["QUERY_STRING"] _ctype = "urlencoded" else: # resp_c.where == "body" info = get_post(inut.environ) logger.info("Response: %s" % info) _conv.trace.reply(info) ev_index = _conv.events.store(EV_RESPONSE, info, sender=self.__class__.__name__) resp_cls = message_factory(self.response_cls) algs = _conv.entity.sign_enc_algs("id_token") try: response = _conv.entity.parse_response(resp_cls, info, _ctype, self.csi["state"], keyjar=_conv.entity.keyjar, algs=algs) except ResponseError as err: return inut.err_response("run_sequence", err) except Exception as err: return inut.err_response("run_sequence", err) logger.info("Parsed response: %s" % response.to_dict()) _conv.trace.response(response) _conv.events.store(EV_PROTOCOL_RESPONSE, response, ref=ev_index, sender=self.__class__.__name__) if self.expect_error: self.expected_error_response(response) else: if isinstance(response, ErrorResponse): raise Break("Unexpected error response")
def application(environ, start_response): session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) elif '/static/' in path: pre, post = path.split('static') return static(environ, start_response, LOGGER, 'static' + post) query = parse_qs(environ["QUERY_STRING"]) acr_values = session._params['acrs'] clients = session._params['clients'] server_env = session._params['server_env'] LOGGER.info(50 * "=") LOGGER.info("[{}] path: {}".format(session.id, path)) LOGGER.info(50 * "=") if path == '': if 'access_token' not in session: return opchoice(environ, start_response, clients) else: client = clients[session["op"]] # check_session_iframe_url = None try: # check_session_iframe_url = client.provider_info[ # "check_session_iframe"] session["session_management"] = { "session_state": query["session_state"][0], "client_id": client.client_id, "issuer": client.provider_info["issuer"] } except KeyError: pass kwargs = dict([(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if p in session]) return opresult(environ, start_response, **kwargs) elif path == "rp": # After having chosen which OP to authenticate at if "uid" in query: try: client = clients.dynamic_client(userid=query["uid"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) elif 'issuer' in query: try: client = clients[query["issuer"][0]] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) else: client = clients[query["op"][0]] client.get_userinfo = session._params['userinfo'] try: client.resource_server = session._params['resource_server'] except KeyError: pass try: session['response_format'] = query["response_format"][0] except KeyError: session['response_format'] = 'html' session["op"] = client.provider_info["issuer"] try: resp = client.create_authn_request(session, acr_values) except Exception as err: logging.error(err) raise else: return resp(environ, start_response) elif path.endswith('authz_post'): try: _iss = session['op'] except KeyError: LOGGER.info('[{}] No active session with {}'.format( session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) else: client = clients[_iss] query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return sorry_response(environ, start_response, conf.BASE, "missing fragment ?!") if info == ['x']: return sorry_response(environ, start_response, conf.BASE, "Expected fragment didn't get one ?!") LOGGER.info('[{}] Fragment part: {}'.format(session.id, info)) try: result = client.callback(info, session, 'urlencoded') if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception as err: raise else: session.update(result) res = SeeOther(server_env['base_url']) return res(environ, start_response) elif path in clients.return_paths( ): # After having authenticated at the OP try: _iss = session['op'] except KeyError: LOGGER.info('[{}]No active session with {}'.format( session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) # mismatch between callback and return_uri # ignore trailing '/' if not url_eq(_iss, clients.path[path]): LOGGER.warning('[{}]issuer mismatch: {} != {}'.format( session.id, _iss, clients.path[path])) return operror(environ, start_response, "%s" % 'Not allowed') client = clients[clients.path[path]] _response_type = client.behaviour["response_type"] try: _response_mode = client.authz_req[ session['state']]['response_mode'] except KeyError: _response_mode = '' LOGGER.info("[{}]response_type: {}, response_mode: {}".format( session.id, _response_type, _response_mode)) if _response_type and _response_type != "code": # Fall through if it's a query response anyway if query: pass elif _response_mode: # form_post encoded pass else: return opresult_fragment(environ, start_response) LOGGER.info("[{}]Query part: {}".format(session.id, query)) try: result = client.callback(query, session) if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception: raise else: session.update(result) res = SeeOther(server_env['base_url']) return res(environ, start_response) elif path == "logout": # After the user has pressed the logout button try: _iss = session['op'] except KeyError: LOGGER.info('[{}]No active session with {}'.format( session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) client = clients[_iss] try: del client.authz_req[session['state']] except KeyError: pass logout_url = client.end_session_endpoint try: # Specify to which URL the OP should return the user after # log out. That URL must be registered with the OP at client # registration. logout_url += "?" + urlencode({ "post_logout_redirect_uri": client.registration_response["post_logout_redirect_uris"][0] }) except KeyError: pass else: # If there is an ID token send it along as a id_token_hint _idtoken = get_id_token(client, session) if _idtoken: logout_url += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt(client, _idtoken, "HS256") }) # Also append the ACR values logout_url += "&" + urlencode({"acr_values": acr_values}, True) LOGGER.debug("[{}]Logout URL: {}".format(session.id, logout_url)) LOGGER.debug("Logging out from session: [{}]".format(session.id)) session.delete() resp = SeeOther(str(logout_url)) return resp(environ, start_response) elif path == "logout_success": # post_logout_redirect_uri return Response("Logout successful!")(environ, start_response) elif path == "session_iframe": # session management kwargs = session["session_management"] resp = Response(mako_template="rp_session_iframe.mako", template_lookup=LOOKUP) return resp(environ, start_response, session_change_url="{}session_change".format( server_env["base_url"]), **kwargs) elif path == "session_change": try: _iss = session['op'] except KeyError: LOGGER.info('[{}]No active session with {}'.format( session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) try: client = clients[_iss] except KeyError: return Response("No valid session.")(environ, start_response) kwargs = {"prompt": "none"} # If there is an ID token send it along as a id_token_hint idt = get_id_token(client, session) if idt: kwargs["id_token_hint"] = id_token_as_signed_jwt( client, idt, "HS256") resp = client.create_authn_request(session, acr_values, **kwargs) return resp(environ, start_response) return opchoice(environ, start_response, clients)
def application(environ, start_response): session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) query = parse_qs(environ["QUERY_STRING"]) acr_values = session._params['acrs'] clients = session._params['clients'] server_env = session._params['server_env'] LOGGER.info(50 * "=") LOGGER.info("[{}] path: {}".format(session.id, path)) LOGGER.info(50 * "=") if path == '': if 'access_token' not in session: return opchoice(environ, start_response, clients) else: client = clients[session["op"]] check_session_iframe_url = None try: check_session_iframe_url = client.provider_info[ "check_session_iframe"] session["session_management"] = { "session_state": query["session_state"][0], "client_id": client.client_id, "issuer": client.provider_info["issuer"] } except KeyError: pass kwargs = dict( [(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if p in session]) return opresult(environ, start_response, **kwargs) elif path == "rp": # After having chosen which OP to authenticate at if "uid" in query: try: client = clients.dynamic_client(userid=query["uid"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) elif 'issuer' in query: try: client = clients[query["issuer"][0]] except KeyError: try: client = clients.dynamic_client(issuer=query["issuer"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) else: client = clients[query["op"][0]] client.get_userinfo = session._params['userinfo'] try: client.resource_server = session._params['resource_server'] except KeyError: pass try: session['response_format'] = query["response_format"][0] except KeyError: session['response_format'] = 'html' session["op"] = client.provider_info["issuer"] try: resp = client.create_authn_request(session, acr_values) except Exception: raise else: return resp(environ, start_response) elif path.endswith('authz_post'): try: _iss = session['op'] except KeyError: LOGGER.info( '[{}] No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) else: client = clients[_iss] query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return sorry_response(environ, start_response, conf.BASE, "missing fragment ?!") if info == ['x']: return sorry_response(environ, start_response, conf.BASE, "Expected fragment didn't get one ?!") LOGGER.info('[{}] Fragment part: {}'.format(session.id, info)) try: result = client.callback(info, session, 'urlencoded') if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception as err: raise else: session.update(result) res = SeeOther(location=server_env['base_url']) return res(environ, start_response) elif path in clients.return_paths(): # After having authenticated at the OP try: _iss = session['op'] except KeyError: LOGGER.info( '[{}]No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) # mismatch between callback and return_uri if _iss != clients.path[path]: LOGGER.warning( '[{}]issuer mismatch: {} != {}'.format(session.id, _iss, clients.path[path])) return operror(environ, start_response, "%s" % 'Not allowed') client = clients[session["op"]] _response_type = client.behaviour["response_type"] try: _response_mode = client.authz_req[session['state']]['response_mode'] except KeyError: _response_mode = '' LOGGER.info( "[{}]response_type: {}, response_mode: {}".format(session.id, _response_type, _response_mode)) if _response_type and _response_type != "code": # Fall through if it's a query response anyway if query: pass elif _response_mode: # form_post encoded pass else: return opresult_fragment(environ, start_response) LOGGER.info("[{}]Query part: {}".format(session.id, query)) try: result = client.callback(query, session) if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception: raise else: session.update(result) res = SeeOther(server_env['base_url']) return res(environ, start_response) elif path == "logout": # After the user has pressed the logout button try: _iss = session['op'] except KeyError: LOGGER.info( '[{}]No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) client = clients[_iss] try: del client.authz_req[session['state']] except KeyError: pass logout_url = client.end_session_endpoint try: # Specify to which URL the OP should return the user after # log out. That URL must be registered with the OP at client # registration. logout_url += "?" + urlencode( {"post_logout_redirect_uri": client.registration_response[ "post_logout_redirect_uris"][0]}) except KeyError: pass else: # If there is an ID token send it along as a id_token_hint _idtoken = get_id_token(client, session) if _idtoken: logout_url += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt(client, _idtoken, "HS256")}) # Also append the ACR values logout_url += "&" + urlencode({"acr_values": acr_values}, True) LOGGER.debug("[{}]Logout URL: {}".format(session.id, logout_url)) LOGGER.debug("Logging out from session: [{}]".format(session.id)) session.delete() resp = SeeOther(str(logout_url)) return resp(environ, start_response) elif path == "logout_success": # post_logout_redirect_uri return Response("Logout successful!")(environ, start_response) elif path == "session_iframe": # session management kwargs = session["session_management"] resp = Response(mako_template="rp_session_iframe.mako", template_lookup=LOOKUP) return resp(environ, start_response, session_change_url="{}session_change".format( server_env["base_url"]), **kwargs) elif path == "session_change": try: _iss = session['op'] except KeyError: LOGGER.info( '[{}]No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) try: client = clients[_iss] except KeyError: return Response("No valid session.")(environ, start_response) kwargs = {"prompt": "none"} # If there is an ID token send it along as a id_token_hint idt = get_id_token(client, session) if idt: kwargs["id_token_hint"] = id_token_as_signed_jwt(client, idt, "HS256") resp = client.create_authn_request(session, acr_values, **kwargs) return resp(environ, start_response) return opchoice(environ, start_response, clients)
def application(self, environ, start_response): b_session = environ['beaker.session'] jlog = JLog(LOGGER, b_session.id) path = environ.get('PATH_INFO', '').lstrip('/') try: jlog.info({ 'cookie': environ['HTTP_COOKIE'].split(';'), 'path': path }) except KeyError: jlog.info({'path': path}) if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) elif '/static/' in path: pre, post = path.split('static') return static(environ, start_response, LOGGER, 'static' + post) query = parse_qs(environ["QUERY_STRING"]) try: session = b_session['session_info'] except KeyError: session = self.find_session(**query) if session: b_session['session_info'] = session else: session = {} b_session['session_info'] = session self.session[b_session.id] = session if path == '': if 'access_token' not in session: return opchoice(environ, start_response, self.clients) else: client = self.clients[session["op"]] # check_session_iframe_url = None try: # check_session_iframe_url = client.provider_info[ # "check_session_iframe"] session["session_management"] = { "session_state": query["session_state"][0], "client_id": client.client_id, "issuer": client.provider_info["issuer"] } except KeyError: pass kwargs = dict([(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if p in session]) return opresult(environ, start_response, **kwargs) elif path == "rp": # After having chosen which OP to authenticate at if "uid" in query: try: client = self.clients.dynamic_client( userid=query["uid"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) elif 'issuer' in query: try: client = self.clients[query["issuer"][0]] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) else: client = self.clients[query["op"][0]] return self.init_client(client, session, query, environ, start_response) elif path.endswith('authz_post'): try: _iss = session['op'] except KeyError: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR'] }) return opchoice(environ, start_response, self.clients) else: client = self.clients[_iss] query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return sorry_response(environ, start_response, self.base, "missing fragment ?!") if info == ['x']: return sorry_response(environ, start_response, self.base, "Expected fragment didn't get one ?!") jlog.info({'fragment': info}) try: result = client.callback(info, session, 'urlencoded') if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception as err: raise else: session.update(result) res = SeeOther(self.conf['base_url']) return res(environ, start_response) elif path in self.clients.return_paths(): # After having # authenticated at the OP jlog.info({'query': query}) _client = None for cli in self.clients.client.values(): if query['state'][0] in cli.authz_req: _client = cli break if not _client: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR'], 'state': query['state'][0] }) return opchoice(environ, start_response, self.clients) if 'error' in query: # something amiss if query['error'][0] == 'access_denied': # Try reregistering _iss = _client.provider_info['issuer'] del self.clients[_iss] try: client = self.clients[_iss] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) return self.init_client(client, session, query, environ, start_response) try: _iss = query['iss'][0] except KeyError: pass else: if _iss != _client.provider_info['issuer']: jlog.error({'reason': 'Got response from wrong OP'}) return opchoice(environ, start_response, self.clients) _response_type = _client.behaviour["response_type"] try: _response_mode = _client.authz_req[ session['state']]['response_mode'] except KeyError: _response_mode = '' jlog.info({ "response_type": _response_type, "response_mode": _response_mode }) if _response_type and _response_type != "code": # Fall through if it's a query response anyway if query: pass elif _response_mode: # form_post encoded pass else: return opresult_fragment(environ, start_response) try: result = _client.callback(query, session) if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception: raise else: session.update(result) res = SeeOther(self.conf['base_url']) return res(environ, start_response) elif path == "logout": # After the user has pressed the logout button try: _iss = session['op'] except KeyError: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR'] }) return opchoice(environ, start_response, self.clients) client = self.clients[_iss] try: del client.authz_req[session['state']] except KeyError: pass logout_url = client.end_session_endpoint try: # Specify to which URL the OP should return the user after # log out. That URL must be registered with the OP at client # registration. logout_url += "?" + urlencode({ "post_logout_redirect_uri": client.registration_response["post_logout_redirect_uris"] [0] }) except KeyError: pass else: # If there is an ID token send it along as a id_token_hint _idtoken = get_id_token(client, session) if _idtoken: logout_url += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt(client, _idtoken, "HS256") }) # Also append the ACR values logout_url += "&" + urlencode({"acr_values": self.acr_values}, True) session.delete() resp = SeeOther(str(logout_url)) return resp(environ, start_response) elif path == "logout_success": # post_logout_redirect_uri return Response("Logout successful!")(environ, start_response) elif path == "session_iframe": # session management kwargs = session["session_management"] resp = Response(mako_template="rp_session_iframe.mako", template_lookup=LOOKUP) return resp(environ, start_response, session_change_url="{}session_change".format( self.conf["base_url"]), **kwargs) elif path == "session_change": try: _iss = session['op'] except KeyError: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR'] }) return opchoice(environ, start_response, self.clients) try: client = self.clients[_iss] except KeyError: return Response("No valid session.")(environ, start_response) kwargs = {"prompt": "none"} # If there is an ID token send it along as a id_token_hint idt = get_id_token(client, session) if idt: kwargs["id_token_hint"] = id_token_as_signed_jwt( client, idt, "HS256") resp = client.create_authn_request(session, self.acr_values, **kwargs) return resp(environ, start_response) return opchoice(environ, start_response, self.clients)