Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

providers/oauth2: Add provider federation between OAuth2 Providers #12083

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion authentik/blueprints/v1/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@
from authentik.outposts.models import OutpostServiceConnection
from authentik.policies.models import Policy, PolicyBindingModel
from authentik.policies.reputation.models import Reputation
from authentik.providers.oauth2.models import AccessToken, AuthorizationCode, RefreshToken
from authentik.providers.oauth2.models import (
AccessToken,
AuthorizationCode,
DeviceToken,
RefreshToken,
)
from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
from authentik.rbac.models import Role
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
Expand Down Expand Up @@ -125,6 +130,7 @@ def excluded_models() -> list[type[Model]]:
MicrosoftEntraProviderGroup,
EndpointDevice,
EndpointDeviceConnection,
DeviceToken,
)


Expand Down
3 changes: 2 additions & 1 deletion authentik/providers/oauth2/api/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class Meta:
"sub_mode",
"property_mappings",
"issuer_mode",
"jwks_sources",
"jwt_federation_sources",
"jwt_federation_providers",
]
extra_kwargs = ProviderSerializer.Meta.extra_kwargs

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.0.9 on 2024-11-22 14:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("authentik_providers_oauth2", "0024_remove_oauth2provider_redirect_uris_and_more"),
]

operations = [
migrations.RenameField(
model_name="oauth2provider",
old_name="jwks_sources",
new_name="jwt_federation_sources",
),
migrations.AddField(
model_name="oauth2provider",
name="jwt_federation_providers",
field=models.ManyToManyField(
blank=True, default=None, to="authentik_providers_oauth2.oauth2provider"
),
),
]
3 changes: 2 additions & 1 deletion authentik/providers/oauth2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class OAuth2Provider(WebfingerProvider, Provider):
related_name="oauth2provider_encryption_key_set",
)

jwks_sources = models.ManyToManyField(
jwt_federation_sources = models.ManyToManyField(
OAuthSource,
verbose_name=_(
"Any JWT signed by the JWK of the selected source can be used to authenticate."
Expand All @@ -253,6 +253,7 @@ class OAuth2Provider(WebfingerProvider, Provider):
default=None,
blank=True,
)
jwt_federation_providers = models.ManyToManyField("OAuth2Provider", blank=True, default=None)

@cached_property
def jwt_key(self) -> tuple[str | PrivateKeyTypes, str]:
Expand Down
222 changes: 222 additions & 0 deletions authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
"""Test token view"""

from datetime import datetime, timedelta
from json import loads

Check warning on line 4 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L3-L4

Added lines #L3 - L4 were not covered by tests

from django.test import RequestFactory
from django.urls import reverse
from django.utils.timezone import now
from jwt import decode

Check warning on line 9 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L6-L9

Added lines #L6 - L9 were not covered by tests

from authentik.blueprints.tests import apply_blueprint
from authentik.core.models import Application, Group
from authentik.core.tests.utils import create_test_cert, create_test_flow, create_test_user
from authentik.lib.generators import generate_id
from authentik.policies.models import PolicyBinding
from authentik.providers.oauth2.constants import (

Check warning on line 16 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L11-L16

Added lines #L11 - L16 were not covered by tests
GRANT_TYPE_CLIENT_CREDENTIALS,
SCOPE_OPENID,
SCOPE_OPENID_EMAIL,
SCOPE_OPENID_PROFILE,
TOKEN_TYPE,
)
from authentik.providers.oauth2.models import AccessToken, OAuth2Provider, ScopeMapping
from authentik.providers.oauth2.tests.utils import OAuthTestCase

Check warning on line 24 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L23-L24

Added lines #L23 - L24 were not covered by tests


class TestTokenClientCredentialsJWTProvider(OAuthTestCase):

Check warning on line 27 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L27

Added line #L27 was not covered by tests
"""Test token (client_credentials, with JWT) view"""

@apply_blueprint("system/providers-oauth2.yaml")
def setUp(self) -> None:
super().setUp()
self.factory = RequestFactory()
self.other_cert = create_test_cert()
self.cert = create_test_cert()

Check warning on line 35 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L30-L35

Added lines #L30 - L35 were not covered by tests

self.other_provider = OAuth2Provider.objects.create(

Check warning on line 37 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L37

Added line #L37 was not covered by tests
name=generate_id(),
authorization_flow=create_test_flow(),
signing_key=self.other_cert,
)
self.other_provider.property_mappings.set(ScopeMapping.objects.all())
self.app = Application.objects.create(

Check warning on line 43 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L42-L43

Added lines #L42 - L43 were not covered by tests
name=generate_id(), slug=generate_id(), provider=self.other_provider
)

self.provider: OAuth2Provider = OAuth2Provider.objects.create(

Check warning on line 47 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L47

Added line #L47 was not covered by tests
name="test",
authorization_flow=create_test_flow(),
redirect_uris="http://testserver",
signing_key=self.cert,
)
self.provider.jwt_federation_providers.add(self.other_provider)
self.provider.property_mappings.set(ScopeMapping.objects.all())
self.app = Application.objects.create(name="test", slug="test", provider=self.provider)

Check warning on line 55 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L53-L55

Added lines #L53 - L55 were not covered by tests

def test_invalid_type(self):

Check warning on line 57 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L57

Added line #L57 was not covered by tests
"""test invalid type"""

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_successful TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_type TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_no_app TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_jwt TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_expired TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_access_denied TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_signature TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_jwt TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_signature TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_type TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_successful TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_no_app TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_expired TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 15-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_access_denied TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_expired TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_access_denied TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_jwt TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_type TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_signature TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_successful TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-unittest - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_no_app TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_successful TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_no_app TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_signature TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_expired TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_access_denied TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_type TypeError: asdict() should be called on dataclass instances

Check failure on line 58 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View workflow job for this annotation

GitHub Actions / test-migrations-from-stable - PostgreSQL 16-alpine

TestTokenClientCredentialsJWTProvider.test_invalid_jwt TypeError: asdict() should be called on dataclass instances
response = self.client.post(

Check warning on line 59 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L59

Added line #L59 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "foo",
"client_assertion": "foo.bar",
},
)
self.assertEqual(response.status_code, 400)
body = loads(response.content.decode())
self.assertEqual(body["error"], "invalid_grant")

Check warning on line 71 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L69-L71

Added lines #L69 - L71 were not covered by tests

def test_invalid_jwt(self):

Check warning on line 73 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L73

Added line #L73 was not covered by tests
"""test invalid JWT"""
response = self.client.post(

Check warning on line 75 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L75

Added line #L75 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": "foo.bar",
},
)
self.assertEqual(response.status_code, 400)
body = loads(response.content.decode())
self.assertEqual(body["error"], "invalid_grant")

Check warning on line 87 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L85-L87

Added lines #L85 - L87 were not covered by tests

def test_invalid_signature(self):

Check warning on line 89 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L89

Added line #L89 was not covered by tests
"""test invalid JWT"""
token = self.provider.encode(

Check warning on line 91 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L91

Added line #L91 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
}
)
response = self.client.post(

Check warning on line 97 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L97

Added line #L97 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": token + "foo",
},
)
self.assertEqual(response.status_code, 400)
body = loads(response.content.decode())
self.assertEqual(body["error"], "invalid_grant")

Check warning on line 109 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L107-L109

Added lines #L107 - L109 were not covered by tests

def test_invalid_expired(self):

Check warning on line 111 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L111

Added line #L111 was not covered by tests
"""test invalid JWT"""
token = self.provider.encode(

Check warning on line 113 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L113

Added line #L113 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() - timedelta(hours=2),
}
)
response = self.client.post(

Check warning on line 119 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L119

Added line #L119 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": token,
},
)
self.assertEqual(response.status_code, 400)
body = loads(response.content.decode())
self.assertEqual(body["error"], "invalid_grant")

Check warning on line 131 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L129-L131

Added lines #L129 - L131 were not covered by tests

def test_invalid_no_app(self):

Check warning on line 133 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L133

Added line #L133 was not covered by tests
"""test invalid JWT"""
self.app.provider = None
self.app.save()
token = self.provider.encode(

Check warning on line 137 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L135-L137

Added lines #L135 - L137 were not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
}
)
response = self.client.post(

Check warning on line 143 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L143

Added line #L143 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": token,
},
)
self.assertEqual(response.status_code, 400)
body = loads(response.content.decode())
self.assertEqual(body["error"], "invalid_grant")

Check warning on line 155 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L153-L155

Added lines #L153 - L155 were not covered by tests

def test_invalid_access_denied(self):

Check warning on line 157 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L157

Added line #L157 was not covered by tests
"""test invalid JWT"""
group = Group.objects.create(name="foo")
PolicyBinding.objects.create(

Check warning on line 160 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L159-L160

Added lines #L159 - L160 were not covered by tests
group=group,
target=self.app,
order=0,
)
token = self.provider.encode(

Check warning on line 165 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L165

Added line #L165 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
}
)
response = self.client.post(

Check warning on line 171 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L171

Added line #L171 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": token,
},
)
self.assertEqual(response.status_code, 400)
body = loads(response.content.decode())
self.assertEqual(body["error"], "invalid_grant")

Check warning on line 183 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L181-L183

Added lines #L181 - L183 were not covered by tests

def test_successful(self):

Check warning on line 185 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L185

Added line #L185 was not covered by tests
"""test successful"""
user = create_test_user()
token = self.other_provider.encode(

Check warning on line 188 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L187-L188

Added lines #L187 - L188 were not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
}
)
AccessToken.objects.create(

Check warning on line 194 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L194

Added line #L194 was not covered by tests
provider=self.other_provider,
token=token,
user=user,
auth_time=now(),
)

response = self.client.post(

Check warning on line 201 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L201

Added line #L201 was not covered by tests
reverse("authentik_providers_oauth2:token"),
{
"grant_type": GRANT_TYPE_CLIENT_CREDENTIALS,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}",
"client_id": self.provider.client_id,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": token,
},
)
self.assertEqual(response.status_code, 200)
body = loads(response.content.decode())
self.assertEqual(body["token_type"], TOKEN_TYPE)
_, alg = self.provider.jwt_key
jwt = decode(

Check warning on line 215 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L211-L215

Added lines #L211 - L215 were not covered by tests
body["access_token"],
key=self.provider.signing_key.public_key,
algorithms=[alg],
audience=self.provider.client_id,
)
self.assertEqual(jwt["given_name"], user.name)
self.assertEqual(jwt["preferred_username"], user.username)

Check warning on line 222 in authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_provider.py#L221-L222

Added lines #L221 - L222 were not covered by tests
21 changes: 14 additions & 7 deletions authentik/providers/oauth2/tests/test_token_cc_jwt_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@
def setUp(self) -> None:
super().setUp()
self.factory = RequestFactory()
self.other_cert = create_test_cert()

Check warning on line 40 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L40

Added line #L40 was not covered by tests
# Provider used as a helper to sign JWTs with the same key as the OAuth source has
self.helper_provider = OAuth2Provider.objects.create(

Check warning on line 42 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L42

Added line #L42 was not covered by tests
name=generate_id(),
authorization_flow=create_test_flow(),
signing_key=self.other_cert,
)
self.cert = create_test_cert()

jwk = JWKSView().get_jwk_for_key(self.cert, "sig")
jwk = JWKSView().get_jwk_for_key(self.other_cert, "sig")

Check warning on line 49 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L49

Added line #L49 was not covered by tests
self.source: OAuthSource = OAuthSource.objects.create(
name=generate_id(),
slug=generate_id(),
Expand All @@ -62,7 +69,7 @@
redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")],
signing_key=self.cert,
)
self.provider.jwks_sources.add(self.source)
self.provider.jwt_federation_sources.add(self.source)

Check warning on line 72 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L72

Added line #L72 was not covered by tests
self.provider.property_mappings.set(ScopeMapping.objects.all())
self.app = Application.objects.create(name="test", slug="test", provider=self.provider)

Expand Down Expand Up @@ -100,7 +107,7 @@

def test_invalid_signature(self):
"""test invalid JWT"""
token = self.provider.encode(
token = self.helper_provider.encode(

Check warning on line 110 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L110

Added line #L110 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
Expand All @@ -122,7 +129,7 @@

def test_invalid_expired(self):
"""test invalid JWT"""
token = self.provider.encode(
token = self.helper_provider.encode(

Check warning on line 132 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L132

Added line #L132 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() - timedelta(hours=2),
Expand All @@ -146,7 +153,7 @@
"""test invalid JWT"""
self.app.provider = None
self.app.save()
token = self.provider.encode(
token = self.helper_provider.encode(

Check warning on line 156 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L156

Added line #L156 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
Expand Down Expand Up @@ -174,7 +181,7 @@
target=self.app,
order=0,
)
token = self.provider.encode(
token = self.helper_provider.encode(

Check warning on line 184 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L184

Added line #L184 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
Expand All @@ -196,7 +203,7 @@

def test_successful(self):
"""test successful"""
token = self.provider.encode(
token = self.helper_provider.encode(

Check warning on line 206 in authentik/providers/oauth2/tests/test_token_cc_jwt_source.py

View check run for this annotation

Codecov / codecov/patch

authentik/providers/oauth2/tests/test_token_cc_jwt_source.py#L206

Added line #L206 was not covered by tests
{
"sub": "foo",
"exp": datetime.now() + timedelta(hours=2),
Expand Down
2 changes: 1 addition & 1 deletion authentik/providers/oauth2/views/device_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def validate_code(self, code: int) -> HttpResponse | None:


class OAuthDeviceCodeStage(ChallengeStageView):
"""Flow challenge for users to enter device codes"""
"""Flow challenge for users to enter device code"""

response_class = OAuthDeviceCodeChallengeResponse

Expand Down
Loading
Loading