def test_parse_registration_response(self): # construct the entity statement the OP should return es_api = FSEntityStatementAPI(os.path.join(BASE_PATH, 'base_data'), iss="op.ntnu.no") jws = es_api.create_entity_statement("op.ntnu.no") # parse the response and collect the trust chains res = self.service['discovery'].parse_response(jws) self.service['discovery'].update_service_context(res) _sc = self.service['registration'].service_context self.service['registration'].endpoint = _sc.get('provider_info')[ 'federation_registration_endpoint'] # construct the client registration request req_args = {'entity_id': self.federation_entity.entity_id} jws = self.service['registration'].construct(request_args=req_args) assert jws # construct the information needed to send the request _info = self.service['registration'].get_request_parameters( request_body_type="jose", method="POST") # create the request _req_jwt = factory(_info['body']) payload = _req_jwt.jwt.payload() # The OP as federation entity _fe = _sc.federation_entity del _fe.keyjar["https://op.ntnu.no"] # make sure I have the private keys _fe.keyjar.import_jwks( es_api.keyjar.export_jwks(True, "https://op.ntnu.no"), "https://op.ntnu.no" ) tree = _fe.collect_statement_chains(payload['iss'], _info['body']) _node = {payload['iss']: (_info['body'], tree)} chains = branch2lists(_node) statements = [eval_chain(c, _fe.keyjar, 'openid_relying_party') for c in chains] metadata_policy = { "client_id": {"value": "aaaaaaaaa"}, "client_secret": {"value": "bbbbbbbbbb"} } # This is the registration response from the OP _jwt = _fe.create_entity_statement( 'https://op.ntnu.no', 'https://foodle.uninett.no', metadata_policy={_fe.entity_type: metadata_policy}, metadata={"federation_entity": {"trust_anchor_id": statements[0].fo}}, authority_hints=['https://feide.no']) claims = self.service['registration'].parse_response(_jwt, request_body=_info['body']) assert set(claims.keys()) == { 'id_token_signed_response_alg', 'application_type', 'client_secret', 'client_id', 'response_types', 'token_endpoint_auth_method', 'grant_types', "contacts", 'federation_type'}
def get_configuration_information(self, subject_id): """ :param subject_id: :return: A signed JWT """ es_api = FSEntityStatementAPI(self.root_dir, iss=get_netloc(subject_id)) jws = es_api.create_entity_statement(get_netloc(subject_id)) # config = verify_self_signed_signature(jws) # return config return jws
def test_make_entity_statement(): fse = FSEntityStatementAPI(BASE_PATH, iss='ntnu.no') _statement = fse.create_entity_statement('foodle.uninett.no') _jws = factory(_statement) assert _jws payload = _jws.jwt.payload() assert payload['iss'] == 'https://ntnu.no' assert payload['sub'] == 'https://foodle.uninett.no' es = EntityStatement().from_dict(payload) _item = es['metadata_policy']['openid_relying_party'] assert _item['contacts'] == {"add": '*****@*****.**'}
def test_config_information(): fse = FSEntityStatementAPI(BASE_PATH, iss='foodle.uninett.no') _jwt = fse.create_entity_statement('foodle.uninett.no') _jws = factory(_jwt) assert _jws payload = _jws.jwt.payload() assert payload['iss'] == 'https://foodle.uninett.no' assert payload['sub'] == 'https://foodle.uninett.no' es = EntityStatement().from_dict(payload) _item = es['metadata']['openid_relying_party'] assert isinstance(_item, RegistrationResponse) assert _item['response_types'] == ['code']
def build_path(self, intermediate, root_dir='.', sub=''): """ Builds a trust path as a sequence of signed JWTs containing entity statements :param root_dir: Where to find the dummy information to put in the entity statement :param intermediate: Which issuer to use :param sub: The identifier of the subject :return: An Issuer instance """ es_api = FSEntityStatementAPI(self.root_dir, iss=get_netloc(intermediate)) jws = es_api.create_entity_statement(get_netloc(sub)) superior = {} _jwt = factory(jws) entity_statement = _jwt.jwt.payload() if 'authority_hints' in entity_statement: for key in entity_statement['authority_hints']: superior[key] = self.build_path(key, root_dir, intermediate) return jws, superior
def get_entity_statement(self, api_endpoint, issuer, subject): es_api = FSEntityStatementAPI(self.root_dir, iss=get_netloc(issuer)) return es_api.create_entity_statement(get_netloc(subject))
#!/usr/bin/env python3 import os from fedservice.metadata_api.fs2 import FSEntityStatementAPI BASE_PATH = os.path.abspath(os.path.dirname(__file__)) def make_entity_id(item): return "https://{}".format(item) for iss in os.listdir(BASE_PATH): path = os.path.join(BASE_PATH, iss) if os.path.isdir(path): fse = FSEntityStatementAPI(BASE_PATH, iss=iss) # fse.make_entity_id = make_entity_id fse.load_jwks(iss, iss, make_entity_id(iss)) for sub in os.listdir(path): sub_path = os.path.join(path, sub) if os.path.isdir(sub_path): _jwt = fse.create_entity_statement(sub) output = os.path.join(BASE_PATH, iss, sub, 'jws') fp = open(output, "w") fp.write(_jwt) fp.close()
def create_statements(self): res = {} # self-signed from subject es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.subject)) res['subj_sesi'] = es_api.create_entity_statement(get_netloc(self.subject)) # self-signed from intermediate es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.intermediate)) res['inter_sesi'] = es_api.create_entity_statement(get_netloc(self.intermediate)) # self-signed from fedop1 es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.fedop1)) res['fedop1_sesi'] = es_api.create_entity_statement(get_netloc(self.fedop1)) # self-signed from fedop2 es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.fedop2)) res['fedop2_sesi'] = es_api.create_entity_statement(get_netloc(self.fedop2)) # intermediate on subject es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.intermediate)) res['inter_on_sub'] = es_api.create_entity_statement(get_netloc(self.subject)) # fedop1 on intermediate es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.fedop1)) res['fedop1_on_inter'] = es_api.create_entity_statement(get_netloc(self.intermediate)) # fedop2 on intermediate es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(self.fedop2)) res['fedop2_on_inter'] = es_api.create_entity_statement(get_netloc(self.intermediate)) return res
def test_collect_intermediate(self): _collector = self.endpoint.server_get( "endpoint_context").federation_entity.collector subject = 'https://op.ntnu.no' intermediate = 'https://ntnu.no' fedop1 = 'https://feide.no' fedop2 = 'https://swamid.se' # self-signed from subject es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(subject)) subj_sesi = es_api.create_entity_statement(get_netloc(subject)) # self-signed from intermediate es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(intermediate)) inter_sesi = es_api.create_entity_statement(get_netloc(intermediate)) # self-signed from fedop es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(fedop1)) fedop_sesi_1 = es_api.create_entity_statement(get_netloc(fedop1)) es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(fedop2)) fedop_sesi_2 = es_api.create_entity_statement(get_netloc(fedop2)) # intermediate on subject es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(intermediate)) inter_on_sub = es_api.create_entity_statement(get_netloc(subject)) # fedop on intermediate es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(fedop1)) fedop_on_inter_1 = es_api.create_entity_statement( get_netloc(intermediate)) es_api = FSEntityStatementAPI(ROOT_DIR, iss=get_netloc(fedop2)) fedop_on_inter_2 = es_api.create_entity_statement( get_netloc(intermediate)) sleep(1) with responses.RequestsMock() as rsps: _url = "{}/.well-known/openid-federation".format(intermediate) rsps.add("GET", _url, body=inter_sesi, status=200) _url = "{}/.well-known/openid-federation".format(fedop1) rsps.add("GET", _url, body=fedop_sesi_1, status=200) _url = "{}/.well-known/openid-federation".format(fedop2) rsps.add("GET", _url, body=fedop_sesi_2, status=200) _url = 'https://ntnu.no/api?iss=https%3A%2F%2Fntnu.no&sub=https%3A%2F%2Fop.ntnu.no' rsps.add("GET", _url, body=inter_on_sub, status=200) _url = 'https://feide.no/api?iss=https%3A%2F%2Ffeide.no&sub=https%3A%2F%2Fntnu.no' rsps.add("GET", _url, body=fedop_on_inter_1, status=200) _url = 'https://swamid.se/api?iss=https%3A%2F%2Fswamid.se&sub=https%3A%2F%2Fntnu.no' rsps.add("GET", _url, body=fedop_on_inter_2, status=200) tree = _collector.collect_intermediate(subject, 'https://ntnu.no') assert tree assert len(_collector.config_cache) == 3 assert set(_collector.config_cache.keys()) == { 'https://ntnu.no', 'https://feide.no', 'https://swamid.se' } # The unpacked fedop1's self signed entity statement _info = _collector.config_cache['https://feide.no'] assert _info['sub'] == fedop1 assert _info['iss'] == fedop1 assert _info['metadata']['federation_entity'][ 'federation_api_endpoint'] == 'https://feide.no/api' # For each entity statement there is also the expiration time assert len(_collector.entity_statement_cache) == 6 assert set(_collector.entity_statement_cache.keys()) == { 'https://feide.no!!https://ntnu.no', 'https://feide.no!exp!https://ntnu.no', 'https://ntnu.no!!https://op.ntnu.no', 'https://ntnu.no!exp!https://op.ntnu.no', 'https://swamid.se!!https://ntnu.no', 'https://swamid.se!exp!https://ntnu.no' } # have a look at the payload _info = unverified_entity_statement( _collector. entity_statement_cache['https://swamid.se!!https://ntnu.no']) assert _info['sub'] == intermediate assert _info['iss'] == fedop2 assert _info['authority_hints'] == [fedop2] _collector_dump = _collector.dump() _c2 = Collector() _c2.load(_collector_dump) assert len(_c2.config_cache) == 3 assert set(_c2.config_cache.keys()) == { 'https://ntnu.no', 'https://feide.no', 'https://swamid.se' } # The unpacked fedop1's self signed entity statement _info = _c2.config_cache['https://feide.no'] assert _info['sub'] == fedop1 assert _info['iss'] == fedop1 assert _info['metadata']['federation_entity'][ 'federation_api_endpoint'] == 'https://feide.no/api' # For each entity statement there is also the expiration time assert len(_c2.entity_statement_cache) == 6 assert set(_c2.entity_statement_cache.keys()) == { 'https://feide.no!!https://ntnu.no', 'https://feide.no!exp!https://ntnu.no', 'https://ntnu.no!!https://op.ntnu.no', 'https://ntnu.no!exp!https://op.ntnu.no', 'https://swamid.se!!https://ntnu.no', 'https://swamid.se!exp!https://ntnu.no' } # have a look at the payload _info = unverified_entity_statement( _c2.entity_statement_cache['https://swamid.se!!https://ntnu.no']) assert _info['sub'] == intermediate assert _info['iss'] == fedop2 assert _info['authority_hints'] == [fedop2]