authentik.sources.saml.tests.test_property_mappings
SAML Source tests
1"""SAML Source tests""" 2 3from base64 import b64encode 4 5from defusedxml.lxml import fromstring 6from django.test import TestCase 7 8from authentik.common.saml.constants import NS_SAML_ASSERTION 9from authentik.core.tests.utils import RequestFactory, create_test_flow 10from authentik.lib.generators import generate_id 11from authentik.lib.tests.utils import load_fixture 12from authentik.sources.saml.models import SAMLSource, SAMLSourcePropertyMapping 13from authentik.sources.saml.processors.response import ResponseProcessor 14 15ROOT = fromstring(load_fixture("fixtures/response_success.xml").encode()) 16ROOT_GROUPS = fromstring(load_fixture("fixtures/response_success_groups.xml").encode()) 17NAME_ID = ( 18 ROOT.find(f"{{{NS_SAML_ASSERTION}}}Assertion") 19 .find(f"{{{NS_SAML_ASSERTION}}}Subject") 20 .find(f"{{{NS_SAML_ASSERTION}}}NameID") 21) 22 23 24class TestPropertyMappings(TestCase): 25 """Test Property Mappings""" 26 27 def setUp(self): 28 self.factory = RequestFactory() 29 self.source = SAMLSource.objects.create( 30 name=generate_id(), 31 slug=generate_id(), 32 issuer="authentik", 33 allow_idp_initiated=True, 34 pre_authentication_flow=create_test_flow(), 35 ) 36 37 def test_user_base_properties(self): 38 """Test user base properties""" 39 properties = self.source.get_base_user_properties( 40 root=ROOT, assertion=ROOT.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), name_id=NAME_ID 41 ) 42 self.assertEqual( 43 properties, 44 { 45 "email": "foo@bar.baz", 46 "name": "foo", 47 "sn": "bar", 48 "username": "jens@goauthentik.io", 49 }, 50 ) 51 52 def test_group_base_properties(self): 53 """Test group base properties""" 54 properties = self.source.get_base_user_properties( 55 root=ROOT_GROUPS, 56 assertion=ROOT_GROUPS.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), 57 name_id=NAME_ID, 58 ) 59 self.assertEqual(properties["groups"], ["group 1", "group 2"]) 60 for group_id in ["group 1", "group 2"]: 61 properties = self.source.get_base_group_properties(root=ROOT, group_id=group_id) 62 self.assertEqual(properties, {"name": group_id}) 63 64 def test_user_property_mappings(self): 65 """Test user property mappings""" 66 self.source.user_property_mappings.add( 67 SAMLSourcePropertyMapping.objects.create( 68 name="test", 69 expression="return {'attributes': {'department': 'Engineering'}, 'sn': None}", 70 ) 71 ) 72 request = self.factory.post( 73 "/", 74 data={ 75 "SAMLResponse": b64encode( 76 load_fixture("fixtures/response_success.xml").encode() 77 ).decode() 78 }, 79 ) 80 81 parser = ResponseProcessor(self.source, request) 82 parser.parse() 83 sfm = parser.prepare_flow_manager() 84 self.assertEqual( 85 sfm.user_properties, 86 { 87 "email": "foo@bar.baz", 88 "name": "foo", 89 "username": "jens@goauthentik.io", 90 "attributes": { 91 "department": "Engineering", 92 }, 93 "path": self.source.get_user_path(), 94 }, 95 ) 96 97 def test_group_property_mappings(self): 98 """Test group property mappings""" 99 self.source.group_property_mappings.add( 100 SAMLSourcePropertyMapping.objects.create( 101 name="test", 102 expression="return {'attributes': {'id': group_id}}", 103 ) 104 ) 105 request = self.factory.post( 106 "/", 107 data={ 108 "SAMLResponse": b64encode( 109 load_fixture("fixtures/response_success_groups.xml").encode() 110 ).decode() 111 }, 112 ) 113 114 parser = ResponseProcessor(self.source, request) 115 parser.parse() 116 sfm = parser.prepare_flow_manager() 117 self.assertEqual( 118 sfm.groups_properties, 119 { 120 "group 1": { 121 "name": "group 1", 122 "attributes": { 123 "id": "group 1", 124 }, 125 }, 126 "group 2": { 127 "name": "group 2", 128 "attributes": { 129 "id": "group 2", 130 }, 131 }, 132 }, 133 )
ROOT =
<Element {urn:oasis:names:tc:SAML:2.0:protocol}Response>
ROOT_GROUPS =
<Element {urn:oasis:names:tc:SAML:2.0:protocol}Response>
NAME_ID =
<Element {urn:oasis:names:tc:SAML:2.0:assertion}NameID>
class
TestPropertyMappings(django.test.testcases.TestCase):
25class TestPropertyMappings(TestCase): 26 """Test Property Mappings""" 27 28 def setUp(self): 29 self.factory = RequestFactory() 30 self.source = SAMLSource.objects.create( 31 name=generate_id(), 32 slug=generate_id(), 33 issuer="authentik", 34 allow_idp_initiated=True, 35 pre_authentication_flow=create_test_flow(), 36 ) 37 38 def test_user_base_properties(self): 39 """Test user base properties""" 40 properties = self.source.get_base_user_properties( 41 root=ROOT, assertion=ROOT.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), name_id=NAME_ID 42 ) 43 self.assertEqual( 44 properties, 45 { 46 "email": "foo@bar.baz", 47 "name": "foo", 48 "sn": "bar", 49 "username": "jens@goauthentik.io", 50 }, 51 ) 52 53 def test_group_base_properties(self): 54 """Test group base properties""" 55 properties = self.source.get_base_user_properties( 56 root=ROOT_GROUPS, 57 assertion=ROOT_GROUPS.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), 58 name_id=NAME_ID, 59 ) 60 self.assertEqual(properties["groups"], ["group 1", "group 2"]) 61 for group_id in ["group 1", "group 2"]: 62 properties = self.source.get_base_group_properties(root=ROOT, group_id=group_id) 63 self.assertEqual(properties, {"name": group_id}) 64 65 def test_user_property_mappings(self): 66 """Test user property mappings""" 67 self.source.user_property_mappings.add( 68 SAMLSourcePropertyMapping.objects.create( 69 name="test", 70 expression="return {'attributes': {'department': 'Engineering'}, 'sn': None}", 71 ) 72 ) 73 request = self.factory.post( 74 "/", 75 data={ 76 "SAMLResponse": b64encode( 77 load_fixture("fixtures/response_success.xml").encode() 78 ).decode() 79 }, 80 ) 81 82 parser = ResponseProcessor(self.source, request) 83 parser.parse() 84 sfm = parser.prepare_flow_manager() 85 self.assertEqual( 86 sfm.user_properties, 87 { 88 "email": "foo@bar.baz", 89 "name": "foo", 90 "username": "jens@goauthentik.io", 91 "attributes": { 92 "department": "Engineering", 93 }, 94 "path": self.source.get_user_path(), 95 }, 96 ) 97 98 def test_group_property_mappings(self): 99 """Test group property mappings""" 100 self.source.group_property_mappings.add( 101 SAMLSourcePropertyMapping.objects.create( 102 name="test", 103 expression="return {'attributes': {'id': group_id}}", 104 ) 105 ) 106 request = self.factory.post( 107 "/", 108 data={ 109 "SAMLResponse": b64encode( 110 load_fixture("fixtures/response_success_groups.xml").encode() 111 ).decode() 112 }, 113 ) 114 115 parser = ResponseProcessor(self.source, request) 116 parser.parse() 117 sfm = parser.prepare_flow_manager() 118 self.assertEqual( 119 sfm.groups_properties, 120 { 121 "group 1": { 122 "name": "group 1", 123 "attributes": { 124 "id": "group 1", 125 }, 126 }, 127 "group 2": { 128 "name": "group 2", 129 "attributes": { 130 "id": "group 2", 131 }, 132 }, 133 }, 134 )
Test Property Mappings
def
setUp(self):
28 def setUp(self): 29 self.factory = RequestFactory() 30 self.source = SAMLSource.objects.create( 31 name=generate_id(), 32 slug=generate_id(), 33 issuer="authentik", 34 allow_idp_initiated=True, 35 pre_authentication_flow=create_test_flow(), 36 )
Hook method for setting up the test fixture before exercising it.
def
test_user_base_properties(self):
38 def test_user_base_properties(self): 39 """Test user base properties""" 40 properties = self.source.get_base_user_properties( 41 root=ROOT, assertion=ROOT.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), name_id=NAME_ID 42 ) 43 self.assertEqual( 44 properties, 45 { 46 "email": "foo@bar.baz", 47 "name": "foo", 48 "sn": "bar", 49 "username": "jens@goauthentik.io", 50 }, 51 )
Test user base properties
def
test_group_base_properties(self):
53 def test_group_base_properties(self): 54 """Test group base properties""" 55 properties = self.source.get_base_user_properties( 56 root=ROOT_GROUPS, 57 assertion=ROOT_GROUPS.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), 58 name_id=NAME_ID, 59 ) 60 self.assertEqual(properties["groups"], ["group 1", "group 2"]) 61 for group_id in ["group 1", "group 2"]: 62 properties = self.source.get_base_group_properties(root=ROOT, group_id=group_id) 63 self.assertEqual(properties, {"name": group_id})
Test group base properties
def
test_user_property_mappings(self):
65 def test_user_property_mappings(self): 66 """Test user property mappings""" 67 self.source.user_property_mappings.add( 68 SAMLSourcePropertyMapping.objects.create( 69 name="test", 70 expression="return {'attributes': {'department': 'Engineering'}, 'sn': None}", 71 ) 72 ) 73 request = self.factory.post( 74 "/", 75 data={ 76 "SAMLResponse": b64encode( 77 load_fixture("fixtures/response_success.xml").encode() 78 ).decode() 79 }, 80 ) 81 82 parser = ResponseProcessor(self.source, request) 83 parser.parse() 84 sfm = parser.prepare_flow_manager() 85 self.assertEqual( 86 sfm.user_properties, 87 { 88 "email": "foo@bar.baz", 89 "name": "foo", 90 "username": "jens@goauthentik.io", 91 "attributes": { 92 "department": "Engineering", 93 }, 94 "path": self.source.get_user_path(), 95 }, 96 )
Test user property mappings
def
test_group_property_mappings(self):
98 def test_group_property_mappings(self): 99 """Test group property mappings""" 100 self.source.group_property_mappings.add( 101 SAMLSourcePropertyMapping.objects.create( 102 name="test", 103 expression="return {'attributes': {'id': group_id}}", 104 ) 105 ) 106 request = self.factory.post( 107 "/", 108 data={ 109 "SAMLResponse": b64encode( 110 load_fixture("fixtures/response_success_groups.xml").encode() 111 ).decode() 112 }, 113 ) 114 115 parser = ResponseProcessor(self.source, request) 116 parser.parse() 117 sfm = parser.prepare_flow_manager() 118 self.assertEqual( 119 sfm.groups_properties, 120 { 121 "group 1": { 122 "name": "group 1", 123 "attributes": { 124 "id": "group 1", 125 }, 126 }, 127 "group 2": { 128 "name": "group 2", 129 "attributes": { 130 "id": "group 2", 131 }, 132 }, 133 }, 134 )
Test group property mappings