def setup_for_authn_req(self, context, idp_conf, sp_conf, nameid_format=None, relay_state="relay_state", internal_attributes=INTERNAL_ATTRIBUTES, extra_config={}, subject=None): config = {"idp_config": idp_conf, "endpoints": ENDPOINTS} config.update(extra_config) sp_metadata_str = create_metadata_from_config_dict(sp_conf) idp_conf["metadata"]["inline"] = [sp_metadata_str] base_url = self.construct_base_url_from_entity_id(idp_conf["entityid"]) samlfrontend = SAMLFrontend(lambda ctx, internal_req: (ctx, internal_req), internal_attributes, config, base_url, "saml_frontend") samlfrontend.register_endpoints(["saml"]) idp_metadata_str = create_metadata_from_config_dict(samlfrontend.idp_config) sp_conf["metadata"]["inline"].append(idp_metadata_str) fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False)) destination, auth_req = fakesp.make_auth_req( samlfrontend.idp_config["entityid"], nameid_format, relay_state, subject=subject, ) context.request = auth_req tmp_dict = {} for val in context.request: if isinstance(context.request[val], list): tmp_dict[val] = context.request[val][0] else: tmp_dict[val] = context.request[val] context.request = tmp_dict return samlfrontend
def setup_for_authn_req(self, context, idp_conf, sp_conf, nameid_format=None, relay_state="relay_state", internal_attributes=INTERNAL_ATTRIBUTES, extra_config={}): config = {"idp_config": idp_conf, "endpoints": ENDPOINTS} config.update(extra_config) sp_metadata_str = create_metadata_from_config_dict(sp_conf) idp_conf["metadata"]["inline"] = [sp_metadata_str] base_url = self.construct_base_url_from_entity_id(idp_conf["entityid"]) samlfrontend = SAMLFrontend(lambda ctx, internal_req: (ctx, internal_req), internal_attributes, config, base_url, "saml_frontend") samlfrontend.register_endpoints(["saml"]) idp_metadata_str = create_metadata_from_config_dict(samlfrontend.idp_config) sp_conf["metadata"]["inline"].append(idp_metadata_str) fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False)) destination, auth_req = fakesp.make_auth_req(samlfrontend.idp_config["entityid"], nameid_format, relay_state) context.request = auth_req tmp_dict = {} for val in context.request: if isinstance(context.request[val], list): tmp_dict[val] = context.request[val][0] else: tmp_dict[val] = context.request[val] context.request = tmp_dict return samlfrontend
def test_metadata_endpoint(self, context, idp_conf): conf = {"idp_config": idp_conf, "endpoints": ENDPOINTS} samlfrontend = SAMLFrontend(lambda ctx, req: None, INTERNAL_ATTRIBUTES, conf, "base_url", "saml_frontend") samlfrontend.register_endpoints(["todo"]) resp = samlfrontend._metadata_endpoint(context) headers = dict(resp.headers) assert headers["Content-Type"] == "text/xml" assert idp_conf["entityid"] in resp.message
def test_get_filter_attributes_with_sp_requested_attributes_without_friendlyname( self, idp_conf): sp_metadata_str = """<?xml version="1.0"?> <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://sp.example.com"> <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol"> <md:AttributeConsumingService> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> </md:AttributeConsumingService> </md:SPSSODescriptor> </md:EntityDescriptor> """ idp_conf["metadata"] = {"inline": [sp_metadata_str]} base_url = self.construct_base_url_from_entity_id(idp_conf["entityid"]) conf = {"idp_config": idp_conf, "endpoints": ENDPOINTS} internal_attributes = { "attributes": { attr_name.lower(): { "saml": [attr_name] } for attr_name in [ "eduPersonTargetedID", "eduPersonPrincipalName", "eduPersonAffiliation", "mail", "displayName", "sn", "givenName" ] } } # no op mapping for saml attribute names samlfrontend = SAMLFrontend(None, internal_attributes, conf, base_url, "saml_frontend") samlfrontend.register_endpoints(["testprovider"]) internal_req = InternalData( subject_type=NAMEID_FORMAT_PERSISTENT, requester="http://sp.example.com", requester_name="Example SP", ) filtered_attributes = samlfrontend._get_approved_attributes( samlfrontend.idp, samlfrontend.idp.config.getattr("policy", "idp"), internal_req.requester, None) assert set(filtered_attributes) == set([ "edupersontargetedid", "edupersonprincipalname", "edupersonaffiliation", "mail", "displayname", "sn", "givenname" ])
def test_get_filter_attributes_with_sp_requested_attributes_without_friendlyname(self, idp_conf): sp_metadata_str = """<?xml version="1.0"?> <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://sp.example.com"> <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol"> <md:AttributeConsumingService> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/> <md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> <md:RequestedAttribute Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/> </md:AttributeConsumingService> </md:SPSSODescriptor> </md:EntityDescriptor> """ idp_conf["metadata"] = {"inline": [sp_metadata_str]} base_url = self.construct_base_url_from_entity_id(idp_conf["entityid"]) conf = {"idp_config": idp_conf, "endpoints": ENDPOINTS} internal_attributes = {"attributes": {attr_name.lower(): {"saml": [attr_name]} for attr_name in ["eduPersonTargetedID", "eduPersonPrincipalName", "eduPersonAffiliation", "mail", "displayName", "sn", "givenName"]}} # no op mapping for saml attribute names samlfrontend = SAMLFrontend(None, internal_attributes, conf, base_url, "saml_frontend") samlfrontend.register_endpoints(["testprovider"]) internal_req = InternalData( subject_type=NAMEID_FORMAT_PERSISTENT, requester="http://sp.example.com", requester_name="Example SP", ) filtered_attributes = samlfrontend._get_approved_attributes(samlfrontend.idp, samlfrontend.idp.config.getattr( "policy", "idp"), internal_req.requester, None) assert set(filtered_attributes) == set(["edupersontargetedid", "edupersonprincipalname", "edupersonaffiliation", "mail", "displayname", "sn", "givenname"])
def test_register_endpoints(self, idp_conf): """ Tests the method register_endpoints """ def get_path_from_url(url): return urlparse(url).path.lstrip("/") config = {"idp_config": idp_conf, "endpoints": ENDPOINTS} base_url = self.construct_base_url_from_entity_id(idp_conf["entityid"]) samlfrontend = SAMLFrontend(lambda context, internal_req: (context, internal_req), INTERNAL_ATTRIBUTES, config, base_url, "saml_frontend") providers = ["foo", "bar"] url_map = samlfrontend.register_endpoints(providers) all_idp_endpoints = [get_path_from_url(v[0][0]) for v in idp_conf["service"]["idp"]["endpoints"].values()] compiled_regex = [re.compile(regex) for regex, _ in url_map] for endp in all_idp_endpoints: assert any(p.match(endp) for p in compiled_regex)
def test_config_error_handling(self, conf): with pytest.raises(ValueError): SAMLFrontend(lambda ctx, req: None, INTERNAL_ATTRIBUTES, conf, "base_url", "saml_frontend")