authentik.providers.oauth2.tests.test_api
Test OAuth2 API
1"""Test OAuth2 API""" 2 3from json import loads 4from sys import version_info 5from unittest import skipUnless 6 7from django.urls import reverse 8from rest_framework.test import APITestCase 9 10from authentik.blueprints.tests import apply_blueprint 11from authentik.core.models import Application 12from authentik.core.tests.utils import create_test_admin_user, create_test_flow 13from authentik.lib.generators import generate_id 14from authentik.providers.oauth2.models import ( 15 OAuth2Provider, 16 RedirectURI, 17 RedirectURIMatchingMode, 18 ScopeMapping, 19) 20 21 22class TestAPI(APITestCase): 23 """Test api view""" 24 25 @apply_blueprint("system/providers-oauth2.yaml") 26 def setUp(self) -> None: 27 self.provider: OAuth2Provider = OAuth2Provider.objects.create( 28 name="test", 29 authorization_flow=create_test_flow(), 30 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 31 ) 32 self.provider.property_mappings.set(ScopeMapping.objects.all()) 33 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 34 self.user = create_test_admin_user() 35 self.client.force_login(self.user) 36 37 def test_preview(self): 38 """Test Preview API Endpoint""" 39 response = self.client.get( 40 reverse("authentik_api:oauth2provider-preview-user", kwargs={"pk": self.provider.pk}) 41 ) 42 self.assertEqual(response.status_code, 200) 43 body = loads(response.content.decode())["preview"] 44 self.assertEqual(body["iss"], "http://testserver/application/o/test/") 45 46 def test_setup_urls(self): 47 """Test Setup URLs API Endpoint""" 48 response = self.client.get( 49 reverse("authentik_api:oauth2provider-setup-urls", kwargs={"pk": self.provider.pk}) 50 ) 51 self.assertEqual(response.status_code, 200) 52 body = loads(response.content.decode()) 53 self.assertEqual(body["issuer"], "http://testserver/application/o/test/") 54 55 # https://github.com/goauthentik/authentik/pull/5918 56 @skipUnless(version_info >= (3, 11, 4), "This behaviour is only Python 3.11.4 and up") 57 def test_launch_url(self): 58 """Test launch_url""" 59 self.provider.redirect_uris = [ 60 RedirectURI( 61 RedirectURIMatchingMode.REGEX, 62 "https://[\\d\\w]+.pr.test.goauthentik.io/source/oauth/callback/authentik/", 63 ), 64 ] 65 self.provider.save() 66 self.provider.refresh_from_db() 67 self.assertIsNone(self.provider.launch_url) 68 69 def test_validate_redirect_uris(self): 70 """Test redirect_uris API""" 71 response = self.client.post( 72 reverse("authentik_api:oauth2provider-list"), 73 data={ 74 "name": generate_id(), 75 "authorization_flow": create_test_flow().pk, 76 "invalidation_flow": create_test_flow().pk, 77 "redirect_uris": [ 78 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 79 {"matching_mode": "regex", "url": "**"}, 80 ], 81 }, 82 ) 83 self.assertJSONEqual(response.content, {"redirect_uris": ["Invalid Regex Pattern: **"]}) 84 85 def test_logout_uri_validation(self): 86 """Test logout_uri API validation""" 87 response = self.client.post( 88 reverse("authentik_api:oauth2provider-list"), 89 data={ 90 "name": generate_id(), 91 "authorization_flow": create_test_flow().pk, 92 "invalidation_flow": create_test_flow().pk, 93 "redirect_uris": [ 94 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 95 ], 96 "logout_uri": "invalid-url", 97 "logout_method": "backchannel", 98 }, 99 ) 100 self.assertEqual(response.status_code, 400) 101 102 def test_logout_uri_create_and_retrieve(self): 103 """Test creating and retrieving logout URI with method""" 104 response = self.client.post( 105 reverse("authentik_api:oauth2provider-list"), 106 data={ 107 "name": generate_id(), 108 "authorization_flow": create_test_flow().pk, 109 "invalidation_flow": create_test_flow().pk, 110 "redirect_uris": [ 111 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 112 ], 113 "logout_uri": "http://goauthentik.io/logout", 114 "logout_method": "backchannel", 115 }, 116 ) 117 self.assertEqual(response.status_code, 201) 118 provider_data = response.json() 119 self.assertEqual(provider_data["logout_uri"], "http://goauthentik.io/logout") 120 self.assertEqual(provider_data["logout_method"], "backchannel") 121 122 # Test retrieving the provider 123 provider_pk = provider_data["pk"] 124 response = self.client.get( 125 reverse("authentik_api:oauth2provider-detail", kwargs={"pk": provider_pk}) 126 ) 127 self.assertEqual(response.status_code, 200) 128 retrieved_data = response.json() 129 self.assertEqual(retrieved_data["logout_uri"], "http://goauthentik.io/logout") 130 self.assertEqual(retrieved_data["logout_method"], "backchannel")
class
TestAPI(rest_framework.test.APITestCase):
23class TestAPI(APITestCase): 24 """Test api view""" 25 26 @apply_blueprint("system/providers-oauth2.yaml") 27 def setUp(self) -> None: 28 self.provider: OAuth2Provider = OAuth2Provider.objects.create( 29 name="test", 30 authorization_flow=create_test_flow(), 31 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 32 ) 33 self.provider.property_mappings.set(ScopeMapping.objects.all()) 34 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 35 self.user = create_test_admin_user() 36 self.client.force_login(self.user) 37 38 def test_preview(self): 39 """Test Preview API Endpoint""" 40 response = self.client.get( 41 reverse("authentik_api:oauth2provider-preview-user", kwargs={"pk": self.provider.pk}) 42 ) 43 self.assertEqual(response.status_code, 200) 44 body = loads(response.content.decode())["preview"] 45 self.assertEqual(body["iss"], "http://testserver/application/o/test/") 46 47 def test_setup_urls(self): 48 """Test Setup URLs API Endpoint""" 49 response = self.client.get( 50 reverse("authentik_api:oauth2provider-setup-urls", kwargs={"pk": self.provider.pk}) 51 ) 52 self.assertEqual(response.status_code, 200) 53 body = loads(response.content.decode()) 54 self.assertEqual(body["issuer"], "http://testserver/application/o/test/") 55 56 # https://github.com/goauthentik/authentik/pull/5918 57 @skipUnless(version_info >= (3, 11, 4), "This behaviour is only Python 3.11.4 and up") 58 def test_launch_url(self): 59 """Test launch_url""" 60 self.provider.redirect_uris = [ 61 RedirectURI( 62 RedirectURIMatchingMode.REGEX, 63 "https://[\\d\\w]+.pr.test.goauthentik.io/source/oauth/callback/authentik/", 64 ), 65 ] 66 self.provider.save() 67 self.provider.refresh_from_db() 68 self.assertIsNone(self.provider.launch_url) 69 70 def test_validate_redirect_uris(self): 71 """Test redirect_uris API""" 72 response = self.client.post( 73 reverse("authentik_api:oauth2provider-list"), 74 data={ 75 "name": generate_id(), 76 "authorization_flow": create_test_flow().pk, 77 "invalidation_flow": create_test_flow().pk, 78 "redirect_uris": [ 79 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 80 {"matching_mode": "regex", "url": "**"}, 81 ], 82 }, 83 ) 84 self.assertJSONEqual(response.content, {"redirect_uris": ["Invalid Regex Pattern: **"]}) 85 86 def test_logout_uri_validation(self): 87 """Test logout_uri API validation""" 88 response = self.client.post( 89 reverse("authentik_api:oauth2provider-list"), 90 data={ 91 "name": generate_id(), 92 "authorization_flow": create_test_flow().pk, 93 "invalidation_flow": create_test_flow().pk, 94 "redirect_uris": [ 95 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 96 ], 97 "logout_uri": "invalid-url", 98 "logout_method": "backchannel", 99 }, 100 ) 101 self.assertEqual(response.status_code, 400) 102 103 def test_logout_uri_create_and_retrieve(self): 104 """Test creating and retrieving logout URI with method""" 105 response = self.client.post( 106 reverse("authentik_api:oauth2provider-list"), 107 data={ 108 "name": generate_id(), 109 "authorization_flow": create_test_flow().pk, 110 "invalidation_flow": create_test_flow().pk, 111 "redirect_uris": [ 112 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 113 ], 114 "logout_uri": "http://goauthentik.io/logout", 115 "logout_method": "backchannel", 116 }, 117 ) 118 self.assertEqual(response.status_code, 201) 119 provider_data = response.json() 120 self.assertEqual(provider_data["logout_uri"], "http://goauthentik.io/logout") 121 self.assertEqual(provider_data["logout_method"], "backchannel") 122 123 # Test retrieving the provider 124 provider_pk = provider_data["pk"] 125 response = self.client.get( 126 reverse("authentik_api:oauth2provider-detail", kwargs={"pk": provider_pk}) 127 ) 128 self.assertEqual(response.status_code, 200) 129 retrieved_data = response.json() 130 self.assertEqual(retrieved_data["logout_uri"], "http://goauthentik.io/logout") 131 self.assertEqual(retrieved_data["logout_method"], "backchannel")
Test api view
@apply_blueprint('system/providers-oauth2.yaml')
def
setUp(self) -> None:
26 @apply_blueprint("system/providers-oauth2.yaml") 27 def setUp(self) -> None: 28 self.provider: OAuth2Provider = OAuth2Provider.objects.create( 29 name="test", 30 authorization_flow=create_test_flow(), 31 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 32 ) 33 self.provider.property_mappings.set(ScopeMapping.objects.all()) 34 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 35 self.user = create_test_admin_user() 36 self.client.force_login(self.user)
Hook method for setting up the test fixture before exercising it.
def
test_preview(self):
38 def test_preview(self): 39 """Test Preview API Endpoint""" 40 response = self.client.get( 41 reverse("authentik_api:oauth2provider-preview-user", kwargs={"pk": self.provider.pk}) 42 ) 43 self.assertEqual(response.status_code, 200) 44 body = loads(response.content.decode())["preview"] 45 self.assertEqual(body["iss"], "http://testserver/application/o/test/")
Test Preview API Endpoint
def
test_setup_urls(self):
47 def test_setup_urls(self): 48 """Test Setup URLs API Endpoint""" 49 response = self.client.get( 50 reverse("authentik_api:oauth2provider-setup-urls", kwargs={"pk": self.provider.pk}) 51 ) 52 self.assertEqual(response.status_code, 200) 53 body = loads(response.content.decode()) 54 self.assertEqual(body["issuer"], "http://testserver/application/o/test/")
Test Setup URLs API Endpoint
@skipUnless(version_info >= (3, 11, 4), 'This behaviour is only Python 3.11.4 and up')
def
test_launch_url(self):
57 @skipUnless(version_info >= (3, 11, 4), "This behaviour is only Python 3.11.4 and up") 58 def test_launch_url(self): 59 """Test launch_url""" 60 self.provider.redirect_uris = [ 61 RedirectURI( 62 RedirectURIMatchingMode.REGEX, 63 "https://[\\d\\w]+.pr.test.goauthentik.io/source/oauth/callback/authentik/", 64 ), 65 ] 66 self.provider.save() 67 self.provider.refresh_from_db() 68 self.assertIsNone(self.provider.launch_url)
Test launch_url
def
test_validate_redirect_uris(self):
70 def test_validate_redirect_uris(self): 71 """Test redirect_uris API""" 72 response = self.client.post( 73 reverse("authentik_api:oauth2provider-list"), 74 data={ 75 "name": generate_id(), 76 "authorization_flow": create_test_flow().pk, 77 "invalidation_flow": create_test_flow().pk, 78 "redirect_uris": [ 79 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 80 {"matching_mode": "regex", "url": "**"}, 81 ], 82 }, 83 ) 84 self.assertJSONEqual(response.content, {"redirect_uris": ["Invalid Regex Pattern: **"]})
Test redirect_uris API
def
test_logout_uri_validation(self):
86 def test_logout_uri_validation(self): 87 """Test logout_uri API validation""" 88 response = self.client.post( 89 reverse("authentik_api:oauth2provider-list"), 90 data={ 91 "name": generate_id(), 92 "authorization_flow": create_test_flow().pk, 93 "invalidation_flow": create_test_flow().pk, 94 "redirect_uris": [ 95 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 96 ], 97 "logout_uri": "invalid-url", 98 "logout_method": "backchannel", 99 }, 100 ) 101 self.assertEqual(response.status_code, 400)
Test logout_uri API validation
def
test_logout_uri_create_and_retrieve(self):
103 def test_logout_uri_create_and_retrieve(self): 104 """Test creating and retrieving logout URI with method""" 105 response = self.client.post( 106 reverse("authentik_api:oauth2provider-list"), 107 data={ 108 "name": generate_id(), 109 "authorization_flow": create_test_flow().pk, 110 "invalidation_flow": create_test_flow().pk, 111 "redirect_uris": [ 112 {"matching_mode": "strict", "url": "http://goauthentik.io"}, 113 ], 114 "logout_uri": "http://goauthentik.io/logout", 115 "logout_method": "backchannel", 116 }, 117 ) 118 self.assertEqual(response.status_code, 201) 119 provider_data = response.json() 120 self.assertEqual(provider_data["logout_uri"], "http://goauthentik.io/logout") 121 self.assertEqual(provider_data["logout_method"], "backchannel") 122 123 # Test retrieving the provider 124 provider_pk = provider_data["pk"] 125 response = self.client.get( 126 reverse("authentik_api:oauth2provider-detail", kwargs={"pk": provider_pk}) 127 ) 128 self.assertEqual(response.status_code, 200) 129 retrieved_data = response.json() 130 self.assertEqual(retrieved_data["logout_uri"], "http://goauthentik.io/logout") 131 self.assertEqual(retrieved_data["logout_method"], "backchannel")
Test creating and retrieving logout URI with method