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

Test Property Mappings

def setUp(self):
29    def setUp(self):
30        self.factory = RequestFactory()
31        self.source = SAMLSource.objects.create(
32            name=generate_id(),
33            slug=generate_id(),
34            issuer="authentik",
35            allow_idp_initiated=True,
36            pre_authentication_flow=create_test_flow(),
37        )

Hook method for setting up the test fixture before exercising it.

@freeze_time('2022-10-14T14:15:00')
def test_user_base_properties(self):
39    @freeze_time("2022-10-14T14:15:00")
40    def test_user_base_properties(self):
41        """Test user base properties"""
42        properties = self.source.get_base_user_properties(
43            root=ROOT, assertion=ROOT.find(f"{{{NS_SAML_ASSERTION}}}Assertion"), name_id=NAME_ID
44        )
45        self.assertEqual(
46            properties,
47            {
48                "email": "foo@bar.baz",
49                "name": "foo",
50                "sn": "bar",
51                "username": "jens@goauthentik.io",
52            },
53        )

Test user base properties

def test_group_base_properties(self):
55    def test_group_base_properties(self):
56        """Test group base properties"""
57        properties = self.source.get_base_user_properties(
58            root=ROOT_GROUPS,
59            assertion=ROOT_GROUPS.find(f"{{{NS_SAML_ASSERTION}}}Assertion"),
60            name_id=NAME_ID,
61        )
62        self.assertEqual(properties["groups"], ["group 1", "group 2"])
63        for group_id in ["group 1", "group 2"]:
64            properties = self.source.get_base_group_properties(root=ROOT, group_id=group_id)
65            self.assertEqual(properties, {"name": group_id})

Test group base properties

@freeze_time('2022-10-14T14:15:00')
def test_user_property_mappings(self):
67    @freeze_time("2022-10-14T14:15:00")
68    def test_user_property_mappings(self):
69        """Test user property mappings"""
70        self.source.user_property_mappings.add(
71            SAMLSourcePropertyMapping.objects.create(
72                name="test",
73                expression="return {'attributes': {'department': 'Engineering'}, 'sn': None}",
74            )
75        )
76        request = self.factory.post(
77            "/",
78            data={
79                "SAMLResponse": b64encode(
80                    load_fixture("fixtures/response_success.xml").encode()
81                ).decode()
82            },
83        )
84
85        parser = ResponseProcessor(self.source, request)
86        parser.parse()
87        sfm = parser.prepare_flow_manager()
88        self.assertEqual(
89            sfm.user_properties,
90            {
91                "email": "foo@bar.baz",
92                "name": "foo",
93                "username": "jens@goauthentik.io",
94                "attributes": {
95                    "department": "Engineering",
96                },
97                "path": self.source.get_user_path(),
98            },
99        )

Test user property mappings

@freeze_time('2022-10-14T14:15:00')
def test_group_property_mappings(self):
101    @freeze_time("2022-10-14T14:15:00")
102    def test_group_property_mappings(self):
103        """Test group property mappings"""
104        self.source.group_property_mappings.add(
105            SAMLSourcePropertyMapping.objects.create(
106                name="test",
107                expression="return {'attributes': {'id': group_id}}",
108            )
109        )
110        request = self.factory.post(
111            "/",
112            data={
113                "SAMLResponse": b64encode(
114                    load_fixture("fixtures/response_success_groups.xml").encode()
115                ).decode()
116            },
117        )
118
119        parser = ResponseProcessor(self.source, request)
120        parser.parse()
121        sfm = parser.prepare_flow_manager()
122        self.assertEqual(
123            sfm.groups_properties,
124            {
125                "group 1": {
126                    "name": "group 1",
127                    "attributes": {
128                        "id": "group 1",
129                    },
130                },
131                "group 2": {
132                    "name": "group 2",
133                    "attributes": {
134                        "id": "group 2",
135                    },
136                },
137            },
138        )

Test group property mappings