authentik.providers.oauth2.tests.test_token_cc_standard_compat

Test token view

  1"""Test token view"""
  2
  3from base64 import b64encode
  4from json import loads
  5from urllib.parse import quote
  6
  7from django.test import RequestFactory
  8from django.urls import reverse
  9from jwt import decode
 10
 11from authentik.blueprints.tests import apply_blueprint
 12from authentik.common.oauth.constants import (
 13    GRANT_TYPE_CLIENT_CREDENTIALS,
 14    GRANT_TYPE_PASSWORD,
 15    SCOPE_OPENID,
 16    SCOPE_OPENID_EMAIL,
 17    SCOPE_OPENID_PROFILE,
 18    TOKEN_TYPE,
 19)
 20from authentik.core.models import Application, Group, Token, TokenIntents, UserTypes
 21from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
 22from authentik.policies.models import PolicyBinding
 23from authentik.providers.oauth2.errors import TokenError
 24from authentik.providers.oauth2.models import (
 25    OAuth2Provider,
 26    RedirectURI,
 27    RedirectURIMatchingMode,
 28    ScopeMapping,
 29)
 30from authentik.providers.oauth2.tests.utils import OAuthTestCase
 31
 32
 33class TestTokenClientCredentialsStandardCompat(OAuthTestCase):
 34    """Test token (client_credentials) view"""
 35
 36    @apply_blueprint("system/providers-oauth2.yaml")
 37    def setUp(self) -> None:
 38        super().setUp()
 39        self.factory = RequestFactory()
 40        self.provider = OAuth2Provider.objects.create(
 41            name="test",
 42            authorization_flow=create_test_flow(),
 43            redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")],
 44            signing_key=create_test_cert(),
 45        )
 46        self.provider.property_mappings.set(ScopeMapping.objects.all())
 47        self.app = Application.objects.create(name="test", slug="test", provider=self.provider)
 48        self.user = create_test_admin_user("sa")
 49        self.user.type = UserTypes.SERVICE_ACCOUNT
 50        self.user.save()
 51        self.token = Token.objects.create(
 52            identifier="sa-token",
 53            user=self.user,
 54            intent=TokenIntents.INTENT_APP_PASSWORD,
 55            expiring=False,
 56        )
 57
 58    def test_wrong_user(self):
 59        """test invalid username"""
 60        response = self.client.post(
 61            reverse("authentik_providers_oauth2:token"),
 62            {
 63                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
 64                "scope": SCOPE_OPENID,
 65                "client_id": self.provider.client_id,
 66                "client_secret": b64encode(f"saa:{self.token.key}".encode()).decode(),
 67            },
 68        )
 69        self.assertEqual(response.status_code, 400)
 70        self.assertJSONEqual(
 71            response.content.decode(),
 72            {
 73                "error": "invalid_grant",
 74                "error_description": TokenError.errors["invalid_grant"],
 75                "request_id": response.headers["X-authentik-id"],
 76            },
 77        )
 78
 79    def test_wrong_token(self):
 80        """test invalid token"""
 81        response = self.client.post(
 82            reverse("authentik_providers_oauth2:token"),
 83            {
 84                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
 85                "scope": SCOPE_OPENID,
 86                "client_id": self.provider.client_id,
 87                "client_secret": b64encode(f"sa:{self.token.key}foo".encode()).decode(),
 88            },
 89        )
 90        self.assertEqual(response.status_code, 400)
 91        self.assertJSONEqual(
 92            response.content.decode(),
 93            {
 94                "error": "invalid_grant",
 95                "error_description": TokenError.errors["invalid_grant"],
 96                "request_id": response.headers["X-authentik-id"],
 97            },
 98        )
 99
100    def test_no_provider(self):
101        """test no provider"""
102        self.app.provider = None
103        self.app.save()
104        response = self.client.post(
105            reverse("authentik_providers_oauth2:token"),
106            {
107                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
108                "scope": SCOPE_OPENID,
109                "client_id": self.provider.client_id,
110                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
111            },
112        )
113        self.assertEqual(response.status_code, 400)
114        self.assertJSONEqual(
115            response.content.decode(),
116            {
117                "error": "invalid_grant",
118                "error_description": TokenError.errors["invalid_grant"],
119                "request_id": response.headers["X-authentik-id"],
120            },
121        )
122
123    def test_permission_denied(self):
124        """test permission denied"""
125        group = Group.objects.create(name="foo")
126        PolicyBinding.objects.create(
127            group=group,
128            target=self.app,
129            order=0,
130        )
131        response = self.client.post(
132            reverse("authentik_providers_oauth2:token"),
133            {
134                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
135                "scope": SCOPE_OPENID,
136                "client_id": self.provider.client_id,
137                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
138            },
139        )
140        self.assertEqual(response.status_code, 400)
141        self.assertJSONEqual(
142            response.content.decode(),
143            {
144                "error": "invalid_grant",
145                "error_description": TokenError.errors["invalid_grant"],
146                "request_id": response.headers["X-authentik-id"],
147            },
148        )
149
150    def test_successful(self):
151        """test successful"""
152        response = self.client.post(
153            reverse("authentik_providers_oauth2:token"),
154            {
155                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
156                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
157                "client_id": self.provider.client_id,
158                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
159            },
160        )
161        self.assertEqual(response.status_code, 200)
162        body = loads(response.content.decode())
163        self.assertEqual(body["token_type"], TOKEN_TYPE)
164        _, alg = self.provider.jwt_key
165        jwt = decode(
166            body["access_token"],
167            key=self.provider.signing_key.public_key,
168            algorithms=[alg],
169            audience=self.provider.client_id,
170        )
171        self.assertEqual(jwt["given_name"], self.user.name)
172        self.assertEqual(jwt["preferred_username"], self.user.username)
173        jwt = decode(
174            body["id_token"],
175            key=self.provider.signing_key.public_key,
176            algorithms=[alg],
177            audience=self.provider.client_id,
178        )
179        self.assertEqual(jwt["given_name"], self.user.name)
180        self.assertEqual(jwt["preferred_username"], self.user.username)
181
182    def test_successful_basic_auth_urlencoded_client_secret(self):
183        """test successful with URL-encoded Basic auth credentials"""
184        client_secret = b64encode(f"sa:{self.token.key}".encode()).decode()
185        header = b64encode(
186            f"{quote(self.provider.client_id, safe='')}:{quote(client_secret, safe='')}".encode()
187        ).decode()
188        response = self.client.post(
189            reverse("authentik_providers_oauth2:token"),
190            {
191                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
192                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
193            },
194            HTTP_AUTHORIZATION=f"Basic {header}",
195        )
196        self.assertEqual(response.status_code, 200)
197        body = loads(response.content.decode())
198        self.assertEqual(body["token_type"], TOKEN_TYPE)
199        _, alg = self.provider.jwt_key
200        jwt = decode(
201            body["access_token"],
202            key=self.provider.signing_key.public_key,
203            algorithms=[alg],
204            audience=self.provider.client_id,
205        )
206        self.assertEqual(jwt["given_name"], self.user.name)
207        self.assertEqual(jwt["preferred_username"], self.user.username)
208        jwt = decode(
209            body["id_token"],
210            key=self.provider.signing_key.public_key,
211            algorithms=[alg],
212            audience=self.provider.client_id,
213        )
214        self.assertEqual(jwt["given_name"], self.user.name)
215        self.assertEqual(jwt["preferred_username"], self.user.username)
216
217    def test_successful_password(self):
218        """test successful (password grant)"""
219        response = self.client.post(
220            reverse("authentik_providers_oauth2:token"),
221            {
222                "grant_type": GRANT_TYPE_PASSWORD,
223                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
224                "client_id": self.provider.client_id,
225                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
226            },
227        )
228        self.assertEqual(response.status_code, 200)
229        body = loads(response.content.decode())
230        self.assertEqual(body["token_type"], TOKEN_TYPE)
231        _, alg = self.provider.jwt_key
232        jwt = decode(
233            body["access_token"],
234            key=self.provider.signing_key.public_key,
235            algorithms=[alg],
236            audience=self.provider.client_id,
237        )
238        self.assertEqual(jwt["given_name"], self.user.name)
239        self.assertEqual(jwt["preferred_username"], self.user.username)
class TestTokenClientCredentialsStandardCompat(authentik.providers.oauth2.tests.utils.OAuthTestCase):
 34class TestTokenClientCredentialsStandardCompat(OAuthTestCase):
 35    """Test token (client_credentials) view"""
 36
 37    @apply_blueprint("system/providers-oauth2.yaml")
 38    def setUp(self) -> None:
 39        super().setUp()
 40        self.factory = RequestFactory()
 41        self.provider = OAuth2Provider.objects.create(
 42            name="test",
 43            authorization_flow=create_test_flow(),
 44            redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")],
 45            signing_key=create_test_cert(),
 46        )
 47        self.provider.property_mappings.set(ScopeMapping.objects.all())
 48        self.app = Application.objects.create(name="test", slug="test", provider=self.provider)
 49        self.user = create_test_admin_user("sa")
 50        self.user.type = UserTypes.SERVICE_ACCOUNT
 51        self.user.save()
 52        self.token = Token.objects.create(
 53            identifier="sa-token",
 54            user=self.user,
 55            intent=TokenIntents.INTENT_APP_PASSWORD,
 56            expiring=False,
 57        )
 58
 59    def test_wrong_user(self):
 60        """test invalid username"""
 61        response = self.client.post(
 62            reverse("authentik_providers_oauth2:token"),
 63            {
 64                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
 65                "scope": SCOPE_OPENID,
 66                "client_id": self.provider.client_id,
 67                "client_secret": b64encode(f"saa:{self.token.key}".encode()).decode(),
 68            },
 69        )
 70        self.assertEqual(response.status_code, 400)
 71        self.assertJSONEqual(
 72            response.content.decode(),
 73            {
 74                "error": "invalid_grant",
 75                "error_description": TokenError.errors["invalid_grant"],
 76                "request_id": response.headers["X-authentik-id"],
 77            },
 78        )
 79
 80    def test_wrong_token(self):
 81        """test invalid token"""
 82        response = self.client.post(
 83            reverse("authentik_providers_oauth2:token"),
 84            {
 85                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
 86                "scope": SCOPE_OPENID,
 87                "client_id": self.provider.client_id,
 88                "client_secret": b64encode(f"sa:{self.token.key}foo".encode()).decode(),
 89            },
 90        )
 91        self.assertEqual(response.status_code, 400)
 92        self.assertJSONEqual(
 93            response.content.decode(),
 94            {
 95                "error": "invalid_grant",
 96                "error_description": TokenError.errors["invalid_grant"],
 97                "request_id": response.headers["X-authentik-id"],
 98            },
 99        )
100
101    def test_no_provider(self):
102        """test no provider"""
103        self.app.provider = None
104        self.app.save()
105        response = self.client.post(
106            reverse("authentik_providers_oauth2:token"),
107            {
108                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
109                "scope": SCOPE_OPENID,
110                "client_id": self.provider.client_id,
111                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
112            },
113        )
114        self.assertEqual(response.status_code, 400)
115        self.assertJSONEqual(
116            response.content.decode(),
117            {
118                "error": "invalid_grant",
119                "error_description": TokenError.errors["invalid_grant"],
120                "request_id": response.headers["X-authentik-id"],
121            },
122        )
123
124    def test_permission_denied(self):
125        """test permission denied"""
126        group = Group.objects.create(name="foo")
127        PolicyBinding.objects.create(
128            group=group,
129            target=self.app,
130            order=0,
131        )
132        response = self.client.post(
133            reverse("authentik_providers_oauth2:token"),
134            {
135                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
136                "scope": SCOPE_OPENID,
137                "client_id": self.provider.client_id,
138                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
139            },
140        )
141        self.assertEqual(response.status_code, 400)
142        self.assertJSONEqual(
143            response.content.decode(),
144            {
145                "error": "invalid_grant",
146                "error_description": TokenError.errors["invalid_grant"],
147                "request_id": response.headers["X-authentik-id"],
148            },
149        )
150
151    def test_successful(self):
152        """test successful"""
153        response = self.client.post(
154            reverse("authentik_providers_oauth2:token"),
155            {
156                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
157                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
158                "client_id": self.provider.client_id,
159                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
160            },
161        )
162        self.assertEqual(response.status_code, 200)
163        body = loads(response.content.decode())
164        self.assertEqual(body["token_type"], TOKEN_TYPE)
165        _, alg = self.provider.jwt_key
166        jwt = decode(
167            body["access_token"],
168            key=self.provider.signing_key.public_key,
169            algorithms=[alg],
170            audience=self.provider.client_id,
171        )
172        self.assertEqual(jwt["given_name"], self.user.name)
173        self.assertEqual(jwt["preferred_username"], self.user.username)
174        jwt = decode(
175            body["id_token"],
176            key=self.provider.signing_key.public_key,
177            algorithms=[alg],
178            audience=self.provider.client_id,
179        )
180        self.assertEqual(jwt["given_name"], self.user.name)
181        self.assertEqual(jwt["preferred_username"], self.user.username)
182
183    def test_successful_basic_auth_urlencoded_client_secret(self):
184        """test successful with URL-encoded Basic auth credentials"""
185        client_secret = b64encode(f"sa:{self.token.key}".encode()).decode()
186        header = b64encode(
187            f"{quote(self.provider.client_id, safe='')}:{quote(client_secret, safe='')}".encode()
188        ).decode()
189        response = self.client.post(
190            reverse("authentik_providers_oauth2:token"),
191            {
192                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
193                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
194            },
195            HTTP_AUTHORIZATION=f"Basic {header}",
196        )
197        self.assertEqual(response.status_code, 200)
198        body = loads(response.content.decode())
199        self.assertEqual(body["token_type"], TOKEN_TYPE)
200        _, alg = self.provider.jwt_key
201        jwt = decode(
202            body["access_token"],
203            key=self.provider.signing_key.public_key,
204            algorithms=[alg],
205            audience=self.provider.client_id,
206        )
207        self.assertEqual(jwt["given_name"], self.user.name)
208        self.assertEqual(jwt["preferred_username"], self.user.username)
209        jwt = decode(
210            body["id_token"],
211            key=self.provider.signing_key.public_key,
212            algorithms=[alg],
213            audience=self.provider.client_id,
214        )
215        self.assertEqual(jwt["given_name"], self.user.name)
216        self.assertEqual(jwt["preferred_username"], self.user.username)
217
218    def test_successful_password(self):
219        """test successful (password grant)"""
220        response = self.client.post(
221            reverse("authentik_providers_oauth2:token"),
222            {
223                "grant_type": GRANT_TYPE_PASSWORD,
224                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
225                "client_id": self.provider.client_id,
226                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
227            },
228        )
229        self.assertEqual(response.status_code, 200)
230        body = loads(response.content.decode())
231        self.assertEqual(body["token_type"], TOKEN_TYPE)
232        _, alg = self.provider.jwt_key
233        jwt = decode(
234            body["access_token"],
235            key=self.provider.signing_key.public_key,
236            algorithms=[alg],
237            audience=self.provider.client_id,
238        )
239        self.assertEqual(jwt["given_name"], self.user.name)
240        self.assertEqual(jwt["preferred_username"], self.user.username)

Test token (client_credentials) view

@apply_blueprint('system/providers-oauth2.yaml')
def setUp(self) -> None:
37    @apply_blueprint("system/providers-oauth2.yaml")
38    def setUp(self) -> None:
39        super().setUp()
40        self.factory = RequestFactory()
41        self.provider = OAuth2Provider.objects.create(
42            name="test",
43            authorization_flow=create_test_flow(),
44            redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")],
45            signing_key=create_test_cert(),
46        )
47        self.provider.property_mappings.set(ScopeMapping.objects.all())
48        self.app = Application.objects.create(name="test", slug="test", provider=self.provider)
49        self.user = create_test_admin_user("sa")
50        self.user.type = UserTypes.SERVICE_ACCOUNT
51        self.user.save()
52        self.token = Token.objects.create(
53            identifier="sa-token",
54            user=self.user,
55            intent=TokenIntents.INTENT_APP_PASSWORD,
56            expiring=False,
57        )

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

def test_wrong_user(self):
59    def test_wrong_user(self):
60        """test invalid username"""
61        response = self.client.post(
62            reverse("authentik_providers_oauth2:token"),
63            {
64                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
65                "scope": SCOPE_OPENID,
66                "client_id": self.provider.client_id,
67                "client_secret": b64encode(f"saa:{self.token.key}".encode()).decode(),
68            },
69        )
70        self.assertEqual(response.status_code, 400)
71        self.assertJSONEqual(
72            response.content.decode(),
73            {
74                "error": "invalid_grant",
75                "error_description": TokenError.errors["invalid_grant"],
76                "request_id": response.headers["X-authentik-id"],
77            },
78        )

test invalid username

def test_wrong_token(self):
80    def test_wrong_token(self):
81        """test invalid token"""
82        response = self.client.post(
83            reverse("authentik_providers_oauth2:token"),
84            {
85                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
86                "scope": SCOPE_OPENID,
87                "client_id": self.provider.client_id,
88                "client_secret": b64encode(f"sa:{self.token.key}foo".encode()).decode(),
89            },
90        )
91        self.assertEqual(response.status_code, 400)
92        self.assertJSONEqual(
93            response.content.decode(),
94            {
95                "error": "invalid_grant",
96                "error_description": TokenError.errors["invalid_grant"],
97                "request_id": response.headers["X-authentik-id"],
98            },
99        )

test invalid token

def test_no_provider(self):
101    def test_no_provider(self):
102        """test no provider"""
103        self.app.provider = None
104        self.app.save()
105        response = self.client.post(
106            reverse("authentik_providers_oauth2:token"),
107            {
108                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
109                "scope": SCOPE_OPENID,
110                "client_id": self.provider.client_id,
111                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
112            },
113        )
114        self.assertEqual(response.status_code, 400)
115        self.assertJSONEqual(
116            response.content.decode(),
117            {
118                "error": "invalid_grant",
119                "error_description": TokenError.errors["invalid_grant"],
120                "request_id": response.headers["X-authentik-id"],
121            },
122        )

test no provider

def test_permission_denied(self):
124    def test_permission_denied(self):
125        """test permission denied"""
126        group = Group.objects.create(name="foo")
127        PolicyBinding.objects.create(
128            group=group,
129            target=self.app,
130            order=0,
131        )
132        response = self.client.post(
133            reverse("authentik_providers_oauth2:token"),
134            {
135                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
136                "scope": SCOPE_OPENID,
137                "client_id": self.provider.client_id,
138                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
139            },
140        )
141        self.assertEqual(response.status_code, 400)
142        self.assertJSONEqual(
143            response.content.decode(),
144            {
145                "error": "invalid_grant",
146                "error_description": TokenError.errors["invalid_grant"],
147                "request_id": response.headers["X-authentik-id"],
148            },
149        )

test permission denied

def test_successful(self):
151    def test_successful(self):
152        """test successful"""
153        response = self.client.post(
154            reverse("authentik_providers_oauth2:token"),
155            {
156                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
157                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
158                "client_id": self.provider.client_id,
159                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
160            },
161        )
162        self.assertEqual(response.status_code, 200)
163        body = loads(response.content.decode())
164        self.assertEqual(body["token_type"], TOKEN_TYPE)
165        _, alg = self.provider.jwt_key
166        jwt = decode(
167            body["access_token"],
168            key=self.provider.signing_key.public_key,
169            algorithms=[alg],
170            audience=self.provider.client_id,
171        )
172        self.assertEqual(jwt["given_name"], self.user.name)
173        self.assertEqual(jwt["preferred_username"], self.user.username)
174        jwt = decode(
175            body["id_token"],
176            key=self.provider.signing_key.public_key,
177            algorithms=[alg],
178            audience=self.provider.client_id,
179        )
180        self.assertEqual(jwt["given_name"], self.user.name)
181        self.assertEqual(jwt["preferred_username"], self.user.username)

test successful

def test_successful_basic_auth_urlencoded_client_secret(self):
183    def test_successful_basic_auth_urlencoded_client_secret(self):
184        """test successful with URL-encoded Basic auth credentials"""
185        client_secret = b64encode(f"sa:{self.token.key}".encode()).decode()
186        header = b64encode(
187            f"{quote(self.provider.client_id, safe='')}:{quote(client_secret, safe='')}".encode()
188        ).decode()
189        response = self.client.post(
190            reverse("authentik_providers_oauth2:token"),
191            {
192                "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
193                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
194            },
195            HTTP_AUTHORIZATION=f"Basic {header}",
196        )
197        self.assertEqual(response.status_code, 200)
198        body = loads(response.content.decode())
199        self.assertEqual(body["token_type"], TOKEN_TYPE)
200        _, alg = self.provider.jwt_key
201        jwt = decode(
202            body["access_token"],
203            key=self.provider.signing_key.public_key,
204            algorithms=[alg],
205            audience=self.provider.client_id,
206        )
207        self.assertEqual(jwt["given_name"], self.user.name)
208        self.assertEqual(jwt["preferred_username"], self.user.username)
209        jwt = decode(
210            body["id_token"],
211            key=self.provider.signing_key.public_key,
212            algorithms=[alg],
213            audience=self.provider.client_id,
214        )
215        self.assertEqual(jwt["given_name"], self.user.name)
216        self.assertEqual(jwt["preferred_username"], self.user.username)

test successful with URL-encoded Basic auth credentials

def test_successful_password(self):
218    def test_successful_password(self):
219        """test successful (password grant)"""
220        response = self.client.post(
221            reverse("authentik_providers_oauth2:token"),
222            {
223                "grant_type": GRANT_TYPE_PASSWORD,
224                "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
225                "client_id": self.provider.client_id,
226                "client_secret": b64encode(f"sa:{self.token.key}".encode()).decode(),
227            },
228        )
229        self.assertEqual(response.status_code, 200)
230        body = loads(response.content.decode())
231        self.assertEqual(body["token_type"], TOKEN_TYPE)
232        _, alg = self.provider.jwt_key
233        jwt = decode(
234            body["access_token"],
235            key=self.provider.signing_key.public_key,
236            algorithms=[alg],
237            audience=self.provider.client_id,
238        )
239        self.assertEqual(jwt["given_name"], self.user.name)
240        self.assertEqual(jwt["preferred_username"], self.user.username)

test successful (password grant)