Skip to content

Commit f28758a

Browse files
authored
Merge pull request #27 from makinacorpus/fix_spectacular
Fix invalid well_known url in drf spectacular schema
2 parents 5f9b400 + f63e024 commit f28758a

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ If you are not satisfied with the default configuration, take a look at the cook
3131
- Easy configuration through premade `Provider` classes (see the list [here](https://django-pyoidc.readthedocs.io/latest/reference.html#providers))
3232
- Authenticate users from multiple providers
3333
- Bearer authentication support for [django-rest-framework](https://www.django-rest-framework.org/) integration (**single provider**)
34+
- [drf-spectacular](https://drf-spectacular.readthedocs.io/en/latest/customization.html) : your swagger page will allow to connect to your OIDC provider
3435
- Easy integration with the [Django permission system](https://django-pyoidc.readthedocs.io/latest/how-to.html#use-the-django-permission-system-with-oidc)
3536
- Highly customizable design that should suit most needs
3637
- Support back-channel logout

django_pyoidc/apps.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from django.apps import AppConfig
2+
3+
4+
class DjangoPyoidcConfig(AppConfig):
5+
name = "django_pyoidc"
6+
7+
def ready(self) -> None:
8+
# Register schema with drf_spectacular
9+
from .drf import schema # noqa: F401

django_pyoidc/drf/schema.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ class OIDCScheme(OpenApiAuthenticationExtension): # type: ignore[no-untyped-cal
1313
match_subclasses = True
1414
priority = -1
1515

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

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

2227
header_name = opsettings.get("oidc_api_bearer_name", "Bearer")
2328
if header_name != "Bearer":

tests/tests_schema.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from unittest import mock
2+
3+
from django.test import TestCase
4+
5+
from django_pyoidc.drf.schema import OIDCScheme
6+
7+
8+
class OIDCShemaTestCase(TestCase):
9+
10+
@mock.patch("django_pyoidc.drf.schema.OIDCSettingsFactory.get")
11+
def test_security_definition_no_well_known_endpoint(self, mocked_get_settings):
12+
mocked_get_settings.return_value = {
13+
"provider_discovery_uri": "https://sso.demo/realms/test"
14+
}
15+
result = OIDCScheme.get_security_definition(None)
16+
self.assertEqual(
17+
result["openIdConnectUrl"],
18+
"https://sso.demo/realms/test/.well-known/openid-configuration",
19+
)
20+
21+
@mock.patch("django_pyoidc.drf.schema.OIDCSettingsFactory.get")
22+
def test_security_definition_with_well_known_endpoint(self, mocked_get_settings):
23+
mocked_get_settings.return_value = {
24+
"provider_discovery_uri": "https://sso.demo/realms/test/.well-known/openid-configuration"
25+
}
26+
result = OIDCScheme.get_security_definition(None)
27+
self.assertEqual(
28+
result["openIdConnectUrl"],
29+
"https://sso.demo/realms/test/.well-known/openid-configuration",
30+
)

0 commit comments

Comments
 (0)