diff --git a/gracedb/api/tests/test_authentication.py b/gracedb/api/tests/test_authentication.py new file mode 100644 index 0000000000000000000000000000000000000000..be56823f260199cb321a509dbc5ed5b63c805b92 --- /dev/null +++ b/gracedb/api/tests/test_authentication.py @@ -0,0 +1,286 @@ +from django.conf import settings +from django.test import RequestFactory +from django.test.utils import override_settings, modify_settings +from django.contrib.auth.models import Group, User, AnonymousUser +from django.urls import reverse +from django.core.exceptions import ImproperlyConfigured +from django.contrib.sessions.middleware import SessionMiddleware + +from ligoauth.middleware import ShibbolethWebAuthMiddleware + +# See this test class for information about what groups and users +# are already defined for use. +from core.tests.utils import GraceDbTestBase + +class TestX509Authentication(GraceDbTestBase): + """ + """ + + @classmethod + def setUpClass(cls): + # Make sure middleware is installed + if not any(['GraceDbX509Authentication' in m for m in + settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES']]): + raise ImproperlyConfigured(('GraceDbX509Authentication must be ' + 'installed in the DEFAULT_AUTHENTICATION_CLASSES element ' + 'of the REST_FRAMEWORK dictionary in your project settings')) + + # Attach request factory to class + cls.factory = RequestFactory() + + # Attach middleware to class + #cls.middleware = ShibbolethWebAuthMiddleware() + + @classmethod + def setUpTestData(cls): + # Call base class setUpTestData + super(TestX509Authentication, cls).setUpTestData() + + @classmethod + def setUp(cls): + cls.request = cls.factory.get(reverse('home')) + cls.request.user = AnonymousUser() + SessionMiddleware().process_request(cls.request) + cls.request.session.save() + + def test_web_path(self): + pass + + def test_basic_api_path(self): + pass + + def test_internal_user_auth(self): + # Can we check backend with this type of setup? + pass + + def test_lvem_user_auth(self): + pass + + def test_public_user_auth(self): + pass + + def test_proxy_auth(self): + # test proxy pattern thing + pass + +#class TestBasicAuthentication(GraceDbTestBase): +# Make sure to test password expiration + +class TestShibbolethWebAuthMiddleware(GraceDbTestBase): + + @classmethod + def setUpClass(cls): + # Make sure middleware is installed + if not any(['ShibbolethWebAuthMiddleware' in m for m in + settings.MIDDLEWARE]): + raise ImproperlyConfigured( + 'ShibbolethWebAuthMiddleware must be installed in MIDDLEWARE') + + # Attach request factory to class + cls.factory = RequestFactory() + + # Attach middleware to class + cls.middleware = ShibbolethWebAuthMiddleware() + + @classmethod + def setUpTestData(cls): + # Call base class setUpTestData + super(TestShibbolethWebAuthMiddleware, cls).setUpTestData() + + @classmethod + def setUp(cls): + cls.request = cls.factory.get(reverse('home')) + cls.request.user = AnonymousUser() + SessionMiddleware().process_request(cls.request) + cls.request.session.save() + + def test_internal_authentication(self): + """Test internal user authentication""" + self.request.META = { + settings.SHIB_USER_HEADER: self.internal_user.username, + settings.SHIB_GROUPS_HEADER: self.internal_group.name, + } + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and that the internal group is + # attached to the user account + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + self.assertIn(self.internal_group, self.request.user.groups.all()) + + def test_lvem_authentication(self): + """Test lvem user authentication""" + self.request.META = { + settings.SHIB_USER_HEADER: self.lvem_user.username, + settings.SHIB_GROUPS_HEADER: self.lvem_group.name, + } + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and that the lvem group is + # attached to the user account and that the internal group + # is NOT attached to the user account + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + self.assertIn(self.lvem_group, self.request.user.groups.all()) + self.assertNotIn(self.internal_group, self.request.user.groups.all()) + + def test_public_authentication(self): + """Test middleware on public user""" + self.middleware.process_request(self.request) + + # Make sure user is not authenticated and is anonymous, + # auth backend is not set, and the user has no groups + self.assertFalse(self.request.user.is_authenticated) + self.assertTrue(self.request.user.is_anonymous) + self.assertFalse(hasattr(self.request.user, 'backend')) + self.assertTrue(self.request.user.groups.count() == 0) + + def test_internal_user_creation(self): + """Test creating a new internal user in the auth framework""" + new_user_dict = { + 'username': 'new_internal.user', + 'email': 'new_internal.user@group.org', + } + self.request.META = { + settings.SHIB_USER_HEADER: new_user_dict['username'], + settings.SHIB_GROUPS_HEADER: self.internal_group.name, + settings.SHIB_ATTRIBUTE_MAP['email']: new_user_dict['email'], + } + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and that the internal group is + # attached to the user account + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + + # Make sure user information is correct + new_user = User.objects.get(username=new_user_dict['username']) + self.assertIn(self.internal_group, new_user.groups.all()) + self.assertEqual(new_user.username, new_user_dict['username']) + self.assertEqual(new_user.email, new_user_dict['email']) + + def test_lvem_user_creation(self): + """Test creating a new lvem user in the auth framework""" + new_user_dict = { + 'username': 'new_lvem.user', + 'email': 'new_lvem.user@group.org', + } + self.request.META = { + settings.SHIB_USER_HEADER: new_user_dict['username'], + settings.SHIB_GROUPS_HEADER: self.lvem_group.name, + settings.SHIB_ATTRIBUTE_MAP['email']: new_user_dict['email'], + } + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and that the internal group is + # attached to the user account + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + + # Make sure user information is correct + new_user = User.objects.get(username=new_user_dict['username']) + self.assertIn(self.lvem_group, new_user.groups.all()) + self.assertEqual(new_user.username, new_user_dict['username']) + self.assertEqual(new_user.email, new_user_dict['email']) + + def test_group_addition(self): + """Test group addition in middleware""" + # Create new group for testing + new_group = Group.objects.create(name='new_group') + + delim = ShibbolethWebAuthMiddleware.group_delimiter + groups_str = delim.join([self.internal_group.name, new_group.name]) + self.request.META = { + settings.SHIB_USER_HEADER: self.internal_user.username, + settings.SHIB_GROUPS_HEADER: groups_str, + } + + # Make sure user just has internal group initially + self.assertTrue(self.internal_user.groups.count() == 1) + self.assertTrue(self.internal_user.groups.all()[0] == + self.internal_group) + + # Process request + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and that the two groups attached are what + # we expect + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + self.assertTrue(self.internal_user.groups.count() == 2) + self.assertIn(self.internal_group, self.internal_user.groups.all()) + self.assertIn(new_group, self.internal_user.groups.all()) + + def test_group_removal(self): + """Test group addition in middleware""" + # Create new group, add to user + new_group = Group.objects.create(name='new_group') + self.internal_user.groups.add(new_group) + + # Shib session doesn't have new_group in it + self.request.META = { + settings.SHIB_USER_HEADER: self.internal_user.username, + settings.SHIB_GROUPS_HEADER: self.internal_group.name, + } + + # Make sure user just has internal group initially + self.assertTrue(self.internal_user.groups.count() == 2) + self.assertIn(self.internal_group, self.internal_user.groups.all()) + self.assertIn(new_group, self.internal_user.groups.all()) + + # Process request + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and only the internal group is attached + # to the user + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + self.assertTrue(self.internal_user.groups.count() == 1) + self.assertTrue(self.internal_user.groups.all()[0] == + self.internal_group) + self.assertNotIn(new_group, self.internal_user.groups.all()) + + def test_user_update(self): + """Test user information update in middleware""" + email1 = 'email1@email.com' + email2 = 'email2@email.com' + self.internal_user.email = email1 + self.internal_user.save() + + self.request.META = { + settings.SHIB_USER_HEADER: self.internal_user.username, + settings.SHIB_GROUPS_HEADER: self.internal_group.name, + settings.SHIB_ATTRIBUTE_MAP['email']: email2, + } + + # Check email just to be sure + self.assertEqual(email1, self.internal_user.email) + + # Process request + self.middleware.process_request(self.request) + + # Make sure user is authenticated and was authenticated by + # the shibboleth backend and that the internal group is + # attached to the user account + self.assertTrue(self.request.user.is_authenticated) + self.assertEqual(self.request.user.backend, + 'ligoauth.backends.ShibbolethRemoteUserBackend') + + # Make sure email is changed as expected + self.internal_user.refresh_from_db() + self.assertEqual(email2, self.internal_user.email) + + def test_webapi(self): + pass