From a654d5e7acca986b8ef525ef322a18f508017580 Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Wed, 2 Dec 2015 19:49:07 -0800 Subject: [PATCH] Add additional data to custom SSO auth form extension points --- common/djangoapps/third_party_auth/pipeline.py | 11 ++++++++--- .../third_party_auth/tests/specs/test_google.py | 5 ++++- common/djangoapps/third_party_auth/views.py | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/common/djangoapps/third_party_auth/pipeline.py b/common/djangoapps/third_party_auth/pipeline.py index 4700a1938c..de7d081f26 100644 --- a/common/djangoapps/third_party_auth/pipeline.py +++ b/common/djangoapps/third_party_auth/pipeline.py @@ -461,7 +461,7 @@ def set_pipeline_timeout(strategy, user, *args, **kwargs): # choice of the user. -def redirect_to_custom_form(request, auth_entry, user_details): +def redirect_to_custom_form(request, auth_entry, kwargs): """ If auth_entry is found in AUTH_ENTRY_CUSTOM, this is used to send provider data to an external server's registration/login page. @@ -469,13 +469,18 @@ def redirect_to_custom_form(request, auth_entry, user_details): The data is sent as a base64-encoded values in a POST request and includes a cryptographic checksum in case the integrity of the data is important. """ + backend_name = request.backend.name + provider_id = provider.Registry.get_from_pipeline({'backend': backend_name, 'kwargs': kwargs}).provider_id form_info = AUTH_ENTRY_CUSTOM[auth_entry] secret_key = form_info['secret_key'] if isinstance(secret_key, unicode): secret_key = secret_key.encode('utf-8') custom_form_url = form_info['url'] data_str = json.dumps({ - "user_details": user_details + "auth_entry": auth_entry, + "backend_name": backend_name, + "provider_id": provider_id, + "user_details": kwargs['details'], }) digest = hmac.new(secret_key, msg=data_str, digestmod=hashlib.sha256).digest() # Store the data in the session temporarily, then redirect to a page that will POST it to @@ -537,7 +542,7 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia raise AuthEntryError(backend, 'auth_entry is wrong. Settings requires a user.') elif auth_entry in AUTH_ENTRY_CUSTOM: # Pass the username, email, etc. via query params to the custom entry page: - return redirect_to_custom_form(strategy.request, auth_entry, kwargs['details']) + return redirect_to_custom_form(strategy.request, auth_entry, kwargs) else: raise AuthEntryError(backend, 'auth_entry invalid') diff --git a/common/djangoapps/third_party_auth/tests/specs/test_google.py b/common/djangoapps/third_party_auth/tests/specs/test_google.py index 1d4c144cd0..a4d37e40db 100644 --- a/common/djangoapps/third_party_auth/tests/specs/test_google.py +++ b/common/djangoapps/third_party_auth/tests/specs/test_google.py @@ -80,13 +80,16 @@ class GoogleOauth2IntegrationTest(base.Oauth2IntegrationTest): data_parsed = json.loads(data_decoded) # The user's details get passed to the custom page as a base64 encoded query parameter: self.assertEqual(data_parsed, { + 'auth_entry': 'custom1', + 'backend_name': 'google-oauth2', + 'provider_id': 'oa2-google-oauth2', 'user_details': { 'username': 'email_value', 'email': 'email_value@example.com', 'fullname': 'name_value', 'first_name': 'given_name_value', 'last_name': 'family_name_value', - } + }, }) # Check the hash that is used to confirm the user's data in the GET parameter is correct secret_key = settings.THIRD_PARTY_AUTH_CUSTOM_AUTH_FORMS['custom1']['secret_key'] diff --git a/common/djangoapps/third_party_auth/views.py b/common/djangoapps/third_party_auth/views.py index 505d69c187..56d34dd178 100644 --- a/common/djangoapps/third_party_auth/views.py +++ b/common/djangoapps/third_party_auth/views.py @@ -74,7 +74,7 @@ def post_to_custom_auth_form(request): # Verify the format of pipeline_data: data = { 'post_url': pipeline_data['post_url'], - # The user's name, email, etc. as base64 encoded JSON + # data: The provider info and user's name, email, etc. as base64 encoded JSON # It's base64 encoded because it's signed cryptographically and we don't want whitespace # or ordering issues affecting the hash/signature. 'data': pipeline_data['data'],