def test_handle_requests(self, aside_key_class): """ Checks that handler to save tags in StructuredTagsAside works properly """ handler_url = reverse_usage_url( 'component_handler', unicode(aside_key_class(self.problem.location, self.aside_name)), kwargs={'handler': 'save_tags'} ) client = AjaxEnabledTestClient() client.login(username=self.user.username, password=self.user_password) response = client.post(handler_url, json.dumps({}), content_type="application/json") self.assertEqual(response.status_code, 400) response = client.post(handler_url, json.dumps({'undefined_tag': ['undefined1', 'undefined2']}), content_type="application/json") self.assertEqual(response.status_code, 400) response = client.post(handler_url, json.dumps({self.aside_tag_dif: ['undefined1', 'undefined2']}), content_type="application/json") self.assertEqual(response.status_code, 400) def _test_helper_func(problem_location): """ Helper function """ problem = modulestore().get_item(problem_location) asides = problem.runtime.get_asides(problem) tag_aside = None for aside in asides: if isinstance(aside, StructuredTagsAside): tag_aside = aside break return tag_aside response = client.post(handler_url, json.dumps({self.aside_tag_dif: [self.aside_tag_dif_value]}), content_type="application/json") self.assertEqual(response.status_code, 200) tag_aside = _test_helper_func(self.problem.location) self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found") self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], [self.aside_tag_dif_value]) response = client.post(handler_url, json.dumps({self.aside_tag_dif: [self.aside_tag_dif_value, self.aside_tag_dif_value2]}), content_type="application/json") self.assertEqual(response.status_code, 200) tag_aside = _test_helper_func(self.problem.location) self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found") self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], [self.aside_tag_dif_value, self.aside_tag_dif_value2])
def test_handle_requests(self, aside_key_class): """ Checks that handler to save tags in StructuredTagsAside works properly """ handler_url = reverse_usage_url( 'preview_handler', unicode(aside_key_class(self.problem.location, self.aside_name)), kwargs={'handler': 'save_tags'} ) client = AjaxEnabledTestClient() client.login(username=self.user.username, password=self.user_password) response = client.post(handler_url, json.dumps({}), content_type="application/json") self.assertEqual(response.status_code, 400) response = client.post(handler_url, json.dumps({'undefined_tag': ['undefined1', 'undefined2']}), content_type="application/json") self.assertEqual(response.status_code, 400) response = client.post(handler_url, json.dumps({self.aside_tag_dif: ['undefined1', 'undefined2']}), content_type="application/json") self.assertEqual(response.status_code, 400) def _test_helper_func(problem_location): """ Helper function """ problem = modulestore().get_item(problem_location) asides = problem.runtime.get_asides(problem) tag_aside = None for aside in asides: if isinstance(aside, StructuredTagsAside): tag_aside = aside break return tag_aside response = client.post(handler_url, json.dumps({self.aside_tag_dif: [self.aside_tag_dif_value]}), content_type="application/json") self.assertEqual(response.status_code, 200) tag_aside = _test_helper_func(self.problem.location) self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found") self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], [self.aside_tag_dif_value]) response = client.post(handler_url, json.dumps({self.aside_tag_dif: [self.aside_tag_dif_value, self.aside_tag_dif_value2]}), content_type="application/json") self.assertEqual(response.status_code, 200) tag_aside = _test_helper_func(self.problem.location) self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found") self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], [self.aside_tag_dif_value, self.aside_tag_dif_value2])
def test_handle_requests(self): """ Checks that handler to save tags in StructuredTagsAside works properly """ handler_url = reverse_usage_url( 'preview_handler', '%s:%s::%s' % (AsideUsageKeyV1.CANONICAL_NAMESPACE, self.problem.location, self.aside_name), kwargs={'handler': 'save_tags'}) client = AjaxEnabledTestClient() client.login(username=self.user.username, password=self.user_password) response = client.post(path=handler_url, data={}) self.assertEqual(response.status_code, 400) response = client.post(path=handler_url, data={'tag': 'undefined_tag:undefined'}) self.assertEqual(response.status_code, 400) val = '%s:undefined' % self.aside_tag response = client.post(path=handler_url, data={'tag': val}) self.assertEqual(response.status_code, 400) val = '%s:%s' % (self.aside_tag, self.aside_tag_value) response = client.post(path=handler_url, data={'tag': val}) self.assertEqual(response.status_code, 200) problem = modulestore().get_item(self.problem.location) asides = problem.runtime.get_asides(problem) tag_aside = None for aside in asides: if isinstance(aside, StructuredTagsAside): tag_aside = aside break self.assertIsNotNone( tag_aside, "Necessary StructuredTagsAside object isn't found") self.assertEqual(tag_aside.saved_tags[self.aside_tag], self.aside_tag_value)
def test_handle_requests(self): """ Checks that handler to save tags in StructuredTagsAside works properly """ handler_url = reverse_usage_url( 'preview_handler', '%s:%s::%s' % (AsideUsageKeyV1.CANONICAL_NAMESPACE, self.problem.location, self.aside_name), kwargs={'handler': 'save_tags'} ) client = AjaxEnabledTestClient() client.login(username=self.user.username, password=self.user_password) response = client.post(path=handler_url, data={}) self.assertEqual(response.status_code, 400) response = client.post(path=handler_url, data={'tag': 'undefined_tag:undefined'}) self.assertEqual(response.status_code, 400) val = '%s:undefined' % self.aside_tag_dif response = client.post(path=handler_url, data={'tag': val}) self.assertEqual(response.status_code, 400) val = '%s:%s' % (self.aside_tag_dif, self.aside_tag_dif_value) response = client.post(path=handler_url, data={'tag': val}) self.assertEqual(response.status_code, 200) problem = modulestore().get_item(self.problem.location) asides = problem.runtime.get_asides(problem) tag_aside = None for aside in asides: if isinstance(aside, StructuredTagsAside): tag_aside = aside break self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found") self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], self.aside_tag_dif_value)
class AuthTestCase(ContentStoreTestCase): """Check that various permissions-related things work""" def setUp(self): self.email = '*****@*****.**' self.pw = 'xyz' self.username = '******' self.client = AjaxEnabledTestClient() # clear the cache so ratelimiting won't affect these tests cache.clear() def check_page_get(self, url, expected): resp = self.client.get_html(url) self.assertEqual(resp.status_code, expected) return resp def test_public_pages_load(self): """Make sure pages that don't require login load without error.""" pages = ( reverse('login'), reverse('signup'), ) for page in pages: print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): # No post data -- should fail resp = self.client.post('/create_account', {}) self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertEqual(data['success'], False) def test_create_account(self): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) def test_login(self): self.create_account(self.username, self.email, self.pw) # Not activated yet. Login should fail. resp = self._login(self.email, self.pw) data = parse_json(resp) self.assertFalse(data['success']) self.activate_user(self.email) # Now login should work self.login(self.email, self.pw) def test_login_ratelimited(self): # try logging in 30 times, the default limit in the number of failed # login attempts in one 5 minute period before the rate gets limited for i in xrange(30): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn('Too many failed login attempts.', data['value']) def test_login_link_on_activation_age(self): self.create_account(self.username, self.email, self.pw) # we want to test the rendering of the activation page when the user isn't logged in self.client.logout() resp = self._activate_user(self.email) self.assertEqual(resp.status_code, 200) # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">login</a>.' self.assertIn(expected, resp.content) def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ('/course', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ('/course', ) # need an activated user self.test_create_account() # Create a new session self.client = AjaxEnabledTestClient() # Not logged in. Should redirect to login. print('Not logged in') for page in auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) print('Logged in') for page in simple_auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): # not logged in. Should return a redirect. resp = self.client.get_html('/course') self.assertEqual(resp.status_code, 302)
class AuthTestCase(ContentStoreTestCase): """Check that various permissions-related things work""" def setUp(self): self.email = '*****@*****.**' self.pw = 'xyz' self.username = '******' self.client = AjaxEnabledTestClient() # clear the cache so ratelimiting won't affect these tests cache.clear() def check_page_get(self, url, expected): resp = self.client.get_html(url) self.assertEqual(resp.status_code, expected) return resp def test_public_pages_load(self): """Make sure pages that don't require login load without error.""" pages = ( reverse('login'), reverse('signup'), ) for page in pages: print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): # No post data -- should fail resp = self.client.post('/create_account', {}) self.assertEqual(resp.status_code, 400) data = parse_json(resp) self.assertEqual(data['success'], False) def test_create_account(self): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) def test_create_account_username_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account(self.username, "*****@*****.**", "password") # we have a constraint on unique usernames, so this should fail self.assertEqual(resp.status_code, 400) def test_create_account_pw_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account("abcdef", "*****@*****.**", self.pw) # we can have two users with the same password, so this should succeed self.assertEqual(resp.status_code, 200) @unittest.skipUnless(settings.SOUTH_TESTS_MIGRATE, "South migrations required") def test_create_account_email_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account("abcdef", self.email, "password") # This is tricky. Django's user model doesn't have a constraint on # unique email addresses, but we *add* that constraint during the # migration process: # see common/djangoapps/student/migrations/0004_add_email_index.py # # The behavior we *want* is for this account creation request # to fail, due to this uniqueness constraint, but the request will # succeed if the migrations have not run. self.assertEqual(resp.status_code, 400) def test_login(self): self.create_account(self.username, self.email, self.pw) # Not activated yet. Login should fail. resp = self._login(self.email, self.pw) data = parse_json(resp) self.assertFalse(data['success']) self.activate_user(self.email) # Now login should work self.login(self.email, self.pw) def test_login_ratelimited(self): # try logging in 30 times, the default limit in the number of failed # login attempts in one 5 minute period before the rate gets limited for i in xrange(30): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn('Too many failed login attempts.', data['value']) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED=3) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS=2) def test_excessive_login_failures(self): # try logging in 3 times, the account should get locked for 3 seconds # note we want to keep the lockout time short, so we don't slow down the tests with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True}): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) for i in xrange(3): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn('Email or password is incorrect.', data['value']) # now the account should be locked resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn( 'This account has been temporarily locked due to excessive login failures. Try again later.', data['value']) with freeze_time('2100-01-01'): self.login(self.email, self.pw) # make sure the failed attempt counter gets reset on successful login resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) # account should not be locked out after just one attempt self.login(self.email, self.pw) # do one more login when there is no bad login counter row at all in the database to # test the "ObjectNotFound" case self.login(self.email, self.pw) def test_login_link_on_activation_age(self): self.create_account(self.username, self.email, self.pw) # we want to test the rendering of the activation page when the user isn't logged in self.client.logout() resp = self._activate_user(self.email) self.assertEqual(resp.status_code, 200) # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">login</a>.' self.assertIn(expected, resp.content) def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ('/course/', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ('/course/', ) # need an activated user self.test_create_account() # Create a new session self.client = AjaxEnabledTestClient() # Not logged in. Should redirect to login. print('Not logged in') for page in auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) print('Logged in') for page in simple_auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): # not logged in. Should return a redirect. resp = self.client.get_html('/course/') self.assertEqual(resp.status_code, 302) # Logged in should work. @override_settings(SESSION_INACTIVITY_TIMEOUT_IN_SECONDS=1) def test_inactive_session_timeout(self): """ Verify that an inactive session times out and redirects to the login page """ self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) self.login(self.email, self.pw) # make sure we can access courseware immediately course_url = '/course/' resp = self.client.get_html(course_url) self.assertEquals(resp.status_code, 200) # then wait a bit and see if we get timed out time.sleep(2) resp = self.client.get_html(course_url) # re-request, and we should get a redirect to login page self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=/course/')
class AuthTestCase(ContentStoreTestCase): """Check that various permissions-related things work""" CREATE_USER = False ENABLED_CACHES = ['default', 'mongo_metadata_inheritance', 'loc_cache'] def setUp(self): super(AuthTestCase, self).setUp() self.email = '*****@*****.**' self.pw = 'xyz' self.username = '******' self.client = AjaxEnabledTestClient() # clear the cache so ratelimiting won't affect these tests cache.clear() def check_page_get(self, url, expected): resp = self.client.get_html(url) self.assertEqual(resp.status_code, expected) return resp def test_public_pages_load(self): """Make sure pages that don't require login load without error.""" pages = ( reverse('login'), reverse('signup'), ) for page in pages: print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): # No post data -- should fail registration_url = reverse('user_api_registration') resp = self.client.post(registration_url, {}) self.assertEqual(resp.status_code, 400) def test_create_account(self): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) def test_create_account_username_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account(self.username, "*****@*****.**", "password") # we have a constraint on unique usernames, so this should fail self.assertEqual(resp.status_code, 409) def test_create_account_pw_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account("abcdef", "*****@*****.**", self.pw) # we can have two users with the same password, so this should succeed self.assertEqual(resp.status_code, 200) def test_login(self): self.create_account(self.username, self.email, self.pw) # Not activated yet. Login should fail. resp = self._login(self.email, self.pw) self.activate_user(self.email) # Now login should work self.login(self.email, self.pw) def test_login_ratelimited(self): # try logging in 30 times, the default limit in the number of failed # login attempts in one 5 minute period before the rate gets limited for i in xrange(30): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 403) resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 403) self.assertIn('Too many failed login attempts.', resp.content) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED=3) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS=2) def test_excessive_login_failures(self): # try logging in 3 times, the account should get locked for 3 seconds # note we want to keep the lockout time short, so we don't slow down the tests with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True}): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) for i in xrange(3): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 403) self.assertIn( 'Email or password is incorrect.', resp.content ) # now the account should be locked resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 403) self.assertIn( 'This account has been temporarily locked due to excessive login failures.', resp.content ) with freeze_time('2100-01-01'): self.login(self.email, self.pw) # make sure the failed attempt counter gets reset on successful login resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 403) self.assertIn( 'Email or password is incorrect.', resp.content ) # account should not be locked out after just one attempt self.login(self.email, self.pw) # do one more login when there is no bad login counter row at all in the database to # test the "ObjectNotFound" case self.login(self.email, self.pw) def test_login_link_on_activation_age(self): self.create_account(self.username, self.email, self.pw) # we want to test the rendering of the activation page when the user isn't logged in self.client.logout() resp = self._activate_user(self.email) self.assertEqual(resp.status_code, 200) # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">sign in</a>.' self.assertIn(expected, resp.content.decode('utf-8')) def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ( '/home/', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ( '/home/', ) # need an activated user self.test_create_account() # Create a new session self.client = AjaxEnabledTestClient() # Not logged in. Should redirect to login. print('Not logged in') for page in auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) print('Logged in') for page in simple_auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): # not logged in. Should return a redirect. resp = self.client.get_html('/home/') self.assertEqual(resp.status_code, 302) # Logged in should work. @override_settings(SESSION_INACTIVITY_TIMEOUT_IN_SECONDS=1) def test_inactive_session_timeout(self): """ Verify that an inactive session times out and redirects to the login page """ self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) self.login(self.email, self.pw) # make sure we can access courseware immediately course_url = '/home/' resp = self.client.get_html(course_url) self.assertEquals(resp.status_code, 200) # then wait a bit and see if we get timed out time.sleep(2) resp = self.client.get_html(course_url) # re-request, and we should get a redirect to login page self.assertRedirects(resp, settings.LOGIN_URL + '?next=/home/') @mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": False}) def test_signup_button_index_page(self): """ Navigate to the home page and check the Sign Up button is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag is turned off """ response = self.client.get(reverse('homepage')) self.assertNotIn('<a class="action action-signup" href="/signup">Sign Up</a>', response.content) @mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": False}) def test_signup_button_login_page(self): """ Navigate to the login page and check the Sign Up button is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag is turned off """ response = self.client.get(reverse('login')) self.assertNotIn('<a class="action action-signup" href="/signup">Sign Up</a>', response.content) @mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": False}) def test_signup_link_login_page(self): """ Navigate to the login page and check the Sign Up link is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag is turned off """ response = self.client.get(reverse('login')) self.assertNotIn('<a href="/signup" class="action action-signin">Don't have a Studio Account? Sign up!</a>', response.content)
class AuthTestCase(ContentStoreTestCase): """Check that various permissions-related things work""" def setUp(self): self.email = '*****@*****.**' self.pw = 'xyz' self.username = '******' self.client = AjaxEnabledTestClient() # clear the cache so ratelimiting won't affect these tests cache.clear() def check_page_get(self, url, expected): resp = self.client.get_html(url) self.assertEqual(resp.status_code, expected) return resp def test_public_pages_load(self): """Make sure pages that don't require login load without error.""" pages = ( reverse('login'), reverse('signup'), ) for page in pages: print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): # No post data -- should fail resp = self.client.post('/create_account', {}) self.assertEqual(resp.status_code, 400) data = parse_json(resp) self.assertEqual(data['success'], False) def test_create_account(self): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) def test_create_account_username_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account(self.username, "*****@*****.**", "password") # we have a constraint on unique usernames, so this should fail self.assertEqual(resp.status_code, 400) def test_create_account_pw_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account("abcdef", "*****@*****.**", self.pw) # we can have two users with the same password, so this should succeed self.assertEqual(resp.status_code, 200) @unittest.skipUnless(settings.SOUTH_TESTS_MIGRATE, "South migrations required") def test_create_account_email_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account("abcdef", self.email, "password") # This is tricky. Django's user model doesn't have a constraint on # unique email addresses, but we *add* that constraint during the # migration process: # see common/djangoapps/student/migrations/0004_add_email_index.py # # The behavior we *want* is for this account creation request # to fail, due to this uniqueness constraint, but the request will # succeed if the migrations have not run. self.assertEqual(resp.status_code, 400) def test_login(self): self.create_account(self.username, self.email, self.pw) # Not activated yet. Login should fail. resp = self._login(self.email, self.pw) data = parse_json(resp) self.assertFalse(data['success']) self.activate_user(self.email) # Now login should work self.login(self.email, self.pw) def test_login_ratelimited(self): # try logging in 30 times, the default limit in the number of failed # login attempts in one 5 minute period before the rate gets limited for i in xrange(30): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn('Too many failed login attempts.', data['value']) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED=3) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS=2) def test_excessive_login_failures(self): # try logging in 3 times, the account should get locked for 3 seconds # note we want to keep the lockout time short, so we don't slow down the tests with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True}): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) for i in xrange(3): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn( 'Email or password is incorrect.', data['value'] ) # now the account should be locked resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn( 'This account has been temporarily locked due to excessive login failures. Try again later.', data['value'] ) with freeze_time('2100-01-01'): self.login(self.email, self.pw) # make sure the failed attempt counter gets reset on successful login resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) # account should not be locked out after just one attempt self.login(self.email, self.pw) # do one more login when there is no bad login counter row at all in the database to # test the "ObjectNotFound" case self.login(self.email, self.pw) def test_login_link_on_activation_age(self): self.create_account(self.username, self.email, self.pw) # we want to test the rendering of the activation page when the user isn't logged in self.client.logout() resp = self._activate_user(self.email) self.assertEqual(resp.status_code, 200) # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">login</a>.' self.assertIn(expected, resp.content) def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ( '/course/', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ( '/course/', ) # need an activated user self.test_create_account() # Create a new session self.client = AjaxEnabledTestClient() # Not logged in. Should redirect to login. print('Not logged in') for page in auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) print('Logged in') for page in simple_auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): # not logged in. Should return a redirect. resp = self.client.get_html('/course/') self.assertEqual(resp.status_code, 302) # Logged in should work. @override_settings(SESSION_INACTIVITY_TIMEOUT_IN_SECONDS=1) def test_inactive_session_timeout(self): """ Verify that an inactive session times out and redirects to the login page """ self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) self.login(self.email, self.pw) # make sure we can access courseware immediately course_url = '/course/' resp = self.client.get_html(course_url) self.assertEquals(resp.status_code, 200) # then wait a bit and see if we get timed out time.sleep(2) resp = self.client.get_html(course_url) # re-request, and we should get a redirect to login page self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=/course/')
class AuthTestCase(ContentStoreTestCase): """Check that various permissions-related things work""" CREATE_USER = False ENABLED_CACHES = ['default', 'mongo_metadata_inheritance', 'loc_cache'] def setUp(self): super(AuthTestCase, self).setUp() self.email = '*****@*****.**' self.pw = 'xyz' self.username = '******' self.client = AjaxEnabledTestClient() # clear the cache so ratelimiting won't affect these tests cache.clear() def check_page_get(self, url, expected): resp = self.client.get_html(url) self.assertEqual(resp.status_code, expected) return resp def test_public_pages_load(self): """Make sure pages that don't require login load without error.""" pages = ( reverse('login'), reverse('signup'), ) for page in pages: print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): # No post data -- should fail resp = self.client.post('/create_account', {}) self.assertEqual(resp.status_code, 400) data = parse_json(resp) self.assertEqual(data['success'], False) def test_create_account(self): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) def test_create_account_username_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account(self.username, "*****@*****.**", "password") # we have a constraint on unique usernames, so this should fail self.assertEqual(resp.status_code, 400) def test_create_account_pw_already_exists(self): User.objects.create_user(self.username, self.email, self.pw) resp = self._create_account("abcdef", "*****@*****.**", self.pw) # we can have two users with the same password, so this should succeed self.assertEqual(resp.status_code, 200) def test_login(self): self.create_account(self.username, self.email, self.pw) # Not activated yet. Login should fail. resp = self._login(self.email, self.pw) data = parse_json(resp) self.assertFalse(data['success']) self.activate_user(self.email) # Now login should work self.login(self.email, self.pw) def test_login_ratelimited(self): # try logging in 30 times, the default limit in the number of failed # login attempts in one 5 minute period before the rate gets limited for i in xrange(30): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn('Too many failed login attempts.', data['value']) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED=3) @override_settings(MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS=2) def test_excessive_login_failures(self): # try logging in 3 times, the account should get locked for 3 seconds # note we want to keep the lockout time short, so we don't slow down the tests with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True}): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) for i in xrange(3): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn( 'Email or password is incorrect.', data['value'] ) # now the account should be locked resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn( 'This account has been temporarily locked due to excessive login failures.', data['value'] ) with freeze_time('2100-01-01'): self.login(self.email, self.pw) # make sure the failed attempt counter gets reset on successful login resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) # account should not be locked out after just one attempt self.login(self.email, self.pw) # do one more login when there is no bad login counter row at all in the database to # test the "ObjectNotFound" case self.login(self.email, self.pw) def test_login_link_on_activation_age(self): self.create_account(self.username, self.email, self.pw) # we want to test the rendering of the activation page when the user isn't logged in self.client.logout() resp = self._activate_user(self.email) self.assertEqual(resp.status_code, 200) # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">sign in</a>.' self.assertIn(expected, resp.content.decode('utf-8')) def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ( '/home/', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ( '/home/', ) # need an activated user self.test_create_account() # Create a new session self.client = AjaxEnabledTestClient() # Not logged in. Should redirect to login. print('Not logged in') for page in auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) print('Logged in') for page in simple_auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): # not logged in. Should return a redirect. resp = self.client.get_html('/home/') self.assertEqual(resp.status_code, 302) # Logged in should work. @override_settings(SESSION_INACTIVITY_TIMEOUT_IN_SECONDS=1) def test_inactive_session_timeout(self): """ Verify that an inactive session times out and redirects to the login page """ self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) self.login(self.email, self.pw) # make sure we can access courseware immediately course_url = '/home/' resp = self.client.get_html(course_url) self.assertEquals(resp.status_code, 200) # then wait a bit and see if we get timed out time.sleep(2) resp = self.client.get_html(course_url) # re-request, and we should get a redirect to login page self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=/home/') @mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": False}) def test_signup_button_index_page(self): """ Navigate to the home page and check the Sign Up button is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag is turned off """ response = self.client.get(reverse('homepage')) self.assertNotIn('<a class="action action-signup" href="/signup">Sign Up</a>', response.content) @mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": False}) def test_signup_button_login_page(self): """ Navigate to the login page and check the Sign Up button is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag is turned off """ response = self.client.get(reverse('login')) self.assertNotIn('<a class="action action-signup" href="/signup">Sign Up</a>', response.content) @mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": False}) def test_signup_link_login_page(self): """ Navigate to the login page and check the Sign Up link is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag is turned off """ response = self.client.get(reverse('login')) self.assertNotIn('<a href="/signup" class="action action-signin">Don't have a Studio Account? Sign up!</a>', response.content)
class AuthTestCase(ContentStoreTestCase): """Check that various permissions-related things work""" def setUp(self): self.email = '*****@*****.**' self.pw = 'xyz' self.username = '******' self.client = AjaxEnabledTestClient() # clear the cache so ratelimiting won't affect these tests cache.clear() def check_page_get(self, url, expected): resp = self.client.get_html(url) self.assertEqual(resp.status_code, expected) return resp def test_public_pages_load(self): """Make sure pages that don't require login load without error.""" pages = ( reverse('login'), reverse('signup'), ) for page in pages: print("Checking '{0}'".format(page)) self.check_page_get(page, 200) def test_create_account_errors(self): # No post data -- should fail resp = self.client.post('/create_account', {}) self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertEqual(data['success'], False) def test_create_account(self): self.create_account(self.username, self.email, self.pw) self.activate_user(self.email) def test_login(self): self.create_account(self.username, self.email, self.pw) # Not activated yet. Login should fail. resp = self._login(self.email, self.pw) data = parse_json(resp) self.assertFalse(data['success']) self.activate_user(self.email) # Now login should work self.login(self.email, self.pw) def test_login_ratelimited(self): # try logging in 30 times, the default limit in the number of failed # login attempts in one 5 minute period before the rate gets limited for i in xrange(30): resp = self._login(self.email, 'wrong_password{0}'.format(i)) self.assertEqual(resp.status_code, 200) resp = self._login(self.email, 'wrong_password') self.assertEqual(resp.status_code, 200) data = parse_json(resp) self.assertFalse(data['success']) self.assertIn('Too many failed login attempts.', data['value']) def test_login_link_on_activation_age(self): self.create_account(self.username, self.email, self.pw) # we want to test the rendering of the activation page when the user isn't logged in self.client.logout() resp = self._activate_user(self.email) self.assertEqual(resp.status_code, 200) # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">login</a>.' self.assertIn(expected, resp.content) def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ( '/course', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ( '/course', ) # need an activated user self.test_create_account() # Create a new session self.client = AjaxEnabledTestClient() # Not logged in. Should redirect to login. print('Not logged in') for page in auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=302) # Logged in should work. self.login(self.email, self.pw) print('Logged in') for page in simple_auth_pages: print("Checking '{0}'".format(page)) self.check_page_get(page, expected=200) def test_index_auth(self): # not logged in. Should return a redirect. resp = self.client.get_html('/course') self.assertEqual(resp.status_code, 302)