Skip to content

Commit d655fc9

Browse files
Merge pull request #613 from skoranda/more_flexible_entity_category_import
Make entity category imports more flexible
2 parents 1d06338 + 15bdc66 commit d655fc9

File tree

4 files changed

+144
-2
lines changed

4 files changed

+144
-2
lines changed

src/saml2/assertion.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,11 @@ def compile(self, restrictions):
353353
else:
354354
ecs = []
355355
for cat in items:
356-
_mod = importlib.import_module(
357-
"saml2.entity_category.%s" % cat)
356+
try:
357+
_mod = importlib.import_module(cat)
358+
except ImportError:
359+
_mod = importlib.import_module(
360+
"saml2.entity_category.%s" % cat)
358361
_ec = {}
359362
for key, items in _mod.RELEASE.items():
360363
alist = [k.lower() for k in items]

tests/entity_cat_rs.xml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata"
3+
xmlns:xs="http://www.w3.org/2001/XMLSchema"
4+
xmlns:ns1="urn:oasis:names:tc:SAML:metadata:attribute"
5+
xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion"
6+
xmlns:ns5="http://www.w3.org/2000/09/xmldsig#"
7+
xmlns:ns4="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
8+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
entityID="urn:mace:example.com:saml:roland:sp">
10+
<ns0:Extensions>
11+
<ns1:EntityAttributes>
12+
<ns2:Attribute Name="http://macedir.org/entity-category">
13+
<ns2:AttributeValue xsi:type="xs:string">
14+
http://refeds.org/category/research-and-scholarship
15+
</ns2:AttributeValue>
16+
</ns2:Attribute>
17+
</ns1:EntityAttributes>
18+
</ns0:Extensions>
19+
<ns0:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true"
20+
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
21+
<ns0:Extensions>
22+
<ns4:DiscoveryResponse
23+
Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
24+
Location="https://xenosmilus2.umdc.umu.se:8086/disco"
25+
index="1"/>
26+
</ns0:Extensions>
27+
<ns0:KeyDescriptor use="encryption">
28+
<ns5:KeyInfo>
29+
<ns5:X509Data>
30+
<ns5:X509Certificate>
31+
MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV
32+
BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx
33+
EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz
34+
MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l
35+
YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw
36+
DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7
37+
bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC
38+
FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR
39+
mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW
40+
BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9
41+
o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW
42+
BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE
43+
AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
44+
BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO
45+
zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN
46+
+vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI=
47+
</ns5:X509Certificate>
48+
</ns5:X509Data>
49+
</ns5:KeyInfo>
50+
</ns0:KeyDescriptor>
51+
<ns0:KeyDescriptor use="signing">
52+
<ns5:KeyInfo>
53+
<ns5:X509Data>
54+
<ns5:X509Certificate>
55+
MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV
56+
BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx
57+
EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz
58+
MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l
59+
YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw
60+
DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7
61+
bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC
62+
FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR
63+
mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW
64+
BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9
65+
o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW
66+
BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE
67+
AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
68+
BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO
69+
zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN
70+
+vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI=
71+
</ns5:X509Certificate>
72+
</ns5:X509Data>
73+
</ns5:KeyInfo>
74+
</ns0:KeyDescriptor>
75+
<ns0:AssertionConsumerService
76+
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
77+
Location="https://xenosmilus2.umdc.umu.se:8086/acs/sfs/re_nren/redirect"
78+
index="1"/>
79+
<ns0:AssertionConsumerService
80+
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
81+
Location="https://xenosmilus2.umdc.umu.se:8086/acs/sfs/re_nren/post"
82+
index="2"/>
83+
</ns0:SPSSODescriptor>
84+
</ns0:EntityDescriptor>

tests/myentitycategory.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CUSTOM_R_AND_S = ['eduPersonTargetedID',
2+
'eduPersonPrincipalName',
3+
'mail',
4+
'displayName',
5+
'givenName',
6+
'sn',
7+
'eduPersonScopedAffiliation',
8+
'eduPersonUniqueId'
9+
]
10+
11+
RESEARCH_AND_SCHOLARSHIP = "http://refeds.org/category/research-and-scholarship"
12+
13+
RELEASE = {
14+
"": ["eduPersonTargetedID"],
15+
RESEARCH_AND_SCHOLARSHIP: CUSTOM_R_AND_S,
16+
}

tests/test_37_entity_categories.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,5 +152,44 @@ def test_idp_policy_filter():
152152
"eduPersonTargetedID"] # because no entity category
153153

154154

155+
def test_entity_category_import_from_path():
156+
# The entity category module myentitycategory.py is in the tests
157+
# directory which is on the standard module search path.
158+
# The module uses a custom interpretation of the REFEDs R&S entity category
159+
# by adding eduPersonUniqueId.
160+
policy = Policy({
161+
"default": {
162+
"lifetime": {"minutes": 15},
163+
"entity_categories": ["myentitycategory"]
164+
}
165+
})
166+
167+
mds = MetadataStore(ATTRCONV, sec_config,
168+
disable_ssl_certificate_validation=True)
169+
170+
# The file entity_cat_rs.xml contains the SAML metadata for an SP
171+
# tagged with the REFEDs R&S entity category.
172+
mds.imp([{"class": "saml2.mdstore.MetaDataFile",
173+
"metadata": [(full_path("entity_cat_rs.xml"),)]}])
174+
175+
ava = {"givenName": ["Derek"], "sn": ["Jeter"],
176+
"displayName": "Derek Jeter",
177+
"mail": ["[email protected]"], "c": ["USA"],
178+
"eduPersonTargetedID": "foo!bar!xyz",
179+
"eduPersonUniqueId": "[email protected]",
180+
"eduPersonScopedAffiliation": "[email protected]",
181+
"eduPersonPrincipalName": "[email protected]",
182+
"norEduPersonNIN": "19800101134"}
183+
184+
ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", mds)
185+
186+
# We expect c and norEduPersonNIN to be filtered out since they are not
187+
# part of the custom entity category.
188+
assert _eq(list(ava.keys()),
189+
["eduPersonTargetedID", "eduPersonPrincipalName",
190+
"eduPersonUniqueId", "displayName", "givenName",
191+
"eduPersonScopedAffiliation", "mail", "sn"])
192+
193+
155194
if __name__ == "__main__":
156195
test_filter_ava3()

0 commit comments

Comments
 (0)