From 82939c525088db42bf0ed89b9c89197fffb243f6 Mon Sep 17 00:00:00 2001 From: ichuang Date: Mon, 12 Aug 2013 20:41:58 +0000 Subject: [PATCH 1/5] fix external_auth @ssl_login_shortcut decorator to properly use retfun --- common/djangoapps/external_auth/views.py | 41 ++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py index 37dcd5313a94..db663fc7f849 100644 --- a/common/djangoapps/external_auth/views.py +++ b/common/djangoapps/external_auth/views.py @@ -42,8 +42,6 @@ from ratelimitbackend.exceptions import RateLimitException import student.views as student_views -# Required for Pearson -from courseware.views import get_module_for_descriptor, jump_to from courseware.model_data import ModelDataCache from xmodule.modulestore.django import modulestore from xmodule.course_module import CourseDescriptor @@ -178,7 +176,7 @@ def _external_login_or_signup(request, return _signup(request, eamap) else: log.info('No user for %s yet. doing signup', eamap.external_email) - return _signup(request, eamap) + return _signup(request, eamap, retfun) # We trust shib's authentication, so no need to authenticate using the password again uname = internal_user.username @@ -196,7 +194,7 @@ def _external_login_or_signup(request, if user is None: # we want to log the failure, but don't want to log the password attempted: AUDIT_LOG.warning('External Auth Login failed for "%s"', uname) - return _signup(request, eamap) + return _signup(request, eamap, retfun) if not user.is_active: AUDIT_LOG.warning('User "%s" is not active after external login', uname) @@ -223,7 +221,7 @@ def _external_login_or_signup(request, @ensure_csrf_cookie @cache_if_anonymous -def _signup(request, eamap): +def _signup(request, eamap, retfun=None): """ Present form to complete for signup via external authentication. Even though the user has external credentials, he/she still needs @@ -232,10 +230,30 @@ def _signup(request, eamap): eamap is an ExternalAuthMap object, specifying the external user for which to complete the signup. + + retfun is a function to execute for the return value, if immediate + signup is used. That allows @ssl_login_shortcut() to work. """ # save this for use by student.views.create_account request.session['ExternalAuthMap'] = eamap + if settings.MITX_FEATURES.get('AUTH_USE_MIT_CERTIFICATES_IMMEDIATE_SIGNUP',''): + # do signin immediately, by calling create_account, instead of asking + # student to fill in form. MIT students already have information filed. + username = eamap.external_email.split('@',1)[0] + username = username.replace('.','_') + post_vars = dict(username = username, + honor_code = u'true', + terms_of_service = u'true', + ) + ret = student_views.create_account(request, post_vars) + log.debug('doing immediate signup for %s, ret=%s' % (username, ret)) + # should check return content for successful completion before continuing + if retfun is not None: + return retfun() + else: + return ret + # default conjoin name, no spaces username = eamap.external_name.replace(' ', '') @@ -324,10 +342,17 @@ def wrapped(*args, **kwargs): if not settings.MITX_FEATURES['AUTH_USE_MIT_CERTIFICATES']: return fn(*args, **kwargs) request = args[0] + + if request.user and request.user.is_authenticated(): # don't re-authenticate + return fn(*args, **kwargs) + cert = _ssl_get_cert_from_request(request) if not cert: # no certificate information - show normal login window return fn(*args, **kwargs) + def retfun(): + return fn(*args, **kwargs) + (_user, email, fullname) = _ssl_dn_extract_info(cert) return _external_login_or_signup( request, @@ -335,7 +360,8 @@ def wrapped(*args, **kwargs): external_domain="ssl:MIT", credentials=cert, email=email, - fullname=fullname + fullname=fullname, + retfun=retfun, ) return wrapped @@ -839,6 +865,9 @@ def test_center_login(request): - exitURL - the url that we redirect to once we're done - vueExamSeriesCode - a code that indicates the exam that we're using ''' + # Required for Pearson + from courseware.views import get_module_for_descriptor, jump_to + # errors are returned by navigating to the error_url, adding a query parameter named "code" # which contains the error code describing the exceptional condition. def makeErrorURL(error_url, error_code): From 143d3f56e029b1d3d5e71730302341331e3a72ca Mon Sep 17 00:00:00 2001 From: ichuang Date: Wed, 4 Sep 2013 23:01:36 -0400 Subject: [PATCH 2/5] add missing retfun --- common/djangoapps/external_auth/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py index db663fc7f849..a6cdd6566c2f 100644 --- a/common/djangoapps/external_auth/views.py +++ b/common/djangoapps/external_auth/views.py @@ -173,7 +173,7 @@ def _external_login_or_signup(request, return default_render_failure(request, failure_msg) except User.DoesNotExist: log.info('SHIB: No user for %s yet, doing signup', eamap.external_email) - return _signup(request, eamap) + return _signup(request, eamap, retfun) else: log.info('No user for %s yet. doing signup', eamap.external_email) return _signup(request, eamap, retfun) From e82449480554099e8893a72e71cc23fdb7dce292 Mon Sep 17 00:00:00 2001 From: ichuang Date: Thu, 5 Sep 2013 07:51:41 -0400 Subject: [PATCH 3/5] change default '' to False in settings.get call --- common/djangoapps/external_auth/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py index a6cdd6566c2f..08a880fa1098 100644 --- a/common/djangoapps/external_auth/views.py +++ b/common/djangoapps/external_auth/views.py @@ -237,7 +237,7 @@ def _signup(request, eamap, retfun=None): # save this for use by student.views.create_account request.session['ExternalAuthMap'] = eamap - if settings.MITX_FEATURES.get('AUTH_USE_MIT_CERTIFICATES_IMMEDIATE_SIGNUP',''): + if settings.MITX_FEATURES.get('AUTH_USE_MIT_CERTIFICATES_IMMEDIATE_SIGNUP', False): # do signin immediately, by calling create_account, instead of asking # student to fill in form. MIT students already have information filed. username = eamap.external_email.split('@',1)[0] From 8a95b86cd3ac3923ae78896bee47376e29059328 Mon Sep 17 00:00:00 2001 From: ichuang Date: Thu, 5 Sep 2013 07:53:48 -0400 Subject: [PATCH 4/5] comment about import in test center code --- common/djangoapps/external_auth/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py index 08a880fa1098..fd613f684de2 100644 --- a/common/djangoapps/external_auth/views.py +++ b/common/djangoapps/external_auth/views.py @@ -866,6 +866,8 @@ def test_center_login(request): - vueExamSeriesCode - a code that indicates the exam that we're using ''' # Required for Pearson + # this import must be here because the test center code imports this file (can't have import loops) + # also, the test center code really needs refactoring - it is a huge kludge from courseware.views import get_module_for_descriptor, jump_to # errors are returned by navigating to the error_url, adding a query parameter named "code" From 3311ac3c8ed3d963063df0cf3b766c4eb118c197 Mon Sep 17 00:00:00 2001 From: ichuang Date: Tue, 8 Oct 2013 10:01:12 -0400 Subject: [PATCH 5/5] remove @cache_if_anonymous --- common/djangoapps/external_auth/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py index 4ad9f91b59ee..fab2ecfa9e81 100644 --- a/common/djangoapps/external_auth/views.py +++ b/common/djangoapps/external_auth/views.py @@ -237,7 +237,6 @@ def _flatten_to_ascii(txt): @ensure_csrf_cookie -@cache_if_anonymous def _signup(request, eamap, retfun=None): """ Present form to complete for signup via external authentication.