def op_info(environ, start_response, session_info, events, jlog, **kwargs): _ev = Operation("ProviderConfiguration", path=environ["PATH_INFO"]) try: _ev.query = environ["QUERY_STRING"] except KeyError: pass events.store(EV_REQUEST, _ev) _op = session_info["op"] logger.info('OP keys:{}'.format(key_summary(_op.keyjar, ''))) return wsgi_wrapper(environ, start_response, _op.providerinfo_endpoint, session_info, events, jlog)
def index(self, resource, rel): ev = init_events('/.well-known/webfinger', 'Test tool version:{}'.format(self.version)) ev.store(EV_REQUEST, Operation('WebFinger', resource=resource, rel=rel)) if rel != 'http://openid.net/specs/connect/1.0/issuer': ev.store( EV_FAULT, FailedOperation('Webfinger', error='unknown rel', rel=rel)) try: op_id, test_id = parse_resource(resource) except (ValueError, TypeError): logger.error('webfinger resource specification faulty') raise cherrypy.HTTPError( 400, 'webfinger resource specification faulty') else: write_events(ev, op_id, test_id) raise cherrypy.NotFound() try: op_id, test_id = parse_resource(resource) except (ValueError, TypeError): logger.error('webfinger resource specification faulty') raise cherrypy.HTTPError( 400, 'webfinger resource specification faulty') else: _path = '/'.join([op_id, test_id]) cnf = cherrypy.request.config subj = resource _base = cnf['base_url'] dummy = None # introducing an error if 'rp-discovery-webfinger-http-href' in resource: _base = _base.replace('https', 'http') if 'rp-discovery-webfinger-unknown-member' in resource: dummy = "foobar" if _base.endswith('/'): href = '{}{}'.format(_base, _path) else: href = '{}/{}'.format(_base, _path) ev.store(EV_RESPONSE, Operation('Webfinger', href=href, subj=resource, dummy=dummy)) write_events(ev, op_id, test_id) resp = self.srv.response(subj, href, dummy=dummy) cherrypy.response.headers['Content-Type'] = 'application/jrd+json' return as_bytes(resp)
def store_request(op, where): _ev = Operation(where, path=url()) try: op.events.store(EV_REQUEST, _ev) except Exception as err: raise
def authorization(environ, start_response, session_info, events, jlog, **kwargs): events.store(EV_REQUEST, Operation("Authorization")) _op = session_info["op"] logger.info('OP keys:{}'.format(key_summary(_op.keyjar, ''))) return wsgi_wrapper(environ, start_response, _op.authorization_endpoint, session_info, events, jlog)
def registration(environ, start_response, session_info, events, jlog, **kwargs): events.store(EV_REQUEST, Operation("ClientRegistration")) _op = session_info["op"] if environ["REQUEST_METHOD"] == "POST": return wsgi_wrapper(environ, start_response, _op.registration_endpoint, session_info, events, jlog) elif environ["REQUEST_METHOD"] == "GET": return wsgi_wrapper(environ, start_response, _op.read_registration, session_info, events, jlog) else: resp = ServiceError("Method not supported") return resp(environ, start_response)
def webfinger(environ, start_response, session_info, events, jlog, **kwargs): _query = session_info['parameters'] events.store(EV_REQUEST, Operation("WebFinger", _query)) try: assert _query["rel"] == [OIC_ISSUER] resource = _query["resource"][0] except AssertionError: errmsg = "Wrong 'rel' value: %s" % _query["rel"][0] events.store(EV_FAULT, errmsg) resp = BadRequest(errmsg) except KeyError: errmsg = "Missing 'rel' parameter in request" events.store(EV_FAULT, errmsg) resp = BadRequest(errmsg) else: wf = WebFinger() _url = os.path.join(kwargs["op_arg"]["baseurl"], session_info['oper_id'], session_info["test_id"]) _mesg = wf.response(subject=resource, base=_url) if session_info['test_id'] == 'rp-discovery-webfinger-http-href': _msg = json.loads(_mesg) _msg['links'][0]['href'] = _msg['links'][0]['href'].replace( 'https', 'http') _mesg = json.dumps(_msg) elif session_info[ 'test_id'] == 'rp-discovery-webfinger-unknown-member': _msg = json.loads(_mesg) _msg['dummy'] = 'foobar' _mesg = json.dumps(_msg) resp = Response(_mesg, content="application/jrd+json") events.store(EV_RESPONSE, resp.message) jlog.info(resp2json(resp)) dump_log(session_info, events) return resp(environ, start_response)
def application(self, 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('/') response_encoder = ResponseEncoder(environ=environ, start_response=start_response) parameters = parse_qs(environ["QUERY_STRING"]) session_info = { "addr": get_client_address(environ), 'cookie': environ.get("HTTP_COOKIE", ''), 'path': path, 'parameters': parameters } jlog = JLog(LOGGER, session_info['addr']) jlog.info(session_info) if path == "robots.txt": return static(environ, start_response, "static/robots.txt") if path.startswith("static/"): return static(environ, start_response, path) elif path.startswith("tar/"): return static(environ, start_response, path) elif path.startswith("log"): return display_log(path, environ, start_response, lookup=LOOKUP) elif path.startswith('clear/'): return clear_log(path, environ, start_response, lookup=LOOKUP) elif path.startswith('mktar/'): return make_tar(path, environ, start_response, lookup=LOOKUP) elif path.startswith("_static/"): return static(environ, start_response, path) elif path.startswith("jwks.json"): try: mode, endpoint = extract_mode(self.op_args["baseurl"]) events = Events() events.store('Init', '===========================================') op, path, jlog.id = self.op_setup(environ, mode, events, self.test_conf, endpoint) jwks = op.generate_jwks(mode) resp = Response(jwks, headers=[('Content-Type', 'application/json')]) return resp(environ, start_response) except KeyError: # Try to load from static file return static(environ, start_response, "static/jwks.json") events = Events() events.store('Init', '===========================================') if path == "test_list": return rp_test_list(environ, start_response) elif path == "": return registration(environ, start_response) elif path == "generate_client_credentials": client_id, client_secret = generate_static_client_credentials( parameters) return response_encoder.return_json( json.dumps({"client_id": client_id, "client_secret": client_secret})) elif path == "3rd_party_init_login": return rp_support_3rd_party_init_login(environ, start_response) # path should be <oper_id>/<test_id>/<endpoint> try: mode = parse_path(path) except ValueError: resp = BadRequest('Illegal path') return resp(environ, start_response) try: endpoint = mode['endpoint'] except KeyError: _info = {'error': 'No endpoint', 'mode': mode} events.store(EV_FAULT, _info) jlog.error(_info) resp = BadRequest('Illegal path') return resp(environ, start_response) if endpoint == ".well-known/webfinger": session_info['endpoint'] = endpoint try: _p = urlparse(parameters["resource"][0]) except KeyError: events.store(EV_FAULT, FailedOperation('webfinger', 'No resource defined')) jlog.error({'reason': 'No resource defined'}) resp = ServiceError("No resource defined") return resp(environ, start_response) if _p.scheme in ["http", "https"]: events.store(EV_REQUEST, Operation(name='webfinger', type='url', path=_p.path)) mode = parse_path(_p.path) elif _p.scheme == "acct": _l, _ = _p.path.split('@') _a = _l.split('.') if len(_a) == 2: _oper_id = _a[0] _test_id = _a[1] elif len(_a) > 2: _oper_id = ".".join(_a[:-1]) _test_id = _a[-1] else: _oper_id = _a[0] _test_id = 'default' mode.update({'oper_id': _oper_id, 'test_id': _test_id}) events.store(EV_REQUEST, Operation(name='webfinger', type='acct', oper_id=_oper_id, test_id=_test_id)) else: _msg = "Unknown scheme: {}".format(_p.scheme) events.events(EV_FAULT, FailedOperation('webfinger', _msg)) jlog.error({'reason': _msg}) resp = ServiceError(_msg) return resp(environ, start_response) elif endpoint == "claim": authz = environ["HTTP_AUTHORIZATION"] _ev = Operation('claim') try: assert authz.startswith("Bearer") except AssertionError: resp = BadRequest() else: _ev.authz = authz events.store(EV_REQUEST, _ev) tok = authz[7:] # mode, endpoint = extract_mode(self.op_args["baseurl"]) _op, _, sid = self.op_setup(environ, mode, events, self.test_conf, endpoint) try: _claims = _op.claim_access_token[tok] except KeyError: resp = BadRequest() else: del _op.claim_access_token[tok] _info = Message(**_claims) jwt_key = _op.keyjar.get_signing_key() resp = Response(_info.to_jwt(key=jwt_key, algorithm="RS256"), content='application/jwt') return resp(environ, start_response) if mode: session_info.update(mode) jlog.id = mode['oper_id'] try: _op, path, jlog.id = self.op_setup(environ, mode, events, self.test_conf, endpoint) except UnknownTestID as err: resp = BadRequest('Unknown test ID: {}'.format(err.args[0])) return resp(environ, start_response) session_info["op"] = _op session_info["path"] = path session_info['test_conf'] = self.test_conf[session_info['test_id']] for regex, callback in URLS: match = re.search(regex, endpoint) if match is not None: _op = HTTPRequest(endpoint=endpoint, method=environ["REQUEST_METHOD"]) try: _op.authz = environ["HTTP_AUTHORIZATION"] except KeyError: pass events.store(EV_HTTP_REQUEST, _op) try: environ['oic.url_args'] = match.groups()[0] except IndexError: environ['oic.url_args'] = endpoint jlog.info({'callback': callback.__name__}) try: return callback(environ, start_response, session_info, events, op_arg=self.op_args, jlog=jlog) except Exception as err: print("%s" % err) message = traceback.format_exception(*sys.exc_info()) print(message) events.store(EV_EXCEPTION, err) LOGGER.exception("%s" % err) resp = ServiceError("%s" % err) return resp(environ, start_response) LOGGER.debug("unknown page: '{}'".format(endpoint)) events.store(EV_FAULT, 'No such page: {}'.format(endpoint)) resp = NotFound("Couldn't find the side you asked for!") return resp(environ, start_response)