diff --git a/openedx/core/djangoapps/user_authn/urls.py b/openedx/core/djangoapps/user_authn/urls.py index f9d93d1ab1..6b7807de0f 100644 --- a/openedx/core/djangoapps/user_authn/urls.py +++ b/openedx/core/djangoapps/user_authn/urls.py @@ -2,13 +2,14 @@ from django.urls import include, path -from .views import login, login_form +from .views import auth, login, login_form urlpatterns = [ # TODO move contents of urls_common here once CMS no longer has its own login path('', include('openedx.core.djangoapps.user_authn.urls_common')), path('api/', include('openedx.core.djangoapps.user_authn.api.urls')), path('account/finish_auth', login.finish_auth, name='finish_auth'), + path('auth/jwks.json', auth.get_public_signing_jwks, name='get_public_signing_jwks'), ] diff --git a/openedx/core/djangoapps/user_authn/views/auth.py b/openedx/core/djangoapps/user_authn/views/auth.py new file mode 100644 index 0000000000..d2a8ab2314 --- /dev/null +++ b/openedx/core/djangoapps/user_authn/views/auth.py @@ -0,0 +1,16 @@ +""" Views related to auth. """ + + +from common.djangoapps.util.json_request import JsonResponse +from django.conf import settings + + +def get_public_signing_jwks(request): + """ + View to provide the auth related public signing JWK set as json. + """ + jwt_dict = settings.JWT_AUTH + if not jwt_dict.get('JWT_PUBLIC_SIGNING_JWK_SET'): + return JsonResponse({'error': 'JWK set is not found'}, status=400) + jwks = jwt_dict['JWT_PUBLIC_SIGNING_JWK_SET'] + return JsonResponse(jwks, status=200) diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_auth.py b/openedx/core/djangoapps/user_authn/views/tests/test_auth.py new file mode 100644 index 0000000000..fed7551a59 --- /dev/null +++ b/openedx/core/djangoapps/user_authn/views/tests/test_auth.py @@ -0,0 +1,37 @@ +""" Tests for auth. """ + + +import json +from django.test import TestCase +from django.conf import settings +from django.urls import reverse +from openedx.core.djangolib.testing.utils import skip_unless_lms +from unittest import mock + + +@skip_unless_lms +class getPublicSigningJWKSFunctionTest(TestCase): + """ + Tests for the auth view. + """ + def _get_jwks(self, accepts='application/json'): + """ Get JWKS from the endpoint """ + url = reverse('get_public_signing_jwks') + + return self.client.get(url, HTTP_ACCEPT=accepts) + + @mock.patch.dict(settings.JWT_AUTH, {'JWT_PUBLIC_SIGNING_JWK_SET': None}) + def test_get_public_signing_jwks_with_no_jwk_set(self): + """ Test JWT_PUBLIC_SIGNING_JWK_SET is undefined """ + resp = self._get_jwks() + content = json.loads(resp.content) + assert resp.status_code == 400 + assert 'JWK set is not found' in content['error'] + + @mock.patch.dict(settings.JWT_AUTH, {'JWT_PUBLIC_SIGNING_JWK_SET': {'keys': []}}) + def test_get_public_signing_jwks_with_jwk_set(self): + """ Test JWT_PUBLIC_SIGNING_JWK_SET is defined """ + resp = self._get_jwks() + content = json.loads(resp.content) + assert resp.status_code == 200 + assert content['keys'] == []