def test_token_generation(self): """ Verify token generation using known hashes and signature """ test_user = self.TEST_USER not_user = self.NOT_USER known_hashhash = ('5106273f7789f1e26b4a212789992f75c15433f402f3e94a' 'd18e7c80aee80faf') with self.app.app_context(): token = generate_token(test_user) # Verify hashhash against known value hashhash = get_hashhash(test_user) self.assertEqual(hashhash, known_hashhash) # Now that we verified our hashhash, independently verify # the data with a serializer from config (not trusting # get_signature here). serializer = Serializer(self.app.config['FLASK_SECRET']) self.assertEqual(serializer.loads(token)['hashhash'], hashhash) # Now go ahead and verify the reverse serializer = get_signature() data = serializer.loads(token) self.assertEqual(data['username'], test_user) self.assertEqual(data['hashhash'], hashhash) # Verify no user handling (don't really care what # exception gets raised). with self.assertRaises(Exception): token = generate_token(not_user)
def test_requires_auth(self): """ Verify full auth with both token and basic auth. """ # Test successful basic auth with self.app.test_request_context(headers={ 'Authorization': 'Basic {0}'.format( base64.b64encode( '{0}:{1}'.format( self.TEST_USER, self.TEST_PASS ).encode('ascii') ).decode('ascii') ) }): wrapped, decorated = TestAuth._get_requires_auth_decorator() decorated() wrapped.assert_called_with(user=self.TEST_USER) # Test successful token header auth with self.app.app_context(): with self.app.test_request_context(headers={ 'Authorization': 'token {0}'.format( generate_token(self.TEST_USER) ) }): wrapped, decorated = TestAuth._get_requires_auth_decorator() decorated() wrapped.assert_called_with(user=self.TEST_USER) # Test successful token param auth with self.app.app_context(): with self.app.test_request_context(): wrapped = mock.Mock() request.args = { 'access_token': generate_token(self.TEST_USER) } wrapped, decorated = TestAuth._get_requires_auth_decorator() decorated() wrapped.assert_called_with(user=self.TEST_USER) # Test unsuccessful auth with self.app.test_request_context(headers={ 'Authorization': 'token blah blah' }): wrapped, decorated = TestAuth._get_requires_auth_decorator() response = decorated() self.assertEqual(401, response.status_code)
def test_token_auth(self, log): """ Validate authentication by token works properly """ with self.app.app_context(): # Test bad token valid, username = check_token_auth('asdfasdf.asdfasdf') self.assertEqual(False, valid) self.assertEqual(None, username) log.warn.assert_called_with('Received bad token signature') # Test bad username, but valid signature for users that have # been deleted sig = get_signature() token = sig.dumps({ 'username': self.NOT_USER, }) valid, username = check_token_auth(token) self.assertEqual(False, valid) self.assertEqual(None, username) log.warn.assert_called_with( 'Token auth signed message, but invalid user %s', self.NOT_USER ) # Test that a different password invalidates token token = sig.dumps({ 'username': self.TEST_USER, 'hashhash': get_hashhash('norm') }) valid, username = check_token_auth(token) self.assertEqual(False, valid) self.assertEqual(None, username) log.warn.assert_called_with( 'Token and password do not match, ' '%s needs to regenerate token', self.TEST_USER ) # Test valid case token = generate_token(self.TEST_USER) valid, username = check_token_auth(token) self.assertEqual(True, valid) self.assertEqual(self.TEST_USER, username)
def token(user): """ Return the user token for API auth that is based off the flask secret and user password """ return jsonify({'token': generate_token(user)})