def setup_conv(): entity = Client(client_authn_method=CLIENT_AUTHN_METHOD, verify_ssl=False) entity.provider_info = ProviderConfigurationResponse( authorization_endpoint="https://example.com", ) cls_factories = {'': oper.factory} func_factory = func.factory flow_state = FlowState('flows', profile_handler=ProfileHandler, cls_factories=cls_factories, func_factory=func_factory, display_order=OP_ORDER) iss = 'https://example.org' tag = 'foobar' session_handler = SessionHandler(iss, tag, flows=flow_state, tool_conf={}) # , rest=rest, **webenv) session_handler.iss = iss session_handler.tag = tag info = WebIh(session=session_handler, profile_handler=ProfileHandler) conv = Conversation([], entity, factory, callback_uris=[]) conv.events = Events() conv.tool_config = {} return {'conv': conv, 'io': info}
def __init__(self, flow, entity, msg_factory, check_factory=None, features=None, opid=None, **extra_args): self.flow = flow self.entity = entity self.msg_factory = msg_factory self.events = Events() #self.interaction = Interaction(self.entity, interaction) self.check_factory = check_factory self.features = features self.operator_id = opid self.extra_args = extra_args self.test_id = "" self.info = {} self.index = 0 self.comhandler = None self.exception = None self.sequence = [] self.cache = {} self.tool_config = {} self.conf = None
def __init__(self, base_url, **kwargs): self.base_url = base_url self.kwargs = kwargs self.events = Events() self.endpoints = {} self.session_conf = {} self.internal = kwargs['internal']
def _cp_dispatch(self, vpath): # Only get here if vpath != None ent = cherrypy.request.remote.ip logger.info('ent:{}, vpath: {}'.format(ent, vpath)) if vpath[0] == 'static': return self elif vpath[0] == 'sms': vpath.pop(0) cherrypy.request.params['item'] = vpath.pop(0) return self.smsd if len(vpath) >= 2: ev = init_events(cherrypy.request.path_info) oper_id = vpath.pop(0) test_id = vpath.pop(0) # verify test_id try: self.flows[test_id] except KeyError: raise cherrypy.HTTPError(400, 'Unknown TestID') if len(vpath): if len(vpath) == 1: endpoint = vpath.pop(0) op = self.op_handler.get(oper_id, test_id, ev, endpoint)[0] cherrypy.request.params['op'] = op if endpoint == 'registration': return self.registration elif endpoint == 'authorization': return self.authorization elif endpoint == 'token': return self.token elif endpoint == 'userinfo': return self.userinfo elif endpoint == 'claim': return self.claims elif endpoint == 'reset': return self.reset else: # Shouldn't be any other raise cherrypy.NotFound() if len(vpath) == 2: a = vpath.pop(0) b = vpath.pop(0) endpoint = '{}/{}'.format(a, b) if endpoint == ".well-known/openid-configuration": op = self.op_handler.get(oper_id, test_id, Events(), endpoint)[0] cherrypy.request.params['op'] = op return self.configuration return self
def init_events(path, msg=''): ev = Events() if msg: ev.store('Init', '{} {} {}'.format(10 * '=', msg, 10 * '=')) else: ev.store('Init', 40 * '=') req = HTTPRequest(path, method=cherrypy.request.method) try: req.authz = cherrypy.request.headers['Authorization'] except KeyError: pass ev.store(EV_HTTP_REQUEST, req) return ev
def as_arg_setup(args, lookup, config): if args.port: _port = args.port else: if args.tls: _port = 443 else: _port = 80 if args.path2port: # means there is a reverse proxy in front translating # path -> port p2p_map = read_path2port_map(args.path2port) _path = p2p_map[_port] if args.xport: _issuer = "{base}:{port}/{path}".format(base=config.baseurl, port=args.xport, path=_path) _port = args.xport else: _issuer = "{base}/{path}".format(base=config.baseurl, path=_path) else: # the old port based _path = '' _issuer = "{base}:{port}".format(base=config.baseurl, port=_port) if args.tls and _issuer.startswith('http://'): _issuer = _issuer.replace('http://', 'https://') cdb = {} ac = AuthnBroker() for authkey, value in list(config.AUTHENTICATION.items()): authn = None # if "UserPassword" == authkey: # from oic.utils.authn.user import UsernamePasswordMako # authn = UsernamePasswordMako(None, "login.mako", LOOKUP, PASSWD, # "authorization") if "NoAuthn" == authkey: from oic.utils.authn.user import NoAuthn authn = NoAuthn(None, user=config.AUTHENTICATION[authkey]["user"]) if authn is not None: ac.add(config.AUTHENTICATION[authkey]["ACR"], authn, config.AUTHENTICATION[authkey]["WEIGHT"]) # dealing with authorization authz = AuthzHandling() if config.USERINFO == "SIMPLE": # User info is a simple dictionary in this case statically defined in # the configuration file userinfo = UserInfo(config.USERDB) else: userinfo = None as_args = { "name": _issuer, 'instance_path': _path, 'instance_port': _port, "cdb": cdb, "authn_broker": ac, "userinfo": userinfo, "authz": authz, "client_authn": verify_client, "symkey": config.SYM_KEY, "template_lookup": lookup, "template": { "form_post": "form_response.mako" }, "jwks_name": "./static/jwks_{}.json", 'event_db': Events(), } try: as_args['behavior'] = config.BEHAVIOR except AttributeError: pass com_args = { "baseurl": config.baseurl, } for arg in [ 'name', 'cdb', 'authn_broker', 'userinfo', 'authz', 'template', 'jwks_name', 'client_authn', 'symkey', 'template_lookup' ]: com_args[arg] = as_args[arg] # Add own keys for signing/encrypting JWTs try: # a throw-away OP used to do the initial key setup _op = Provider(sdb=SessionDB(com_args["baseurl"]), **com_args) jwks = keyjar_init(_op, config.keys) except KeyError: key_arg = {} else: key_arg = {"jwks": jwks, "keys": config.keys} as_args['jwks_name'] = 'static/jwks.json' f = open('static/jwks.json', 'w') f.write(json.dumps(jwks)) f.close() if args.insecure: _op.keyjar.verify_ssl = False else: _op.keyjar.verify_ssl = True as_args['keyjar'] = _op.keyjar as_args['sdb'] = SessionDB( com_args["baseurl"], token_factory=JWTToken('T', keyjar=_op.keyjar, lt_pattern={ 'code': 3600, 'token': 900 }, iss=com_args['baseurl'], sign_alg='RS256'), refresh_token_factory=JWTToken('R', keyjar=_op.keyjar, lt_pattern={'': 24 * 3600}, iss=com_args['baseurl'])) return as_args, key_arg
def main_setup(args, lookup): sys.path.insert(0, ".") config = importlib.import_module(args.config) config.issuer = config.issuer % args.port config.SERVICE_URL = config.SERVICE_URL % args.port # Client data base # cdb = shelve.open(config.CLIENT_DB, writeback=True) cdb = {} ac = AuthnBroker() for authkey, value in list(config.AUTHENTICATION.items()): authn = None # if "UserPassword" == authkey: # from oic.utils.authn.user import UsernamePasswordMako # authn = UsernamePasswordMako(None, "login.mako", LOOKUP, PASSWD, # "authorization") if "NoAuthn" == authkey: from oic.utils.authn.user import NoAuthn authn = NoAuthn(None, user=config.AUTHENTICATION[authkey]["user"]) if authn is not None: ac.add(config.AUTHENTICATION[authkey]["ACR"], authn, config.AUTHENTICATION[authkey]["WEIGHT"]) # dealing with authorization authz = AuthzHandling() kwargs = { "template_lookup": lookup, "template": { "form_post": "form_response.mako" }, } if config.USERINFO == "SIMPLE": # User info is a simple dictionary in this case statically defined in # the configuration file userinfo = UserInfo(config.USERDB) else: userinfo = None # Should I care about verifying the certificates used by other entities if args.insecure: kwargs["verify_ssl"] = False else: kwargs["verify_ssl"] = True uri_schemes = read_uri_schemes('uri-schemes-1.csv') as_args = { "name": config.issuer, "cdb": cdb, "authn_broker": ac, "userinfo": userinfo, "authz": authz, "client_authn": verify_client, "symkey": config.SYM_KEY, "template_lookup": lookup, "template": { "form_post": "form_response.mako" }, "jwks_name": "./static/jwks_{}.json", 'event_db': Events(), } com_args = { "name": config.issuer, # "sdb": SessionDB(config.baseurl), "baseurl": config.baseurl, "cdb": cdb, "authn_broker": ac, "userinfo": userinfo, "authz": authz, "client_authn": verify_client, "symkey": config.SYM_KEY, "template_lookup": lookup, "template": { "form_post": "form_response.mako" }, "jwks_name": "./static/jwks_{}.json", 'uri_schemes': uri_schemes } op_arg = {} try: op_arg["cookie_ttl"] = config.COOKIETTL except AttributeError: pass try: op_arg["cookie_name"] = config.COOKIENAME except AttributeError: pass try: as_args['behavior'] = config.BEHAVIOR except AttributeError: pass # print URLS if args.debug: op_arg["debug"] = True if args.port == 80: _baseurl = config.baseurl else: if config.baseurl.endswith("/"): config.baseurl = config.baseurl[:-1] _baseurl = "%s:%d" % (config.baseurl, args.port) if not _baseurl.endswith("/"): _baseurl += "/" op_arg["baseurl"] = _baseurl # Add own keys for signing/encrypting JWTs try: # a throw-away OP used to do the initial key setup _op = Provider(sdb=SessionDB(com_args["baseurl"]), **com_args) jwks = keyjar_init(_op, config.keys) except KeyError: pass else: op_arg["jwks"] = jwks op_arg["keys"] = config.keys as_args['jwks_uri'] = '{}{}/jwks.json'.format(_baseurl, 'static') as_args['jwks_name'] = 'static/jwks.json' f = open('static/jwks.json', 'w') f.write(json.dumps(jwks)) f.close() as_args['keyjar'] = _op.keyjar as_args['sdb'] = SessionDB(com_args["baseurl"], token_factory=JWTToken('T', keyjar=_op.keyjar, lt_pattern={ 'code': 3600, 'token': 900 }, iss=_baseurl, sign_alg='RS256'), refresh_token_factory=JWTToken( 'R', keyjar=_op.keyjar, lt_pattern={'': 24 * 3600}, iss=_baseurl)) try: op_arg["marg"] = multi_keys(as_args, config.multi_keys) except AttributeError as err: pass return as_args, op_arg, config
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)