Commit 2da1e4ee by Carson Gee

Merge pull request #2674 from carsongee/cg/ssl_remove_password

Remove SSL Certifcate auth reliance on internal password
parents 10d1ea11 3303fb12
...@@ -8,6 +8,7 @@ import StringIO ...@@ -8,6 +8,7 @@ import StringIO
import unittest import unittest
from django.conf import settings from django.conf import settings
from django.contrib.auth import SESSION_KEY
from django.contrib.auth.models import AnonymousUser, User from django.contrib.auth.models import AnonymousUser, User
from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.sessions.middleware import SessionMiddleware
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
...@@ -170,7 +171,7 @@ class SSLClientTest(TestCase): ...@@ -170,7 +171,7 @@ class SSLClientTest(TestCase):
reverse('dashboard'), follow=True, reverse('dashboard'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL)) SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(reverse('dashboard'), response['location']) 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') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@override_settings(FEATURES=FEATURES_WITH_SSL_AUTH_IMMEDIATE_SIGNUP) @override_settings(FEATURES=FEATURES_WITH_SSL_AUTH_IMMEDIATE_SIGNUP)
...@@ -183,7 +184,7 @@ class SSLClientTest(TestCase): ...@@ -183,7 +184,7 @@ class SSLClientTest(TestCase):
reverse('register_user'), follow=True, reverse('register_user'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL)) SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(reverse('dashboard'), response['location']) 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') @unittest.skipUnless(settings.ROOT_URLCONF == 'cms.urls', 'Test only valid in cms')
@override_settings(FEATURES=FEATURES_WITH_SSL_AUTH_IMMEDIATE_SIGNUP) @override_settings(FEATURES=FEATURES_WITH_SSL_AUTH_IMMEDIATE_SIGNUP)
...@@ -199,7 +200,7 @@ class SSLClientTest(TestCase): ...@@ -199,7 +200,7 @@ class SSLClientTest(TestCase):
reverse('signup'), follow=True, reverse('signup'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL)) SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
# assert that we are logged in # 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 # Now that we are logged in, make sure we don't see the registration page
with self.assertRaisesRegexp(InsufficientSpecificationError, with self.assertRaisesRegexp(InsufficientSpecificationError,
...@@ -225,7 +226,7 @@ class SSLClientTest(TestCase): ...@@ -225,7 +226,7 @@ class SSLClientTest(TestCase):
reverse('signin_user'), follow=True, reverse('signin_user'), follow=True,
SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL)) SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
self.assertIn(reverse('dashboard'), response['location']) 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') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
...@@ -235,23 +236,21 @@ class SSLClientTest(TestCase): ...@@ -235,23 +236,21 @@ class SSLClientTest(TestCase):
This tests the response when a user exists but their eamap This tests the response when a user exists but their eamap
password doesn't match their internal password. password doesn't match their internal password.
This should start failing and can be removed when the The internal password use for certificates has been removed
eamap.internal_password dependency is removed. and this should not fail.
""" """
# Create account, break internal password, and activate account
external_auth.views.ssl_login(self._create_ssl_request('/')) external_auth.views.ssl_login(self._create_ssl_request('/'))
user = User.objects.get(email=self.USER_EMAIL) user = User.objects.get(email=self.USER_EMAIL)
user.set_password('not autogenerated') user.set_password('not autogenerated')
user.is_active = True
user.save() user.save()
# Validate user failed by checking log # Make sure we can still login
output = StringIO.StringIO() self.client.get(
audit_log_handler = logging.StreamHandler(output) reverse('signin_user'), follow=True,
audit_log = logging.getLogger("audit") SSL_CLIENT_S_DN=self.AUTH_DN.format(self.USER_NAME, self.USER_EMAIL))
audit_log.addHandler(audit_log_handler) self.assertIn(SESSION_KEY, self.client.session)
request = self._create_ssl_request('/')
external_auth.views.ssl_login(request)
self.assertIn('External Auth Login failed for', output.getvalue())
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@override_settings(FEATURES=FEATURES_WITHOUT_SSL_AUTH) @override_settings(FEATURES=FEATURES_WITHOUT_SSL_AUTH)
......
...@@ -151,6 +151,7 @@ def _external_login_or_signup(request, ...@@ -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) 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_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 internal_user = eamap.user
if internal_user is None: if internal_user is None:
if uses_shibboleth: if uses_shibboleth:
...@@ -193,6 +194,11 @@ def _external_login_or_signup(request, ...@@ -193,6 +194,11 @@ def _external_login_or_signup(request,
auth_backend = 'django.contrib.auth.backends.ModelBackend' auth_backend = 'django.contrib.auth.backends.ModelBackend'
user.backend = auth_backend user.backend = auth_backend
AUDIT_LOG.info('Linked user "%s" logged in via Shibboleth', user.email) 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: else:
user = authenticate(username=uname, password=eamap.internal_password, request=request) user = authenticate(username=uname, password=eamap.internal_password, request=request)
if user is None: if user is None:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment