def test_multiple_fo_all_working(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org1 = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) # signed by FO1 ms_org2 = FO1P.pack_metadata_statement(cms_org, alg='RS256', scope=['openid', 'address']) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) ms_rp = ORGOP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=[ms_org1, ms_org2]) # knows all FO's receiver = fo_member(FOP, FO1P) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert len(_cms['metadata_statements']) == 2 _iss = [json.loads(x)['iss'] for x in _cms['metadata_statements']] assert set(_iss) == {ISSUER['fo'], ISSUER['fo1']}
def test_evaluate_metadata_statement_1(): cms_org = ClientMetadataStatement(signing_keys=ORGOP.keyjar.export_jwks(), contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html']) # signed by org ms_inter = ORGOP.pack_metadata_statement(cms_inter, alg='RS256', metadata_statements=[ms_org]) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement(cms_rp, alg='RS256', metadata_statements=[ms_inter]) receiver = fo_member(FOP) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) res = receiver.evaluate_metadata_statement(_cms) assert list(res.keys()) == [ISSUER['fo']] assert sorted(list(res[ISSUER['fo']].keys())) == sorted( ['contacts', 'tos_uri', 'redirect_uris', 'scope'])
def test_pack_and_unpack_ms_lev2(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html']) # signed by org ms_inter = ORGOP.pack_metadata_statement(cms_inter, alg='RS256', metadata_statements=[ms_org]) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement(cms_rp, alg='RS256', metadata_statements=[ms_inter]) receiver = fo_member(FOP) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert _cms
def test_multiple_fo_one_working(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org1 = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) # signed by FO1 ms_org2 = FO1P.pack_metadata_statement(cms_org, alg='RS256', scope=['openid', 'address']) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) ms_rp = ORGOP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=[ms_org1, ms_org2]) # only knows about one FO receiver = fo_member(FOP) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert len(_cms['metadata_statements']) == 1 _ms = json.loads(_cms['metadata_statements'][0]) assert _ms['iss'] == ISSUER['fo']
def registration_endpoint(self, request, authn=None, **kwargs): logger.debug("@registration_endpoint: <<{}>>".format( sanitize(request))) if isinstance(request, dict): request = ClientMetadataStatement(**request) else: try: request = ClientMetadataStatement().deserialize( request, "json") except ValueError: request = ClientMetadataStatement().deserialize(request) logger.info("registration_request:{}".format( sanitize(request.to_dict()))) request_args = self.get_metadata_statement(request) request = RegistrationRequest(**request_args) result = self.client_registration_setup(request) if isinstance(result, Response): return result return Created(result.to_json(), content="application/json", headers=[("Cache-Control", "no-store")])
def test_create_client_metadata_statement(): ms = MetadataStatement(signing_keys=KEYS['org']['jwks']) ms_jwt = ms.to_jwt(KEYS['fo']['keyjar'].get_signing_key('rsa')) cms = ClientMetadataStatement(metadata_statements=[ms_jwt], contacts=['*****@*****.**']) assert cms
def test_evaluate_metadata_statement_3(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org1 = FOP.pack_metadata_statement( cms_org, alg='RS256', claims=['email', 'email_verified', 'phone', 'phone_verified'], scope=['openid', 'email', 'phone']) # signed by FO1 ms_org2 = FO1P.pack_metadata_statement( cms_org, alg='RS256', scope=['openid', 'email', 'address']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html']) # signed by org ms_inter = ORGOP.pack_metadata_statement( cms_inter, alg='RS256', metadata_statements=[ms_org1, ms_org2]) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb'], scope=['openid', 'email']) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement(cms_rp, alg='RS256', metadata_statements=[ms_inter]) # knows all FO's receiver = fo_member(FOP, FO1P) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) res = receiver.evaluate_metadata_statement(_cms) assert set(res.keys()) == {ISSUER['fo'], ISSUER['fo1']} assert sorted(list(res[ISSUER['fo']].keys())) == sorted( ['claims', 'contacts', 'tos_uri', 'redirect_uris', 'scope']) assert res[ISSUER['fo']]['scope'] == ['openid', 'email', 'phone'] assert res[ISSUER['fo1']]['scope'] == ['openid', 'email', 'address'] assert 'claims' in res[ISSUER['fo']] assert 'claims' not in res[ISSUER['fo1']]
def registration_endpoint(self, request, authn=None, **kwargs): logger.debug("@registration_endpoint: <<{}>>".format( sanitize(request))) if isinstance(request, dict): request = ClientMetadataStatement(**request) else: try: request = ClientMetadataStatement().deserialize( request, "json") except ValueError: request = ClientMetadataStatement().deserialize(request) logger.info("registration_request:{}".format( sanitize(request.to_dict()))) res = self.federation_entity.get_metadata_statement(request) if res: request = self.federation_entity.pick_by_priority(res) else: # Nothing I can use return error(error='invalid_request', descr='No signed metadata statement I could use') result = self.client_registration_setup(request) if isinstance(result, Response): return result return Created(result.to_json(), content="application/json", headers=[("Cache-Control", "no-store")])
def test_evaluate_metadata_statement_4(): """ One 4-level (FO, Org, Inter, admin) and one 2-level (FO1, Inter, admin) """ cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement( cms_org, alg='RS256', claims=['email', 'email_verified', 'phone', 'phone_verified'], scope=['openid', 'email', 'phone']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html']) # signed by org ms_inter0 = ORGOP.pack_metadata_statement(cms_inter, alg='RS256', metadata_statements=[ms_org]) ms_inter1 = LIGOOP.pack_metadata_statement(cms_inter, alg='ES256') cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb'], scope=['openid', 'email']) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=[ms_inter0, ms_inter1]) # knows both FO's receiver = fo_member(FOP, LIGOOP) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) res = receiver.evaluate_metadata_statement(_cms) assert set(res.keys()) == {ISSUER['fo'], ISSUER['ligo']} assert sorted(list(res[ISSUER['fo']].keys())) == sorted( ['claims', 'contacts', 'redirect_uris', 'scope', 'tos_uri']) assert res[ISSUER['fo']]['scope'] == ['openid', 'email', 'phone']
def create_compound_metadata_statement(spec): _ms = None root_signer = '' for op, op_args, signer, sig_args in spec: _cms = ClientMetadataStatement(signing_keys=op.keyjar.export_jwks(), **op_args) if _ms: sig_args['metadata_statements'] = [_ms] else: # root signed root_signer = signer.iss _ms = signer.pack_metadata_statement(_cms, **sig_args) return root_signer, _ms
def test_pack_and_unpack_ms_lev1(): # metadata statement created by the organization cms_org = ClientMetadataStatement(signing_keys=ORGOP.keyjar.export_jwks(), contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) # metadata statement created by the admin cms_rp = ClientMetadataStatement( signing_keys=ADMINOP.keyjar.export_jwks(), redirect_uris=['https://rp.example.com/auth_cb']) # signed by the org ms_rp = ORGOP.pack_metadata_statement(cms_rp, alg='RS256', metadata_statements=[ms_org]) receiver = fo_member(FOP) _cms = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert _cms
def test_pack_ms_wrong_fo(): cms = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) _jwt = FOP.pack_metadata_statement(cms, alg='RS256', scope=['openid']) try: member = fo_member(FO1P) _ = member.unpack_metadata_statement(jwt_ms=_jwt) except JWSException as err: assert isinstance(err, NoSuitableSigningKeys) except MissingSigningKey: assert True else: assert False
def test_pack_and_unpack_ms_lev0(): cms = ClientMetadataStatement(signing_keys=FOP.keyjar.export_jwks(), contacts=['*****@*****.**']) _jwt = FOP.pack_metadata_statement(cms, alg='RS256', scope=['openid']) assert _jwt json_ms = unfurl(_jwt) # print(json_ms.keys()) assert set(json_ms.keys()) == { 'signing_keys', 'iss', 'iat', 'exp', 'kid', 'scope', 'contacts', 'jti' } # Unpack what you have packed _cms = FOP.unpack_metadata_statement(jwt_ms=_jwt) assert _cms
def federated_client_registration_request(self, **kwargs): req = ClientMetadataStatement() try: pp = kwargs['fo_pattern'] except KeyError: pp = '.' req['metadata_statements'] = self.pick_signed_metadata_statements(pp) try: req['redirect_uris'] = kwargs['redirect_uris'] except KeyError: try: req["redirect_uris"] = self.redirect_uris except AttributeError: raise MissingRequiredAttribute("redirect_uris", kwargs) return req