Fixed attribute filtering logic, take 2.

This commit is contained in:
Roland Hedberg
2014-06-03 09:28:11 +02:00
parent 884e75b1f5
commit 84a1453a35
7 changed files with 76 additions and 52 deletions

View File

@@ -497,19 +497,32 @@ class Policy(object):
:return: A possibly modified AVA :return: A possibly modified AVA
""" """
_rest = self.get_attribute_restrictions(sp_entity_id) _ava = None
if _rest is None:
_rest = self.get_entity_categories(sp_entity_id, mdstore)
logger.debug("filter based on: %s" % _rest)
_ava = filter_attribute_value_assertions(ava.copy(), _rest)
if required or optional: if required or optional:
logger.debug("required: %s, optional: %s" % (required, optional)) logger.debug("required: %s, optional: %s" % (required, optional))
ava1 = filter_on_attributes( _ava = filter_on_attributes(
ava.copy(), required, optional, self.acs, ava.copy(), required, optional, self.acs,
self.get_fail_on_missing_requested(sp_entity_id)) self.get_fail_on_missing_requested(sp_entity_id))
_ava.update(ava1)
_rest = self.get_entity_categories(sp_entity_id, mdstore)
if _rest:
ava_ec = filter_attribute_value_assertions(ava.copy(), _rest)
if _ava is None:
_ava = ava_ec
else:
_ava.update(ava_ec)
_rest = self.get_attribute_restrictions(sp_entity_id)
if _rest:
if _ava is None:
_ava = ava.copy()
_ava = filter_attribute_value_assertions(_ava, _rest)
elif _ava is None:
_ava = ava.copy()
if _ava is None:
return {}
else:
return _ava return _ava
def restrict(self, ava, sp_entity_id, metadata=None): def restrict(self, ava, sp_entity_id, metadata=None):
@@ -523,7 +536,7 @@ class Policy(object):
if metadata: if metadata:
spec = metadata.attribute_requirement(sp_entity_id) spec = metadata.attribute_requirement(sp_entity_id)
if spec: if spec:
ava = self.filter(ava, sp_entity_id, metadata, return self.filter(ava, sp_entity_id, metadata,
spec["required"], spec["optional"]) spec["required"], spec["optional"])
return self.filter(ava, sp_entity_id, metadata, [], []) return self.filter(ava, sp_entity_id, metadata, [], [])
@@ -757,5 +770,11 @@ class Assertion(dict):
policy.acs = self.acs policy.acs = self.acs
ava = policy.restrict(self, sp_entity_id, metadata) ava = policy.restrict(self, sp_entity_id, metadata)
self.update(ava)
for key, val in self.items():
if key in ava:
self[key] = ava[key]
else:
del self[key]
return ava return ava

View File

@@ -7,7 +7,8 @@ CONFIG = {
"service": { "service": {
"sp": { "sp": {
"endpoints": { "endpoints": {
"assertion_consumer_service": ["http://lingon.catalogix.se:8087/"], "assertion_consumer_service": [
"http://lingon.catalogix.se:8087/"],
}, },
"required_attributes": ["surName", "givenName", "mail"], "required_attributes": ["surName", "givenName", "mail"],
"optional_attributes": ["title"], "optional_attributes": ["title"],
@@ -39,7 +40,8 @@ CONFIG = {
"given_name": "Roland", "given_name": "Roland",
"sur_name": "Hedberg", "sur_name": "Hedberg",
"telephone_number": "+46 70 100 0000", "telephone_number": "+46 70 100 0000",
"email_address": ["tech@eample.com", "tech@example.org"], "email_address": ["tech@eample.com",
"tech@example.org"],
"contact_type": "technical" "contact_type": "technical"
}, },
], ],

View File

@@ -173,16 +173,20 @@ def test_ava_filter_2():
"mail": "derek@example.com"} "mail": "derek@example.com"}
# mail removed because it doesn't match the regular expression # mail removed because it doesn't match the regular expression
# So this should fail. _ava =policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp', None, [mail],
raises(MissingValue, policy.filter, ava, 'urn:mace:umu.se:saml:roland:sp', [gn, sn])
None, [mail], [gn, sn])
assert _eq(_ava.keys(), ["givenName", "surName"])
ava = {"givenName": "Derek", ava = {"givenName": "Derek",
"surName": "Jeter"} "surName": "Jeter"}
# it wasn't there to begin with # it wasn't there to begin with
raises(Exception, policy.filter, ava, 'urn:mace:umu.se:saml:roland:sp', try:
None, [gn, sn, mail]) policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp', None,
[gn, sn, mail])
except MissingValue:
pass
def test_ava_filter_dont_fail(): def test_ava_filter_dont_fail():
@@ -843,4 +847,4 @@ def test_assertion_with_authn_instant():
if __name__ == "__main__": if __name__ == "__main__":
test_ava_filter_dont_fail() test_assertion_2()

View File

@@ -64,7 +64,7 @@ def test_filter_ava2():
"default": { "default": {
"lifetime": {"minutes": 15}, "lifetime": {"minutes": 15},
#"attribute_restrictions": None # means all I have #"attribute_restrictions": None # means all I have
"entity_categories": ["edugain"] "entity_categories": ["refeds", "edugain"]
} }
}) })
@@ -158,7 +158,7 @@ def test_idp_policy_filter():
"norEduPersonNIN": "19800101134"} "norEduPersonNIN": "19800101134"}
policy = idp.config.getattr("policy", "idp") policy = idp.config.getattr("policy", "idp")
policy.filter(ava, "urn:mace:example.com:saml:roland:sp", idp.metadata) ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", idp.metadata)
print ava print ava
assert ava.keys() == ["eduPersonTargetedID"] # because no entity category assert ava.keys() == ["eduPersonTargetedID"] # because no entity category

View File

@@ -98,7 +98,7 @@ class TestResponse:
outstanding_queries={ outstanding_queries={
"bahigehogffohiphlfmplepdpcohkhhmheppcdie": "bahigehogffohiphlfmplepdpcohkhhmheppcdie":
"http://localhost:8088/sso"}, "http://localhost:8088/sso"},
timeslack=10000, decode=False) timeslack=1000000, decode=False)
assert isinstance(resp, StatusResponse) assert isinstance(resp, StatusResponse)
assert isinstance(resp, AuthnResponse) assert isinstance(resp, AuthnResponse)

View File

@@ -71,7 +71,7 @@ class TestAuthnResponse:
print self.ar.__dict__ print self.ar.__dict__
assert self.ar.came_from == 'http://localhost:8088/sso' assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id12" assert self.ar.session_id() == "id12"
assert self.ar.ava["eduPersonAffiliation"] == IDENTITY["eduPersonAffiliation"] assert self.ar.ava["givenName"] == IDENTITY["givenName"]
assert self.ar.name_id assert self.ar.name_id
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp' assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'

View File

@@ -227,18 +227,17 @@ class TestServer1():
assert assertion.attribute_statement assert assertion.attribute_statement
attribute_statement = assertion.attribute_statement attribute_statement = assertion.attribute_statement
print attribute_statement print attribute_statement
assert len(attribute_statement[0].attribute) == 5 assert len(attribute_statement[0].attribute) == 4
# Pick out one attribute # Pick out one attribute
attr = None attr = None
for attr in attribute_statement[0].attribute: for attr in attribute_statement[0].attribute:
if attr.friendly_name == "edupersonentitlement": if attr.friendly_name == "givenname":
break break
assert len(attr.attribute_value) == 1 assert len(attr.attribute_value) == 1
assert attr.name == "urn:oid:1.3.6.1.4.1.5923.1.1.1.7" assert attr.name == "urn:oid:2.5.4.42"
assert attr.name_format == "urn:oasis:names:tc:SAML:2" \ assert attr.name_format == "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
".0:attrname-format:uri"
value = attr.attribute_value[0] value = attr.attribute_value[0]
assert value.text.strip() == "Short stop" assert value.text.strip() == "Derek"
assert value.get_type() == "xs:string" assert value.get_type() == "xs:string"
assert assertion.subject assert assertion.subject
assert assertion.subject.name_id assert assertion.subject.name_id