authentik.providers.oauth2.tests.test_userinfo

Test userinfo view

  1"""Test userinfo view"""
  2
  3import json
  4from dataclasses import asdict
  5
  6from django.urls import reverse
  7from django.utils import timezone
  8
  9from authentik.blueprints.tests import apply_blueprint
 10from authentik.core.models import Application
 11from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
 12from authentik.events.models import Event, EventAction
 13from authentik.lib.generators import generate_id
 14from authentik.providers.oauth2.id_token import IDToken
 15from authentik.providers.oauth2.models import (
 16    AccessToken,
 17    OAuth2Provider,
 18    RedirectURI,
 19    RedirectURIMatchingMode,
 20    ScopeMapping,
 21)
 22from authentik.providers.oauth2.tests.utils import OAuthTestCase
 23
 24
 25class TestUserinfo(OAuthTestCase):
 26    """Test token view"""
 27
 28    @apply_blueprint("system/providers-oauth2.yaml")
 29    def setUp(self) -> None:
 30        super().setUp()
 31        self.app = Application.objects.create(name=generate_id(), slug=generate_id())
 32        self.provider: OAuth2Provider = OAuth2Provider.objects.create(
 33            name=generate_id(),
 34            authorization_flow=create_test_flow(),
 35            redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "")],
 36            signing_key=create_test_cert(),
 37        )
 38        self.provider.property_mappings.set(ScopeMapping.objects.all())
 39        # Needs to be assigned to an application for iss to be set
 40        self.app.provider = self.provider
 41        self.app.save()
 42        self.user = create_test_admin_user()
 43        self.token: AccessToken = AccessToken.objects.create(
 44            provider=self.provider,
 45            user=self.user,
 46            token=generate_id(),
 47            auth_time=timezone.now(),
 48            _scope="openid user profile",
 49            _id_token=json.dumps(
 50                asdict(
 51                    IDToken("foo", "bar"),
 52                )
 53            ),
 54        )
 55
 56    def test_userinfo_normal(self):
 57        """test user info with all normal scopes"""
 58        res = self.client.get(
 59            reverse("authentik_providers_oauth2:userinfo"),
 60            HTTP_AUTHORIZATION=f"Bearer {self.token.token}",
 61        )
 62        self.assertJSONEqual(
 63            res.content.decode(),
 64            {
 65                "name": self.user.name,
 66                "given_name": self.user.name,
 67                "preferred_username": self.user.name,
 68                "nickname": self.user.name,
 69                "groups": [group.name for group in self.user.groups.all()],
 70                "sub": "bar",
 71            },
 72        )
 73        self.assertEqual(res.status_code, 200)
 74
 75    def test_userinfo_invalid_scope(self):
 76        """test user info with a broken scope"""
 77        scope = ScopeMapping.objects.create(name="test", scope_name="openid", expression="q")
 78        self.provider.property_mappings.add(scope)
 79
 80        res = self.client.get(
 81            reverse("authentik_providers_oauth2:userinfo"),
 82            HTTP_AUTHORIZATION=f"Bearer {self.token.token}",
 83        )
 84        self.assertJSONEqual(
 85            res.content.decode(),
 86            {
 87                "name": self.user.name,
 88                "given_name": self.user.name,
 89                "preferred_username": self.user.name,
 90                "nickname": self.user.name,
 91                "groups": [group.name for group in self.user.groups.all()],
 92                "sub": "bar",
 93            },
 94        )
 95        self.assertEqual(res.status_code, 200)
 96
 97        events = Event.objects.filter(
 98            action=EventAction.CONFIGURATION_ERROR,
 99        )
100        self.assertTrue(events.exists())
101        self.assertEqual(
102            events.first().context["message"],
103            "Failed to evaluate property-mapping: 'test'",
104        )
class TestUserinfo(authentik.providers.oauth2.tests.utils.OAuthTestCase):
 26class TestUserinfo(OAuthTestCase):
 27    """Test token view"""
 28
 29    @apply_blueprint("system/providers-oauth2.yaml")
 30    def setUp(self) -> None:
 31        super().setUp()
 32        self.app = Application.objects.create(name=generate_id(), slug=generate_id())
 33        self.provider: OAuth2Provider = OAuth2Provider.objects.create(
 34            name=generate_id(),
 35            authorization_flow=create_test_flow(),
 36            redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "")],
 37            signing_key=create_test_cert(),
 38        )
 39        self.provider.property_mappings.set(ScopeMapping.objects.all())
 40        # Needs to be assigned to an application for iss to be set
 41        self.app.provider = self.provider
 42        self.app.save()
 43        self.user = create_test_admin_user()
 44        self.token: AccessToken = AccessToken.objects.create(
 45            provider=self.provider,
 46            user=self.user,
 47            token=generate_id(),
 48            auth_time=timezone.now(),
 49            _scope="openid user profile",
 50            _id_token=json.dumps(
 51                asdict(
 52                    IDToken("foo", "bar"),
 53                )
 54            ),
 55        )
 56
 57    def test_userinfo_normal(self):
 58        """test user info with all normal scopes"""
 59        res = self.client.get(
 60            reverse("authentik_providers_oauth2:userinfo"),
 61            HTTP_AUTHORIZATION=f"Bearer {self.token.token}",
 62        )
 63        self.assertJSONEqual(
 64            res.content.decode(),
 65            {
 66                "name": self.user.name,
 67                "given_name": self.user.name,
 68                "preferred_username": self.user.name,
 69                "nickname": self.user.name,
 70                "groups": [group.name for group in self.user.groups.all()],
 71                "sub": "bar",
 72            },
 73        )
 74        self.assertEqual(res.status_code, 200)
 75
 76    def test_userinfo_invalid_scope(self):
 77        """test user info with a broken scope"""
 78        scope = ScopeMapping.objects.create(name="test", scope_name="openid", expression="q")
 79        self.provider.property_mappings.add(scope)
 80
 81        res = self.client.get(
 82            reverse("authentik_providers_oauth2:userinfo"),
 83            HTTP_AUTHORIZATION=f"Bearer {self.token.token}",
 84        )
 85        self.assertJSONEqual(
 86            res.content.decode(),
 87            {
 88                "name": self.user.name,
 89                "given_name": self.user.name,
 90                "preferred_username": self.user.name,
 91                "nickname": self.user.name,
 92                "groups": [group.name for group in self.user.groups.all()],
 93                "sub": "bar",
 94            },
 95        )
 96        self.assertEqual(res.status_code, 200)
 97
 98        events = Event.objects.filter(
 99            action=EventAction.CONFIGURATION_ERROR,
100        )
101        self.assertTrue(events.exists())
102        self.assertEqual(
103            events.first().context["message"],
104            "Failed to evaluate property-mapping: 'test'",
105        )

Test token view

@apply_blueprint('system/providers-oauth2.yaml')
def setUp(self) -> None:
29    @apply_blueprint("system/providers-oauth2.yaml")
30    def setUp(self) -> None:
31        super().setUp()
32        self.app = Application.objects.create(name=generate_id(), slug=generate_id())
33        self.provider: OAuth2Provider = OAuth2Provider.objects.create(
34            name=generate_id(),
35            authorization_flow=create_test_flow(),
36            redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "")],
37            signing_key=create_test_cert(),
38        )
39        self.provider.property_mappings.set(ScopeMapping.objects.all())
40        # Needs to be assigned to an application for iss to be set
41        self.app.provider = self.provider
42        self.app.save()
43        self.user = create_test_admin_user()
44        self.token: AccessToken = AccessToken.objects.create(
45            provider=self.provider,
46            user=self.user,
47            token=generate_id(),
48            auth_time=timezone.now(),
49            _scope="openid user profile",
50            _id_token=json.dumps(
51                asdict(
52                    IDToken("foo", "bar"),
53                )
54            ),
55        )

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

def test_userinfo_normal(self):
57    def test_userinfo_normal(self):
58        """test user info with all normal scopes"""
59        res = self.client.get(
60            reverse("authentik_providers_oauth2:userinfo"),
61            HTTP_AUTHORIZATION=f"Bearer {self.token.token}",
62        )
63        self.assertJSONEqual(
64            res.content.decode(),
65            {
66                "name": self.user.name,
67                "given_name": self.user.name,
68                "preferred_username": self.user.name,
69                "nickname": self.user.name,
70                "groups": [group.name for group in self.user.groups.all()],
71                "sub": "bar",
72            },
73        )
74        self.assertEqual(res.status_code, 200)

test user info with all normal scopes

def test_userinfo_invalid_scope(self):
 76    def test_userinfo_invalid_scope(self):
 77        """test user info with a broken scope"""
 78        scope = ScopeMapping.objects.create(name="test", scope_name="openid", expression="q")
 79        self.provider.property_mappings.add(scope)
 80
 81        res = self.client.get(
 82            reverse("authentik_providers_oauth2:userinfo"),
 83            HTTP_AUTHORIZATION=f"Bearer {self.token.token}",
 84        )
 85        self.assertJSONEqual(
 86            res.content.decode(),
 87            {
 88                "name": self.user.name,
 89                "given_name": self.user.name,
 90                "preferred_username": self.user.name,
 91                "nickname": self.user.name,
 92                "groups": [group.name for group in self.user.groups.all()],
 93                "sub": "bar",
 94            },
 95        )
 96        self.assertEqual(res.status_code, 200)
 97
 98        events = Event.objects.filter(
 99            action=EventAction.CONFIGURATION_ERROR,
100        )
101        self.assertTrue(events.exists())
102        self.assertEqual(
103            events.first().context["message"],
104            "Failed to evaluate property-mapping: 'test'",
105        )

test user info with a broken scope