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