def test_evaluate_metadata_statement_3(): cms_org = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid', 'email', 'phone']) cms_inter = ClientMetadataStatement( tos_uri='https://inter.example.com/tos.html', ) cms_rp = ClientMetadataStatement(scope=['openid', 'email'], ) clear_metadata_statements(FEDENT.values()) _ = create_compounded_metadata_statement( [ADMINOP.iss, INTEROP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, ADMINOP.iss: cms_rp, INTEROP.iss: cms_inter }) cms_org = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid', 'email', 'address'], claims=['email', 'email_verified']) cms_rp = ClientMetadataStatement(scope=['openid', 'address'], ) clear_metadata_statements([FEDENT[ORGOP.iss], FEDENT[INTEROP.iss]]) _ = create_compounded_metadata_statement( [ADMINOP.iss, INTEROP.iss, ORGOP.iss, FO1P.iss], FEDENT, { ORGOP.iss: cms_org, ADMINOP.iss: cms_rp, INTEROP.iss: cms_inter }) # Create ultimate registration request and self sign cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) ADMINOP.add_sms_spec_to_request(cms_rp) _sms = ADMINOP.self_sign(cms_rp).to_dict() # knows all FO's receiver = fo_member(FOP, FO1P) ri = receiver.unpack_metadata_statement(ms_dict=_sms) res = receiver.evaluate_metadata_statement(ri.result) assert len(res) == 2 assert set([r.fo for r in res]) == {FOP.iss, FO1P.iss} for r in res: if r.fo == FOP.iss: assert set( r.keys()) == {'contacts', 'tos_uri', 'redirect_uris', 'scope'} assert r['scope'] == ['openid', 'email'] else: assert set(r.keys()) == { 'contacts', 'tos_uri', 'redirect_uris', 'scope', 'claims' } assert r['scope'] == ['openid', 'address']
def test_evaluate_metadata_statement_4(): """ One 4-level (FO, Org, Inter, Ligo) and one 2-level (FO1, Ligo) """ cms_org = ClientMetadataStatement( contacts=['*****@*****.**'], claims=['email', 'email_verified', 'phone', 'phone_verified'], scope=['openid', 'email', 'phone']) cms_inter = ClientMetadataStatement( tos_uri='https://inter.example.com/tos.html', ) cms_rp = ClientMetadataStatement(scope=['openid', 'email'], ) clear_metadata_statements(FEDENT.values()) # 4 _ = create_compounded_metadata_statement( [ADMINOP.iss, INTEROP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, ADMINOP.iss: cms_rp, INTEROP.iss: cms_inter }) fop_sms = ADMINOP.metadata_statements['discovery'][FOP.iss] ADMINOP.metadata_statements['discovery'] = {} clear_metadata_statements([FEDENT[LIGOOP.iss]]) # Need a new untainted instance cms_rp = ClientMetadataStatement(scope=['openid', 'email'], ) # 2 LIGO is FO _ = create_compounded_metadata_statement([ADMINOP.iss, LIGOOP.iss], FEDENT, {ADMINOP.iss: cms_rp}) cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) ADMINOP.metadata_statements['discovery'][FOP.iss] = fop_sms ADMINOP.add_sms_spec_to_request(cms_rp) _sms = ADMINOP.self_sign(cms_rp).to_dict() # knows both FO's receiver = fo_member(FOP, LIGOOP) ri = receiver.unpack_metadata_statement(ms_dict=_sms) _re = receiver.evaluate_metadata_statement(ri.result) res = le_dict(_re) assert set(res.keys()) == {FOP.iss, LIGOOP.iss} assert set(res[FOP.iss].keys()) == { 'claims', 'contacts', 'redirect_uris', 'scope', 'tos_uri' } assert res[FOP.iss]['scope'] == ['openid', 'email']
def test_evaluate_metadata_statement_2(): cms_org = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid', 'email', 'address']) cms_inter = ClientMetadataStatement( tos_uri='https://inter.example.com/tos.html', ) cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], scope=['openid', 'email'], ) clear_metadata_statements(FEDENT.values()) _jws = create_compounded_metadata_statement( [ADMINOP.iss, INTEROP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, INTEROP.iss: cms_inter, ADMINOP.iss: cms_rp }) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=_jws) res = receiver.evaluate_metadata_statement(ri.result) assert len(res) == 1 assert res[0].iss == ORGOP.iss assert res[0].fo == FOP.iss assert set( res[0].keys()) == {'contacts', 'tos_uri', 'redirect_uris', 'scope'} assert res[0]['scope'] == ['openid', 'email']
def test_evaluate_metadata_statement_1(): # Metadata statements created by ORG cms_org = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid']) # Metadata statements created by INTER cms_inter = ClientMetadataStatement( tos_uri='https://inter.example.com/tos.html', ) # Metadata statements created by ADMIN cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) clear_metadata_statements(FEDENT.values()) _jws = create_compounded_metadata_statement( [ADMINOP.iss, INTEROP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, INTEROP.iss: cms_inter, ADMINOP.iss: cms_rp }) # Unpacked by another member of the FO federation receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=_jws) res = receiver.evaluate_metadata_statement(ri.result) assert len(res) == 1 assert res[0].iss == ORGOP.iss assert set( res[0].keys()) == {'contacts', 'tos_uri', 'redirect_uris', 'scope'}
def test_pack_ms_wrong_fo(): cms = ClientMetadataStatement(signing_keys=ORGOP.signing_keys_as_jwks(), contacts=['*****@*****.**'], scope=['openid']) _jwt = create_compounded_metadata_statement([ORGOP.iss, FOP.iss], FEDENT, {ORGOP.iss: cms}) member = fo_member(FO1P) pr = member.unpack_metadata_statement(jwt_ms=_jwt) assert pr.result is None assert isinstance(pr.error[_jwt], (MissingSigningKey, KeyError))
def test_multiple_fo_one_working(): cms_org1 = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid']) cms_none = ClientMetadataStatement() clear_metadata_statements(FEDENT.values()) _ = create_compounded_metadata_statement([ADMINOP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org1, ADMINOP.iss: cms_none }) cms_org1 = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid', 'address']) clear_metadata_statements([FEDENT[ORGOP.iss]]) _ = create_compounded_metadata_statement( [ADMINOP.iss, ORGOP.iss, FO1P.iss], FEDENT, { ORGOP.iss: cms_org1, ADMINOP.iss: cms_none }) cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) ADMINOP.add_sms_spec_to_request(cms_rp) sms = ADMINOP.self_sign(cms_rp).to_dict() # only knows about one FO receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(ms_dict=sms) assert len(ri.result['metadata_statements']) == 1 _key = list(ri.result['metadata_statements'].keys())[0] _ms = ri.result['metadata_statements'][_key] assert _ms['iss'] == ADMINOP.iss
def test_multiple_fo_all_working(): cms_org1 = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid']) cms_none = ClientMetadataStatement() clear_metadata_statements(FEDENT.values()) _ = create_compounded_metadata_statement([ADMINOP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org1, ADMINOP.iss: cms_none }) cms_org1 = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid', 'address']) clear_metadata_statements([FEDENT[ORGOP.iss]]) _ = create_compounded_metadata_statement( [ADMINOP.iss, ORGOP.iss, FO1P.iss], FEDENT, { ORGOP.iss: cms_org1, ADMINOP.iss: cms_none }) cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) ADMINOP.add_sms_spec_to_request(cms_rp) sms = ADMINOP.self_sign(cms_rp).to_dict() # knows all FO's receiver = fo_member(FOP, FO1P) ri = receiver.unpack_metadata_statement(ms_dict=sms) assert len(ri.result['metadata_statements']) == 2 _iss = [iss for iss, val in ri.result['metadata_statements'].items()] assert set(_iss) == {FOP.iss, FO1P.iss}
def test_unpack_discovery_info(): cms_org = ProviderConfigurationResponse() # Made by OP admin cms_sa = ProviderConfigurationResponse( issuer='https://example.org/op', authorization_endpoint='https://example.org/op/auth', ) clear_metadata_statements(FEDENT.values()) # 4 _ = create_compounded_metadata_statement([ADMINOP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, ADMINOP.iss: cms_sa }) cms_op = ProviderConfigurationResponse( issuer='https://example.org/op', authorization_endpoint='https://example.org/op/auth', ) ADMINOP.add_sms_spec_to_request(cms_op) _sms = ADMINOP.self_sign(cms_op).to_dict() receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(ms_dict=_sms, cls=ProviderConfigurationResponse) pcr_ms = receiver.evaluate_metadata_statement(ri.result) assert len(pcr_ms) == 1 assert pcr_ms[0].fo == FOP.iss assert pcr_ms[0]['issuer'] == 'https://example.org/op' _ms = pcr_ms[0] # This includes default claims assert set(_ms.unprotected_and_protected_claims().keys()) == { 'version', 'token_endpoint_auth_methods_supported', 'claims_parameter_supported', 'request_parameter_supported', 'request_uri_parameter_supported', 'require_request_uri_registration', 'grant_types_supported', 'issuer', 'authorization_endpoint' }
def test_pack_and_unpack_ms_lev1(): # metadata statement created by the organization cms_org = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid']) # metadata statement created by the admin cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) clear_metadata_statements(FEDENT.values()) _jwt = create_compounded_metadata_statement( [ADMINOP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, ADMINOP.iss: cms_rp }) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=_jwt) assert ri.result
def create_provider_info_response(fo): sunet_metadata = MetadataStatement() pi_response = ProviderConfigurationResponse( issuer=SUNET_OP.iss, response_types_supported=['code'], grant_types_supported=['Bearer'], subject_types_supported=['pairwise'], authorization_endpoint='https://example.com/op/authz', jwks_uri='https://example.com/op/jwks.json', token_endpoint='https://example.com/op/token', id_token_signing_alg_values_supported=['RS256', 'RS384', 'RS512'], userinfo_signing_alg_values_supported=['RS256', 'RS384', 'RS512']) clear_metadata_statements(FEDENT.values()) _ = create_compounded_metadata_statement( [SUNET_OP.iss, ORG_SUNET.iss, fo.iss], FEDENT, { ORG_SUNET.iss: sunet_metadata, SUNET_OP.iss: pi_response }) # clean copy pi_response = ProviderConfigurationResponse( issuer=SUNET_OP.iss, response_types_supported=['code'], grant_types_supported=['Bearer'], subject_types_supported=['pairwise'], authorization_endpoint='https://example.com/op/authz', jwks_uri='https://example.com/op/jwks.json', token_endpoint='https://example.com/op/token', id_token_signing_alg_values_supported=['RS256', 'RS384', 'RS512'], userinfo_signing_alg_values_supported=['RS256', 'RS384', 'RS512']) SUNET_OP.add_sms_spec_to_request(pi_response) resp = SUNET_OP.self_sign(pi_response) return resp.to_json()
def test_pack_and_unpack_ms_lev2(): cms_org = ClientMetadataStatement(contacts=['*****@*****.**'], scope=['openid']) cms_inter = ClientMetadataStatement( tos_uri='https://inter.example.com/tos.html', ) cms_rp = ClientMetadataStatement( redirect_uris=['https://rp.example.com/auth_cb'], ) clear_metadata_statements(FEDENT.values()) _jwt = create_compounded_metadata_statement( [ADMINOP.iss, INTEROP.iss, ORGOP.iss, FOP.iss], FEDENT, { ORGOP.iss: cms_org, INTEROP.iss: cms_inter, ADMINOP.iss: cms_rp }) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=_jwt) assert ri.result
FED_KEYDEF = [{"type": "EC", "crv": "P-256", "use": ["sig"]}] # Identifiers for all the entities ALL = ['https://edugain.org', 'https://swamid.sunet.se'] # Create the federation entities FEDENT = create_federation_entities(ALL, FED_KEYDEF, root_dir='../') SWAMID = FEDENT['https://swamid.sunet.se'] EDUGAIN = FEDENT['https://edugain.org'] FEDENT[SUNET_OP.iss] = SUNET_OP _sms = create_compounded_metadata_statement( [SUNET_OP.iss, SWAMID.iss, EDUGAIN.iss], FEDENT, { SWAMID.iss: Message(), SUNET_OP.iss: _info }, 'discovery', lifetime=86400) fp = open('sms/discovery/{}'.format(quote_plus(EDUGAIN.iss)), 'w') fp.write(_sms) fp.close() try: _sms = make_signing_sequence([SUNET_OP.iss, SWAMID.iss, EDUGAIN.iss], FEDENT, 'response', lifetime=86400) except Exception as err: print(err)