def test_mapping_from_deeply_nested_attribute(self): mapping = { "attributes": { "address": { "openid": ["address.formatted.text.value"], "saml": ["postaladdress"] }, }, } data = { "address": { "formatted": { "text": { "value": ["100 Universal City Plaza, Hollywood CA 91608, USA"] } } } } converter = DataConverter(mapping) internal_repr = converter.to_internal("openid", data) external_repr = converter.from_internal("saml", internal_repr) assert external_repr["postaladdress"] == data["address"]["formatted"][ "text"]["value"]
def __init__(self, internal_attributes): super(AddStaticAttributes, self).__init__() self.data_converter = DataConverter(internal_attributes) mapping_file = os.environ.get("SATOSA_STATIC_ATTRIBUTES") if not mapping_file: raise ValueError( "Could not find file containing mapping of static attributes.") with open(mapping_file) as f: self.static_attributes = yaml.safe_load(f)
def test_to_internal_with_missing_attribute_value(self): mapping = { "attributes": { "mail": { "p1": ["emailaddress"], }, } } converter = DataConverter(mapping) internal_repr = converter.to_internal("p1", {}) assert not internal_repr
def test_to_internal_same_attribute_value_from_list_and_single_value(self, attribute_value): mapping = { "attributes": { "mail": { "foo": ["email"], }, }, } converter = DataConverter(mapping) internal_repr = converter.to_internal("foo", attribute_value) assert internal_repr["mail"] == ["*****@*****.**"]
def test_to_internal_same_attribute_value_from_list_and_single_value( self, attribute_value): mapping = { "attributes": { "mail": { "foo": ["email"], }, }, } converter = DataConverter(mapping) internal_repr = converter.to_internal("foo", attribute_value) assert internal_repr["mail"] == ["*****@*****.**"]
def test_map_one_source_attribute_to_multiple_internal_attributes(self): mapping = { "attributes": { "mail": { "p1": ["email"], }, "identifier": { "p1": ["email"], }, }, } converter = DataConverter(mapping) internal_repr = converter.to_internal("p1", {"email": ["*****@*****.**"]}) assert internal_repr == {"mail": ["*****@*****.**"], "identifier": ["*****@*****.**"]}
def test_to_internal_filter_case_insensitive(self): mapping = { "attributes": { "mail": { "p1": ["emailaddress"], }, "identifier": { "p1": ["uid"], }, }, } converter = DataConverter(mapping) filter = converter.to_internal_filter("p1", ["Uid", "eMaILAdDreSS"], True) assert Counter(filter) == Counter(["mail", "identifier"])
def test_to_internal_filter(self): mapping = { "attributes": { "mail": { "p1": ["email"], }, "identifier": { "p1": ["uid"], }, }, } converter = DataConverter(mapping) filter = converter.to_internal_filter("p1", ["uid", "email"], False) assert Counter(filter) == Counter(["mail", "identifier"])
def test_to_internal_filter_profile_missing_attribute_mapping(self): mapping = { "attributes": { "mail": { "foo": ["email"], }, "id": { "foo": ["id"], "bar": ["uid"], } }, } converter = DataConverter(mapping) filter = converter.to_internal_filter("bar", ["email", "uid"]) assert Counter(filter) == Counter(["id"])
class AddStaticAttributes(ResponseMicroService): """ Add static attributes to the responses. The path to the file describing the mapping (as YAML) of static attributes must be specified with the environment variable 'SATOSA_STATIC_ATTRIBUTES'. """ def __init__(self, internal_attributes): super(AddStaticAttributes, self).__init__() self.data_converter = DataConverter(internal_attributes) mapping_file = os.environ.get("SATOSA_STATIC_ATTRIBUTES") if not mapping_file: raise ValueError( "Could not find file containing mapping of static attributes.") with open(mapping_file) as f: self.static_attributes = yaml.safe_load(f) def process(self, context, data): all_attributes = data.get_attributes() all_attributes.update( self.data_converter.to_internal("saml", self.static_attributes)) data.add_attributes(all_attributes) return data
def test_to_internal_profile_missing_attribute_mapping(self): mapping = { "attributes": { "mail": { "foo": ["email"], }, "id": { "foo": ["id"], "bar": ["uid"], } }, } converter = DataConverter(mapping) internal_repr = converter.to_internal("bar", {"email": ["*****@*****.**"], "uid": ["uid"]}) assert "mail" not in internal_repr # no mapping for the 'mail' attribute in the 'bar' profile assert internal_repr["id"] == ["uid"]
def test_mapping_to_nested_attribute(self): mapping = { "attributes": { "address": { "openid": ["address.formatted"], "saml": ["postaladdress"] }, }, } data = { "postaladdress": ["100 Universal City Plaza, Hollywood CA 91608, USA"] } converter = DataConverter(mapping) internal_repr = converter.to_internal("saml", data) external_repr = converter.from_internal("openid", internal_repr) assert external_repr["address"]["formatted"] == data["postaladdress"]
def test_map_one_source_attribute_to_multiple_internal_attributes(self): mapping = { "attributes": { "mail": { "p1": ["email"], }, "identifier": { "p1": ["email"], }, }, } converter = DataConverter(mapping) internal_repr = converter.to_internal("p1", {"email": ["*****@*****.**"]}) assert internal_repr == { "mail": ["*****@*****.**"], "identifier": ["*****@*****.**"] }
def __init__(self, internal_attributes): super(AddStaticAttributes, self).__init__() self.data_converter = DataConverter(internal_attributes) mapping_file = os.environ.get("SATOSA_STATIC_ATTRIBUTES") if not mapping_file: raise ValueError("Could not find file containing mapping of static attributes.") with open(mapping_file) as f: self.static_attributes = yaml.safe_load(f)
def test_to_internal_profile_missing_attribute_mapping(self): mapping = { "attributes": { "mail": { "foo": ["email"], }, "id": { "foo": ["id"], "bar": ["uid"], } }, } converter = DataConverter(mapping) internal_repr = converter.to_internal("bar", { "email": ["*****@*****.**"], "uid": ["uid"] }) assert "mail" not in internal_repr # no mapping for the 'mail' attribute in the 'bar' profile assert internal_repr["id"] == ["uid"]
def __init__(self, auth_req_callback_func, internal_attributes): """ :type auth_req_callback_func: (satosa.context.Context, satosa.internal_data.InternalData) -> satosa.response.Response :type internal_attributes: dict[str, dict[str, str | list[str]]] :param auth_req_callback_func: Callback should be called by the module after the authorization response has been processed. """ self.auth_req_callback_func = auth_req_callback_func self.internal_attrbiutes = internal_attributes self.converter = DataConverter(internal_attributes)
def test_multiple_source_attribute_values(self): mapping = { "attributes": { "mail": { "saml": ["mail", "emailAddress", "email"] }, }, } data = { "mail": ["*****@*****.**"], "email": ["*****@*****.**"], "emailAddress": ["*****@*****.**"], } expected = Counter(["*****@*****.**", "*****@*****.**", "*****@*****.**"]) converter = DataConverter(mapping) internal_repr = converter.to_internal("saml", data) assert Counter(internal_repr["mail"]) == expected external_repr = converter.from_internal("saml", internal_repr) assert Counter(external_repr[mapping["attributes"]["mail"]["saml"][0]]) == expected
def __init__(self, auth_callback_func, internal_attributes): """ :type auth_callback_func: (satosa.context.Context, satosa.internal_data.InternalResponse) -> satosa.response.Response :type internal_attributes: dict[string, dict[str, str | list[str]]] :param auth_callback_func: Callback should be called by the module after the authorization in the backend is done. :param internal_attributes: Mapping dictionary between SATOSA internal attribute names and the names returned by underlying IdP's/OP's as well as what attributes the calling SP's and RP's expects namevice. """ self.auth_callback_func = auth_callback_func self.internal_attributes = internal_attributes self.converter = DataConverter(internal_attributes)
def test_multiple_source_attribute_values(self): mapping = { "attributes": { "mail": { "saml": ["mail", "emailAddress", "email"] }, }, } data = { "mail": ["*****@*****.**"], "email": ["*****@*****.**"], "emailAddress": ["*****@*****.**"], } expected = Counter( ["*****@*****.**", "*****@*****.**", "*****@*****.**"]) converter = DataConverter(mapping) internal_repr = converter.to_internal("saml", data) assert Counter(internal_repr["mail"]) == expected external_repr = converter.from_internal("saml", internal_repr) assert Counter(external_repr[mapping["attributes"]["mail"]["saml"] [0]]) == expected
def test_nested_attribute_to_internal(self): mapping = { "attributes": { "address": { "openid": ["address.formatted"], }, }, } data = { "address": { "formatted": ["100 Universal City Plaza, Hollywood CA 91608, USA"] } } internal_repr = DataConverter(mapping).to_internal("openid", data) assert internal_repr["address"] == data["address"]["formatted"]
class AddStaticAttributes(ResponseMicroService): """ Add static attributes to the responses. The path to the file describing the mapping (as YAML) of static attributes must be specified with the environment variable 'SATOSA_STATIC_ATTRIBUTES'. """ def __init__(self, internal_attributes): super(AddStaticAttributes, self).__init__() self.data_converter = DataConverter(internal_attributes) mapping_file = os.environ.get("SATOSA_STATIC_ATTRIBUTES") if not mapping_file: raise ValueError("Could not find file containing mapping of static attributes.") with open(mapping_file) as f: self.static_attributes = yaml.safe_load(f) def process(self, context, data): all_attributes = data.get_attributes() all_attributes.update(self.data_converter.to_internal("saml", self.static_attributes)) data.add_attributes(all_attributes) return data