Skip to content

Fix invalid well_known url in drf spectacular schema #27

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

Merged
merged 1 commit into from
Mar 26, 2025
Merged
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ If you are not satisfied with the default configuration, take a look at the cook
- Easy configuration through premade `Provider` classes (see the list [here](https://django-pyoidc.readthedocs.io/latest/reference.html#providers))
- Authenticate users from multiple providers
- Bearer authentication support for [django-rest-framework](https://www.django-rest-framework.org/) integration (**single provider**)
- [drf-spectacular](https://drf-spectacular.readthedocs.io/en/latest/customization.html) : your swagger page will allow to connect to your OIDC provider
- Easy integration with the [Django permission system](https://django-pyoidc.readthedocs.io/latest/how-to.html#use-the-django-permission-system-with-oidc)
- Highly customizable design that should suit most needs
- Support back-channel logout
Expand Down
9 changes: 9 additions & 0 deletions django_pyoidc/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.apps import AppConfig


class DjangoPyoidcConfig(AppConfig):
name = "django_pyoidc"

def ready(self) -> None:
# Register schema with drf_spectacular
from .drf import schema # noqa: F401
9 changes: 7 additions & 2 deletions django_pyoidc/drf/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ class OIDCScheme(OpenApiAuthenticationExtension): # type: ignore[no-untyped-cal
match_subclasses = True
priority = -1

def get_security_definition(self, auto_schema): # type: ignore[no-untyped-def] # we do not want to type third party libraries
@classmethod
def get_security_definition(cls, auto_schema): # type: ignore[no-untyped-def] # we do not want to type third party libraries
# from django_pyoidc.drf.authentication import OIDCBearerAuthentication

opsettings = OIDCSettingsFactory.get("drf")
well_known_url = opsettings.get("provider_discovery_uri")
well_known_url: str = opsettings.get("provider_discovery_uri") # type: ignore[assignment] # we can assume that this is an str
if not well_known_url.endswith(".well-known/openid-configuration"):
well_known_url = (
well_known_url + "/.well-known/openid-configuration"
) # well_known_url should not end with a "/" as it is sanitized

header_name = opsettings.get("oidc_api_bearer_name", "Bearer")
if header_name != "Bearer":
Expand Down
30 changes: 30 additions & 0 deletions tests/tests_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from unittest import mock

from django.test import TestCase

from django_pyoidc.drf.schema import OIDCScheme


class OIDCShemaTestCase(TestCase):

@mock.patch("django_pyoidc.drf.schema.OIDCSettingsFactory.get")
def test_security_definition_no_well_known_endpoint(self, mocked_get_settings):
mocked_get_settings.return_value = {
"provider_discovery_uri": "https://sso.demo/realms/test"
}
result = OIDCScheme.get_security_definition(None)
self.assertEqual(
result["openIdConnectUrl"],
"https://sso.demo/realms/test/.well-known/openid-configuration",
)

@mock.patch("django_pyoidc.drf.schema.OIDCSettingsFactory.get")
def test_security_definition_with_well_known_endpoint(self, mocked_get_settings):
mocked_get_settings.return_value = {
"provider_discovery_uri": "https://sso.demo/realms/test/.well-known/openid-configuration"
}
result = OIDCScheme.get_security_definition(None)
self.assertEqual(
result["openIdConnectUrl"],
"https://sso.demo/realms/test/.well-known/openid-configuration",
)