Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions common/djangoapps/external_auth/tests/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import unittest

from django.conf import settings
from django.contrib.auth import SESSION_KEY
from django.contrib.auth.models import AnonymousUser, User
from django.contrib.sessions.middleware import SessionMiddleware
from django.core.urlresolvers import reverse
Expand Down Expand Up @@ -170,7 +171,7 @@ def test_default_login_decorator_ssl(self):
reverse('dashboard'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(reverse('dashboard'), response['location'])
self.assertIn('_auth_user_id', self.client.session)
self.assertIn(SESSION_KEY, self.client.session)

@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@override_settings(FEATURES=FEATURES_WITH_SSL_AUTH_IMMEDIATE_SIGNUP)
Expand All @@ -183,7 +184,7 @@ def test_registration_page_bypass(self):
reverse('register_user'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(reverse('dashboard'), response['location'])
self.assertIn('_auth_user_id', self.client.session)
self.assertIn(SESSION_KEY, self.client.session)

@unittest.skipUnless(settings.ROOT_URLCONF == 'cms.urls', 'Test only valid in cms')
@override_settings(FEATURES=FEATURES_WITH_SSL_AUTH_IMMEDIATE_SIGNUP)
Expand All @@ -199,7 +200,7 @@ def test_cms_registration_page_bypass(self):
reverse('signup'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
# assert that we are logged in
self.assertIn('_auth_user_id', self.client.session)
self.assertIn(SESSION_KEY, self.client.session)

# Now that we are logged in, make sure we don't see the registration page
with self.assertRaisesRegexp(InsufficientSpecificationError,
Expand All @@ -225,7 +226,7 @@ def test_signin_page_bypass(self):
reverse('signin_user'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(reverse('dashboard'), response['location'])
self.assertIn('_auth_user_id', self.client.session)
self.assertIn(SESSION_KEY, self.client.session)


@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
Expand All @@ -235,23 +236,21 @@ def test_ssl_bad_eamap(self):
This tests the response when a user exists but their eamap
password doesn't match their internal password.

This should start failing and can be removed when the
eamap.internal_password dependency is removed.
The internal password use for certificates has been removed
and this should not fail.
"""
# Create account, break internal password, and activate account
external_auth.views.ssl_login(self._create_ssl_request('/'))
user = User.objects.get(email=self.USER_EMAIL)
user.set_password('not autogenerated')
user.is_active = True
user.save()

# Validate user failed by checking log
output = StringIO.StringIO()
audit_log_handler = logging.StreamHandler(output)
audit_log = logging.getLogger("audit")
audit_log.addHandler(audit_log_handler)

request = self._create_ssl_request('/')
external_auth.views.ssl_login(request)
self.assertIn('External Auth Login failed for', output.getvalue())
# Make sure we can still login
self.client.get(
reverse('signin_user'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(SESSION_KEY, self.client.session)

@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@override_settings(FEATURES=FEATURES_WITHOUT_SSL_AUTH)
Expand Down
6 changes: 6 additions & 0 deletions common/djangoapps/external_auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def _external_login_or_signup(request,

log.info(u"External_Auth login_or_signup for %s : %s : %s : %s", external_domain, external_id, email, fullname)
uses_shibboleth = settings.FEATURES.get('AUTH_USE_SHIB') and external_domain.startswith(SHIBBOLETH_DOMAIN_PREFIX)
uses_certs = settings.FEATURES.get('AUTH_USE_CERTIFICATES')
internal_user = eamap.user
if internal_user is None:
if uses_shibboleth:
Expand Down Expand Up @@ -193,6 +194,11 @@ def _external_login_or_signup(request,
auth_backend = 'django.contrib.auth.backends.ModelBackend'
user.backend = auth_backend
AUDIT_LOG.info('Linked user "%s" logged in via Shibboleth', user.email)
elif uses_certs:
# Certificates are trusted, so just link the user and log the action
user = internal_user
user.backend = 'django.contrib.auth.backends.ModelBackend'
AUDIT_LOG.info('Linked user "%s" logged in via SSL certificate', user.email)
else:
user = authenticate(username=uname, password=eamap.internal_password, request=request)
if user is None:
Expand Down