From fe6b666f5b0bea853ba627e7cff4adbab2904a0d Mon Sep 17 00:00:00 2001 From: jawad khan Date: Tue, 21 Jun 2022 23:58:39 +0500 Subject: [PATCH] feat: exchange third party auth token with jwt token (#30283) Exchange third party auth token wiith jwt token since mobile platform is moving to jwt token we need jwt token instead of access token now. LEARNER-8517 Co-authored-by: Robert Raposa --- .../oauth_dispatch/tests/test_views.py | 31 ++++++++++++++++++- .../core/djangoapps/oauth_dispatch/views.py | 19 ++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py b/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py index 7cd714e441..700bec6682 100644 --- a/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py +++ b/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py @@ -347,10 +347,14 @@ class TestAccessTokenExchangeView(ThirdPartyOAuthTestMixinGoogle, ThirdPartyOAut super().setUp() def _post_body(self, user, client, token_type=None, scope=None): - return { + body = { 'client_id': client.client_id, 'access_token': self.access_token, } + if token_type: + body['token_type'] = token_type + + return body @ddt.data('dot_app') def test_access_token_exchange_calls_dispatched_view(self, client_attr): @@ -360,6 +364,31 @@ class TestAccessTokenExchangeView(ThirdPartyOAuthTestMixinGoogle, ThirdPartyOAut response = self._post_request(self.user, client) assert response.status_code == 200 + @ddt.data('dot_app') + def test_jwt_access_token_exchange_calls_dispatched_view(self, client_attr): + client = getattr(self, client_attr) + self.oauth_client = client + self._setup_provider_response(success=True) + response = self._post_request(self.user, client, token_type='jwt') + assert response.status_code == 200 + + data = json.loads(response.content.decode('utf-8')) + assert 'expires_in' in data + assert data['expires_in'] > 0 + assert data['token_type'] == 'JWT' + + @ddt.data('dot_app') + def test_jwt_access_token_exchange_calls_dispatched_view_with_disabled_user(self, client_attr): + self.user.set_unusable_password() + self.user.save() + client = getattr(self, client_attr) + self.oauth_client = client + self._setup_provider_response(success=True) + response = self._post_request(self.user, client, token_type='jwt') + assert response.status_code == 403 + data = json.loads(response.content.decode('utf-8')) + assert data['error'] == 'account_disabled' + # pylint: disable=abstract-method @ddt.ddt diff --git a/openedx/core/djangoapps/oauth_dispatch/views.py b/openedx/core/djangoapps/oauth_dispatch/views.py index 2912c997eb..0e9684e95b 100644 --- a/openedx/core/djangoapps/oauth_dispatch/views.py +++ b/openedx/core/djangoapps/oauth_dispatch/views.py @@ -134,6 +134,25 @@ class AccessTokenExchangeView(_DispatchingView): """ dot_view = auth_exchange_views.DOTAccessTokenExchangeView + def dispatch(self, request, *args, **kwargs): + response = super().dispatch(request, *args, **kwargs) + token_type = _get_token_type(request) + + if response.status_code == 200 and token_type == 'jwt': + response.data = self._get_jwt_data_from_access_token_data(request, response) + + return response + + def _get_jwt_data_from_access_token_data(self, request, response): + """ + Gets the JWT response data from the opaque token response data. + + Includes the JWT token and token type in the response. + """ + opaque_token_dict = response.data + jwt_token_dict = create_jwt_token_dict(opaque_token_dict, self.get_adapter(request)) + return jwt_token_dict + class RevokeTokenView(_DispatchingView): """