From 00710f75d2139ab3cc792ea799d9213af7d93af2 Mon Sep 17 00:00:00 2001 From: ichuang Date: Mon, 15 Jul 2013 00:37:26 +0000 Subject: [PATCH] add CAS authentication via django_cas and mods to external_auth --- common/djangoapps/external_auth/views.py | 31 +++++++++++++++++++++++- common/djangoapps/student/views.py | 8 +++++- lms/envs/common.py | 13 ++++++++++ lms/urls.py | 6 +++++ requirements/edx/base.txt | 3 +++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py index 37dcd5313a..aea36cd808 100644 --- a/common/djangoapps/external_auth/views.py +++ b/common/djangoapps/external_auth/views.py @@ -17,7 +17,10 @@ from django.core.urlresolvers import reverse from django.core.validators import validate_email from django.core.exceptions import ValidationError -from student.models import TestCenterUser, TestCenterRegistration +if settings.MITX_FEATURES.get('AUTH_USE_CAS'): + from django_cas.views import login as django_cas_login + +from student.models import UserProfile, TestCenterUser, TestCenterRegistration from django.http import HttpResponse, HttpResponseRedirect, HttpRequest, HttpResponseForbidden from django.utils.http import urlquote @@ -381,6 +384,32 @@ def ssl_login(request): ) +# ----------------------------------------------------------------------------- +# CAS (Central Authentication Service) +# ----------------------------------------------------------------------------- +def cas_login(request, next_page=None, required=False): + """ + Uses django_cas for authentication. + CAS is a common authentcation method pioneered by Yale. + See http://en.wikipedia.org/wiki/Central_Authentication_Service + + Does normal CAS login then generates user_profile if nonexistent, + and if login was successful. We assume that user details are + maintained by the central service, and thus an empty user profile + is appropriate. + """ + + ret = django_cas_login(request, next_page, required) + + if request.user.is_authenticated(): + user = request.user + if not UserProfile.objects.filter(user=user): + up = UserProfile(name=user.username, user=user) + up.save() + + return ret + + # ----------------------------------------------------------------------------- # Shibboleth (Stanford and others. Uses *Apache* environment variables) # ----------------------------------------------------------------------------- diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index b1b8f6ff1e..6e19c9ad5f 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -409,6 +409,8 @@ def change_enrollment(request): @ensure_csrf_cookie def accounts_login(request, error=""): + if settings.MITX_FEATURES.get('AUTH_USE_CAS'): + return redirect(reverse('cas-login')) return render_to_response('login.html', {'error': error}) # Need different levels of logging @@ -505,7 +507,11 @@ def logout_user(request): # We do not log here, because we have a handler registered # to perform logging on successful logouts. logout(request) - response = redirect('/') + if settings.MITX_FEATURES.get('AUTH_USE_CAS'): + target = reverse('cas-logout') + else: + target = '/' + response = redirect(target) response.delete_cookie(settings.EDXMKTG_COOKIE_NAME, path='/', domain=settings.SESSION_COOKIE_DOMAIN) diff --git a/lms/envs/common.py b/lms/envs/common.py index 4e70f3ade1..45499b59cc 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -92,6 +92,7 @@ MITX_FEATURES = { 'AUTH_USE_MIT_CERTIFICATES': False, 'AUTH_USE_OPENID_PROVIDER': False, 'AUTH_USE_SHIB': False, + 'AUTH_USE_CAS': False, # This flag disables the requirement of having to agree to the TOS for users registering # with Shib. Feature was requested by Stanford's office of general counsel @@ -853,3 +854,15 @@ def enable_theme(theme_name): # avoid collisions with default edX static files STATICFILES_DIRS.append((u'themes/%s' % theme_name, theme_root / 'static')) + +######################## CAS authentication ########################### + +if MITX_FEATURES.get('AUTH_USE_CAS'): + CAS_SERVER_URL = 'https://provide_your_cas_url_here' + AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'django_cas.backends.CASBackend', + ) + INSTALLED_APPS += ('django_cas',) + MIDDLEWARE_CLASSES += ('django_cas.middleware.CASMiddleware',) + diff --git a/lms/urls.py b/lms/urls.py index 096d073af6..d0a04f7753 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -363,6 +363,12 @@ if settings.MITX_FEATURES.get('AUTH_USE_SHIB'): url(r'^shib-login/$', 'external_auth.views.shib_login', name='shib-login'), ) +if settings.MITX_FEATURES.get('AUTH_USE_CAS'): + urlpatterns += ( + url(r'^cas-auth/login/$', 'external_auth.views.cas_login', name="cas-login"), + url(r'^cas-auth/logout/$', 'django_cas.views.logout', {'next_page': '/'}, name="cas-logout"), + ) + if settings.MITX_FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD'): urlpatterns += ( url(r'^course_specific_login/(?P[^/]+/[^/]+/[^/]+)/$', diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 8d609e05f1..f8f92983d8 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -92,3 +92,6 @@ nose-ignore-docstring nose-exclude git+https://github.com/mfogel/django-settings-context-processor.git + +# django-cas version 2.0.3 with patch to be compatible with django 1.4 +git+https://github.com/mitocw/django-cas.git