def test_check_token_invalid_timestamp_disabled_security(self): ''' With disabled timestamp security, invalid timestamps should still succeed. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() past = now - datetime.timedelta(seconds=settings.TIMESTAMP_DURATION + 1) past_token = utils.make_token('user', 'secr3t', nonce, past) future = now + datetime.timedelta(seconds=settings.DRIFT_OFFSET + 1) nonce = utils._random_string() future_token = utils.make_token('user', 'secr3t', nonce, future) with mock.patch.object(settings, 'SECURITY_CHECK_TIMESTAMP', False): try: self.assertEqual( utils.check_token(past_token, lambda x: 'secr3t'), 'user') except exceptions.InvalidTimestamp: self.fail( 'InvalidTimestamp raised with expired timestamp and ' + 'timestamp security disabled.') try: self.assertEqual( utils.check_token(future_token, lambda x: 'secr3t'), 'user') except exceptions.InvalidTimestamp: self.fail( 'InvalidTimestamp raised with expired timestamp and ' + 'timestamp security disabled.')
def test_check_token_invalid_password(self): ''' Check a valid token with an invalid password. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'wrong password', nonce, now) self.assertIsNone(utils.check_token(token, lambda x: 'secr3t'))
def test_check_token(self): ''' Check a token that was just generated. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now) self.assertEqual(utils.check_token(token, lambda x: 'secr3t'), 'user')
def test_check_token_long_nonce(self): ''' Check a token with a long nonce - it should be rejected. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() + 'a' token = utils.make_token('user', 'secr3t', nonce, now) with self.assertRaises(exceptions.InvalidNonce): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_short_nonce(self): ''' Check a token with a short nonce - it should be rejected. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string(length=settings.NONCE_LENGTH - 1) token = utils.make_token('user', 'secr3t', nonce, now) with self.assertRaises(exceptions.InvalidNonce): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_replay_attack(self): ''' Check a token twice - a replay attack should be detected. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now) utils.check_token(token, lambda x: 'secr3t') with self.assertRaises(exceptions.InvalidNonce): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_expired_timestamp(self): ''' Check a token that has an expired timestamp. An error should be raised. ''' ts = (datetime.datetime.utcnow().replace(tzinfo=utc.utc) - datetime.timedelta(seconds=settings.TIMESTAMP_DURATION + 1)) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, ts) with self.assertRaises(exceptions.InvalidTimestamp): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_drift(self): ''' Check a token that has a timestamp with drift. The user should still be authenticated. ''' ts = (datetime.datetime.utcnow().replace(tzinfo=utc.utc) + datetime.timedelta(seconds=settings.DRIFT_OFFSET - 1)) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, ts) self.assertEqual(utils.check_token(token, lambda x: 'secr3t'), 'user')
def test_check_token_nonexistent_user(self): ''' Check a valid token but with a user does not exist. An error should be raised. ''' users = {'username': None} now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now) with self.assertRaises(exceptions.UserException): utils.check_token(token, lambda x: users[x])
def test_check_token_future_timestamp(self): ''' Check a token that has a timestamp in the future. An error should be raised. ''' ts = (datetime.datetime.utcnow().replace(tzinfo=utc.utc) + datetime.timedelta(seconds=settings.DRIFT_OFFSET + 1)) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, ts) with self.assertRaises(exceptions.InvalidTimestamp): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_prohibited_algorithms(self): ''' Check a valid token with prohibited algorithms. An error should be raised. ''' for algorithm in settings.PROHIBITED_DIGEST_ALGORITHMS: now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now, algorithm=algorithm.lower()) with self.assertRaises(exceptions.AlgorithmProhibited): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_invalid_timestamp_format(self): ''' Check a token that has a timestamp in an invalid format. ''' ts = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, ts, ts_format='prefix-{}-suffix'.format( settings.TIMESTAMP_FORMATS[0])) with self.assertRaises(exceptions.InvalidTimestamp): utils.check_token(token, lambda x: 'secr3t')
def test_check_token_alternative_algorithm(self): ''' Check a valid token with an alternative algorithm. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now, algorithm='sha512') with mock.patch.object(settings, 'ALLOWED_DIGEST_ALGORITHMS', ['SHA256', 'SHA512']): self.assertEqual(utils.check_token(token, lambda x: 'secr3t'), 'user')
def test_check_token_alterntive_timestamp_format(self): ''' Check a token that was just generated with a timestamp in a different format. ''' for fmt in settings.TIMESTAMP_FORMATS[1:]: now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now, ts_format=fmt) self.assertEqual(utils.check_token(token, lambda x: 'secr3t'), 'user')
def test_make_token(self): ''' Make a token. It should match the proper parameters. ''' username = '******' password = '******' nonce = 'abcdef' now = datetime.datetime(year=2016, month=9, day=1) expected_token = ', '.join( ('Username="******"', 'PasswordDigest="8p5hLaL4rzZOMdOIcX6VGscduxzAY8uNflY2I415S0Q="', 'Nonce="YWJjZGVm"', 'Created="2016-09-01T00:00:00Z"')) received_token = utils.make_token(username, password, nonce, now) self.assertEqual(expected_token, received_token)
def test_check_token_replay_attack_disabled_security(self): ''' Check a token twice, but with nonce security disabled. A replay attack should not be detected. ''' now = datetime.datetime.utcnow().replace(tzinfo=utc.utc) nonce = utils._random_string() token = utils.make_token('user', 'secr3t', nonce, now) with mock.patch.object(settings, 'SECURITY_CHECK_NONCE', False): self.assertEqual(utils.check_token(token, lambda x: 'secr3t'), 'user') try: self.assertEqual(utils.check_token(token, lambda x: 'secr3t'), 'user') except exceptions.InvalidNonce: self.fail('InvalidNonce raised with nonce security disabled.')