Skip to content

Commit 4fcb94b

Browse files
author
Roland Hedberg
committed
Added a policy flag that if set to False will allow the IdP to send back an incomplete reply. Not containing attributes that the SP deemed important (that is marked required).
1 parent e449cd5 commit 4fcb94b

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

src/saml2/assertion.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,17 @@ def _match(attr, ava):
7878
return None
7979

8080

81-
def filter_on_attributes(ava, required=None, optional=None, acs=None):
81+
def filter_on_attributes(ava, required=None, optional=None, acs=None,
82+
fail_on_unfulfilled_requirements=True):
8283
""" Filter
8384
8485
:param ava: An attribute value assertion as a dictionary
8586
:param required: list of RequestedAttribute instances defined to be
8687
required
8788
:param optional: list of RequestedAttribute instances defined to be
8889
optional
90+
:param fail_on_unfulfilled_requirements: If required attributes
91+
are missing fail or fail not depending on this parameter.
8992
:return: The modified attribute value assertion
9093
"""
9194
res = {}
@@ -116,7 +119,7 @@ def filter_on_attributes(ava, required=None, optional=None, acs=None):
116119
values = []
117120
res[_fn] = _filter_values(ava[_fn], values, True)
118121
continue
119-
else:
122+
elif fail_on_unfulfilled_requirements:
120123
desc = "Required attribute missing: '%s' (%s)" % (attr["name"],
121124
_name)
122125
raise MissingValue(desc)
@@ -434,6 +437,16 @@ def get_attribute_restrictions(self, sp_entity_id):
434437

435438
return self.get("attribute_restrictions", sp_entity_id)
436439

440+
def get_fail_on_missing_requested(self, sp_entity_id):
441+
""" Return the whether the IdP should should fail if the SPs
442+
requested attributes could not be found.
443+
444+
:param sp_entity_id: The SP entity ID
445+
:return: The restrictions
446+
"""
447+
448+
return self.get("fail_on_missing_requested", sp_entity_id, True)
449+
437450
def entity_category_attributes(self, ec):
438451
if not self._restrictions:
439452
return None
@@ -492,7 +505,9 @@ def filter(self, ava, sp_entity_id, mdstore, required=None, optional=None):
492505

493506
if required or optional:
494507
logger.debug("required: %s, optional: %s" % (required, optional))
495-
ava = filter_on_attributes(ava, required, optional, self.acs)
508+
ava = filter_on_attributes(
509+
ava, required, optional, self.acs,
510+
self.get_fail_on_missing_requested(sp_entity_id))
496511

497512
return ava
498513

src/saml2/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,8 @@ def load_complex(self, cnf, typ="", metadata_construction=False):
269269
acs = ac_factory()
270270

271271
if not acs:
272-
raise ConfigurationError("No attribute converters, something is wrong!!")
272+
raise ConfigurationError(
273+
"No attribute converters, something is wrong!!")
273274

274275
_acs = self.getattr("attribute_converters", typ)
275276
if _acs:

tests/test_20_assertion.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ def test_ava_filter_2():
172172
"surName": "Jeter",
173173
"mail": "[email protected]"}
174174

175+
# mail removed because it doesn't match the regular expression
176+
# So this should fail.
175177
raises(MissingValue, policy.filter, ava, 'urn:mace:umu.se:saml:roland:sp',
176178
None, [mail], [gn, sn])
177179

@@ -183,6 +185,44 @@ def test_ava_filter_2():
183185
None, [gn, sn, mail])
184186

185187

188+
def test_ava_filter_dont_fail():
189+
conf = {
190+
"default": {
191+
"lifetime": {"minutes": 15},
192+
"attribute_restrictions": None, # means all I have
193+
},
194+
"urn:mace:umu.se:saml:roland:sp": {
195+
"lifetime": {"minutes": 5},
196+
"attribute_restrictions": {
197+
"givenName": None,
198+
"surName": None,
199+
"mail": [".*@.*\.umu\.se"],
200+
},
201+
"fail_on_missing_requested": False
202+
}}
203+
204+
policy = Policy(conf)
205+
206+
ava = {"givenName": "Derek",
207+
"surName": "Jeter",
208+
"mail": "[email protected]"}
209+
210+
# mail removed because it doesn't match the regular expression
211+
# So it should fail if the 'fail_on_ ...' flag wasn't set
212+
_ava = policy.filter(ava,'urn:mace:umu.se:saml:roland:sp', None,
213+
[mail], [gn, sn])
214+
215+
assert _ava
216+
217+
ava = {"givenName": "Derek",
218+
"surName": "Jeter"}
219+
220+
# it wasn't there to begin with
221+
_ava = policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp',
222+
None, [gn, sn, mail])
223+
224+
assert _ava
225+
186226
def test_filter_attribute_value_assertions_0(AVA):
187227
p = Policy({
188228
"default": {
@@ -802,4 +842,4 @@ def test_assertion_with_authn_instant():
802842

803843

804844
if __name__ == "__main__":
805-
test_assertion_2()
845+
test_ava_filter_dont_fail()

0 commit comments

Comments
 (0)