authentik.providers.oauth2.tests.test_token_device
Test token view
1"""Test token view""" 2 3from json import loads 4 5from django.test import RequestFactory 6from django.urls import reverse 7 8from authentik.blueprints.tests import apply_blueprint 9from authentik.common.oauth.constants import ( 10 GRANT_TYPE_DEVICE_CODE, 11 SCOPE_OPENID, 12 SCOPE_OPENID_EMAIL, 13) 14from authentik.core.models import Application 15from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow 16from authentik.lib.generators import generate_code_fixed_length, generate_id 17from authentik.providers.oauth2.models import ( 18 AccessToken, 19 DeviceToken, 20 OAuth2Provider, 21 RedirectURI, 22 RedirectURIMatchingMode, 23 ScopeMapping, 24) 25from authentik.providers.oauth2.tests.utils import OAuthTestCase 26 27 28class TestTokenDeviceCode(OAuthTestCase): 29 """Test token (device code) view""" 30 31 @apply_blueprint("system/providers-oauth2.yaml") 32 def setUp(self) -> None: 33 super().setUp() 34 self.factory = RequestFactory() 35 self.provider = OAuth2Provider.objects.create( 36 name="test", 37 authorization_flow=create_test_flow(), 38 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 39 signing_key=create_test_cert(), 40 ) 41 self.provider.property_mappings.set(ScopeMapping.objects.all()) 42 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 43 self.user = create_test_admin_user() 44 45 def test_code_no_code(self): 46 """Test code without code""" 47 res = self.client.post( 48 reverse("authentik_providers_oauth2:token"), 49 data={ 50 "client_id": self.provider.client_id, 51 "grant_type": GRANT_TYPE_DEVICE_CODE, 52 }, 53 ) 54 self.assertEqual(res.status_code, 400) 55 body = loads(res.content.decode()) 56 self.assertEqual(body["error"], "invalid_grant") 57 58 def test_code_no_user(self): 59 """Test code without user""" 60 device_token = DeviceToken.objects.create( 61 provider=self.provider, 62 user_code=generate_code_fixed_length(), 63 device_code=generate_id(), 64 ) 65 res = self.client.post( 66 reverse("authentik_providers_oauth2:token"), 67 data={ 68 "client_id": self.provider.client_id, 69 "grant_type": GRANT_TYPE_DEVICE_CODE, 70 "device_code": device_token.device_code, 71 }, 72 ) 73 self.assertEqual(res.status_code, 400) 74 body = loads(res.content.decode()) 75 self.assertEqual(body["error"], "authorization_pending") 76 77 def test_code(self): 78 """Test code with user""" 79 device_token = DeviceToken.objects.create( 80 provider=self.provider, 81 user_code=generate_code_fixed_length(), 82 device_code=generate_id(), 83 user=self.user, 84 ) 85 res = self.client.post( 86 reverse("authentik_providers_oauth2:token"), 87 data={ 88 "client_id": self.provider.client_id, 89 "grant_type": GRANT_TYPE_DEVICE_CODE, 90 "device_code": device_token.device_code, 91 }, 92 ) 93 self.assertEqual(res.status_code, 200) 94 95 def test_code_mismatched_scope(self): 96 """Test code with user (mismatched scopes)""" 97 device_token = DeviceToken.objects.create( 98 provider=self.provider, 99 user_code=generate_code_fixed_length(), 100 device_code=generate_id(), 101 user=self.user, 102 scope=[SCOPE_OPENID, SCOPE_OPENID_EMAIL], 103 ) 104 res = self.client.post( 105 reverse("authentik_providers_oauth2:token"), 106 data={ 107 "client_id": self.provider.client_id, 108 "grant_type": GRANT_TYPE_DEVICE_CODE, 109 "device_code": device_token.device_code, 110 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} invalid", 111 }, 112 ) 113 self.assertEqual(res.status_code, 200) 114 body = loads(res.content) 115 token = AccessToken.objects.filter( 116 provider=self.provider, token=body["access_token"] 117 ).first() 118 self.assertSetEqual(set(token.scope), {SCOPE_OPENID, SCOPE_OPENID_EMAIL})
29class TestTokenDeviceCode(OAuthTestCase): 30 """Test token (device code) view""" 31 32 @apply_blueprint("system/providers-oauth2.yaml") 33 def setUp(self) -> None: 34 super().setUp() 35 self.factory = RequestFactory() 36 self.provider = OAuth2Provider.objects.create( 37 name="test", 38 authorization_flow=create_test_flow(), 39 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 40 signing_key=create_test_cert(), 41 ) 42 self.provider.property_mappings.set(ScopeMapping.objects.all()) 43 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 44 self.user = create_test_admin_user() 45 46 def test_code_no_code(self): 47 """Test code without code""" 48 res = self.client.post( 49 reverse("authentik_providers_oauth2:token"), 50 data={ 51 "client_id": self.provider.client_id, 52 "grant_type": GRANT_TYPE_DEVICE_CODE, 53 }, 54 ) 55 self.assertEqual(res.status_code, 400) 56 body = loads(res.content.decode()) 57 self.assertEqual(body["error"], "invalid_grant") 58 59 def test_code_no_user(self): 60 """Test code without user""" 61 device_token = DeviceToken.objects.create( 62 provider=self.provider, 63 user_code=generate_code_fixed_length(), 64 device_code=generate_id(), 65 ) 66 res = self.client.post( 67 reverse("authentik_providers_oauth2:token"), 68 data={ 69 "client_id": self.provider.client_id, 70 "grant_type": GRANT_TYPE_DEVICE_CODE, 71 "device_code": device_token.device_code, 72 }, 73 ) 74 self.assertEqual(res.status_code, 400) 75 body = loads(res.content.decode()) 76 self.assertEqual(body["error"], "authorization_pending") 77 78 def test_code(self): 79 """Test code with user""" 80 device_token = DeviceToken.objects.create( 81 provider=self.provider, 82 user_code=generate_code_fixed_length(), 83 device_code=generate_id(), 84 user=self.user, 85 ) 86 res = self.client.post( 87 reverse("authentik_providers_oauth2:token"), 88 data={ 89 "client_id": self.provider.client_id, 90 "grant_type": GRANT_TYPE_DEVICE_CODE, 91 "device_code": device_token.device_code, 92 }, 93 ) 94 self.assertEqual(res.status_code, 200) 95 96 def test_code_mismatched_scope(self): 97 """Test code with user (mismatched scopes)""" 98 device_token = DeviceToken.objects.create( 99 provider=self.provider, 100 user_code=generate_code_fixed_length(), 101 device_code=generate_id(), 102 user=self.user, 103 scope=[SCOPE_OPENID, SCOPE_OPENID_EMAIL], 104 ) 105 res = self.client.post( 106 reverse("authentik_providers_oauth2:token"), 107 data={ 108 "client_id": self.provider.client_id, 109 "grant_type": GRANT_TYPE_DEVICE_CODE, 110 "device_code": device_token.device_code, 111 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} invalid", 112 }, 113 ) 114 self.assertEqual(res.status_code, 200) 115 body = loads(res.content) 116 token = AccessToken.objects.filter( 117 provider=self.provider, token=body["access_token"] 118 ).first() 119 self.assertSetEqual(set(token.scope), {SCOPE_OPENID, SCOPE_OPENID_EMAIL})
Test token (device code) view
@apply_blueprint('system/providers-oauth2.yaml')
def
setUp(self) -> None:
32 @apply_blueprint("system/providers-oauth2.yaml") 33 def setUp(self) -> None: 34 super().setUp() 35 self.factory = RequestFactory() 36 self.provider = OAuth2Provider.objects.create( 37 name="test", 38 authorization_flow=create_test_flow(), 39 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 40 signing_key=create_test_cert(), 41 ) 42 self.provider.property_mappings.set(ScopeMapping.objects.all()) 43 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 44 self.user = create_test_admin_user()
Hook method for setting up the test fixture before exercising it.
def
test_code_no_code(self):
46 def test_code_no_code(self): 47 """Test code without code""" 48 res = self.client.post( 49 reverse("authentik_providers_oauth2:token"), 50 data={ 51 "client_id": self.provider.client_id, 52 "grant_type": GRANT_TYPE_DEVICE_CODE, 53 }, 54 ) 55 self.assertEqual(res.status_code, 400) 56 body = loads(res.content.decode()) 57 self.assertEqual(body["error"], "invalid_grant")
Test code without code
def
test_code_no_user(self):
59 def test_code_no_user(self): 60 """Test code without user""" 61 device_token = DeviceToken.objects.create( 62 provider=self.provider, 63 user_code=generate_code_fixed_length(), 64 device_code=generate_id(), 65 ) 66 res = self.client.post( 67 reverse("authentik_providers_oauth2:token"), 68 data={ 69 "client_id": self.provider.client_id, 70 "grant_type": GRANT_TYPE_DEVICE_CODE, 71 "device_code": device_token.device_code, 72 }, 73 ) 74 self.assertEqual(res.status_code, 400) 75 body = loads(res.content.decode()) 76 self.assertEqual(body["error"], "authorization_pending")
Test code without user
def
test_code(self):
78 def test_code(self): 79 """Test code with user""" 80 device_token = DeviceToken.objects.create( 81 provider=self.provider, 82 user_code=generate_code_fixed_length(), 83 device_code=generate_id(), 84 user=self.user, 85 ) 86 res = self.client.post( 87 reverse("authentik_providers_oauth2:token"), 88 data={ 89 "client_id": self.provider.client_id, 90 "grant_type": GRANT_TYPE_DEVICE_CODE, 91 "device_code": device_token.device_code, 92 }, 93 ) 94 self.assertEqual(res.status_code, 200)
Test code with user
def
test_code_mismatched_scope(self):
96 def test_code_mismatched_scope(self): 97 """Test code with user (mismatched scopes)""" 98 device_token = DeviceToken.objects.create( 99 provider=self.provider, 100 user_code=generate_code_fixed_length(), 101 device_code=generate_id(), 102 user=self.user, 103 scope=[SCOPE_OPENID, SCOPE_OPENID_EMAIL], 104 ) 105 res = self.client.post( 106 reverse("authentik_providers_oauth2:token"), 107 data={ 108 "client_id": self.provider.client_id, 109 "grant_type": GRANT_TYPE_DEVICE_CODE, 110 "device_code": device_token.device_code, 111 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} invalid", 112 }, 113 ) 114 self.assertEqual(res.status_code, 200) 115 body = loads(res.content) 116 token = AccessToken.objects.filter( 117 provider=self.provider, token=body["access_token"] 118 ).first() 119 self.assertSetEqual(set(token.scope), {SCOPE_OPENID, SCOPE_OPENID_EMAIL})
Test code with user (mismatched scopes)