def get(cls, value): # DB does not contain key but the key_hash. value_hash = hash_utils.hash(value) for model_object in ApiKeyDB.objects(key_hash=value_hash): return model_object raise ApiKeyNotFoundError('ApiKey with key_hash=%s not found.' % value_hash)
class TestApiKeyBasedAuth(FunctionalTest): enable_auth = True apikey1 = None apikey_disabled = None @classmethod def setUpClass(cls): super(TestApiKeyBasedAuth, cls).setUpClass() models = FixturesLoader().save_fixtures_to_db(fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_MODELS) cls.apikey1 = models['apikeys']['apikey1.yaml'] cls.apikey_disabled = models['apikeys']['apikey_disabled.yaml'] @mock.patch.object(User, 'get_by_name', mock.Mock(return_value=UserDB(name='bill'))) def test_apikey_validation_apikey_in_headers(self): response = self.app.get('/v1/actions', headers={'St2-Api-key': KEY1_KEY}, expect_errors=False) self.assertTrue('application/json' in response.headers['content-type']) self.assertEqual(response.status_int, 200) @mock.patch.object(User, 'get_by_name', mock.Mock(return_value=UserDB(name='bill'))) def test_apikey_validation_apikey_in_query_params(self): response = self.app.get('/v1/actions?st2-api-key=%s' % (KEY1_KEY), expect_errors=False) self.assertTrue('application/json' in response.headers['content-type']) self.assertEqual(response.status_int, 200) def test_apikey_disabled(self): response = self.app.get('/v1/actions', headers={'St2-Api-key': DISABLED_KEY}, expect_errors=True) self.assertTrue('application/json' in response.headers['content-type']) self.assertEqual(response.status_int, 401) self.assertEqual(response.json_body['faultstring'], 'Unauthorized - API key is disabled.') def test_apikey_not_found(self): response = self.app.get('/v1/actions', headers={'St2-Api-key': 'UNKNOWN'}, expect_errors=True) self.assertTrue('application/json' in response.headers['content-type']) self.assertEqual(response.status_int, 401) self.assertRegexpMatches(response.json_body['faultstring'], '^Unauthorized - ApiKey with key_hash=([a-zA-Z0-9]+) not found.$') @mock.patch.object( Token, 'get', mock.Mock(return_value=TokenDB(id=OBJ_ID, user=USER, token=TOKEN, expiry=FUTURE))) @mock.patch.object( ApiKey, 'get', mock.Mock(return_value=ApiKeyDB(user=USER, key_hash=KEY1_KEY, enabled=True))) @mock.patch.object(User, 'get_by_name', mock.Mock(return_value=USER_DB)) def test_multiple_auth_sources(self): response = self.app.get('/v1/actions', headers={'X-Auth-Token': TOKEN, 'St2-Api-key': KEY1_KEY}, expect_errors=True) self.assertTrue('application/json' in response.headers['content-type']) self.assertEqual(response.status_int, 401) self.assertEqual(response.json_body['faultstring'], 'Unauthorized - Only one of Token or API key expected.')
USR_TOKEN = TokenDB(id=bson.ObjectId(), user="******", token=uuid.uuid4().hex, expiry=EXPIRY) FIXTURES_PACK = "generic" FIXTURES = {"users": ["system_user.yaml", "token_user.yaml"]} # These parameters are used for the tests of getting value from datastore and decrypting it at # Jinja expression in a action metadata definition. TEST_USER = UserDB(name="user1") TEST_TOKEN = TokenDB(id=bson.ObjectId(), user=TEST_USER, token=uuid.uuid4().hex, expiry=EXPIRY) TEST_APIKEY = ApiKeyDB(user=TEST_USER, key_hash="secret_key", enabled=True) def mock_get_token(*args, **kwargs): if args[0] == SYS_TOKEN.token: return SYS_TOKEN return USR_TOKEN @mock.patch.object(PoolPublisher, "publish", mock.MagicMock()) class ActionExecutionControllerTestCaseAuthEnabled(FunctionalTest): enable_auth = True @classmethod @mock.patch.object(Token, "get",
class TestApiKeyBasedAuth(FunctionalTest): enable_auth = True apikey1 = None apikey_disabled = None @classmethod def setUpClass(cls): super(TestApiKeyBasedAuth, cls).setUpClass() models = FixturesLoader().save_fixtures_to_db( fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_MODELS ) cls.apikey1 = models["apikeys"]["apikey1.yaml"] cls.apikey_disabled = models["apikeys"]["apikey_disabled.yaml"] @mock.patch.object(User, "get_by_name", mock.Mock(return_value=UserDB(name="bill"))) def test_apikey_validation_apikey_in_headers(self): response = self.app.get( "/v1/actions", headers={"St2-Api-key": KEY1_KEY}, expect_errors=False ) self.assertIn("application/json", response.headers["content-type"]) self.assertEqual(response.status_int, 200) @mock.patch.object(User, "get_by_name", mock.Mock(return_value=UserDB(name="bill"))) def test_apikey_validation_apikey_in_query_params(self): response = self.app.get( "/v1/actions?st2-api-key=%s" % (KEY1_KEY), expect_errors=False ) self.assertIn("application/json", response.headers["content-type"]) self.assertEqual(response.status_int, 200) @mock.patch.object(User, "get_by_name", mock.Mock(return_value=UserDB(name="bill"))) def test_apikey_validation_apikey_in_cookies(self): response = self.app.get( "/v1/actions", headers={"St2-Api-key": KEY1_KEY}, expect_errors=False ) self.assertIn("application/json", response.headers["content-type"]) self.assertEqual(response.status_int, 200) with mock.patch.object(self.app.cookiejar, "clear", return_value=None): response = self.app.get("/v1/actions", expect_errors=True) self.assertEqual(response.status_int, 401) self.assertEqual( response.json_body["faultstring"], "Unauthorized - One of Token or API key required.", ) def test_apikey_disabled(self): response = self.app.get( "/v1/actions", headers={"St2-Api-key": DISABLED_KEY}, expect_errors=True ) self.assertIn("application/json", response.headers["content-type"]) self.assertEqual(response.status_int, 401) self.assertEqual( response.json_body["faultstring"], "Unauthorized - API key is disabled." ) def test_apikey_not_found(self): response = self.app.get( "/v1/actions", headers={"St2-Api-key": "UNKNOWN"}, expect_errors=True ) self.assertIn("application/json", response.headers["content-type"]) self.assertEqual(response.status_int, 401) self.assertRegexpMatches( response.json_body["faultstring"], "^Unauthorized - ApiKey with key_hash=([a-zA-Z0-9]+) not found.$", ) @mock.patch.object( Token, "get", mock.Mock( return_value=TokenDB(id=OBJ_ID, user=USER, token=TOKEN, expiry=FUTURE) ), ) @mock.patch.object( ApiKey, "get", mock.Mock(return_value=ApiKeyDB(user=USER, key_hash=KEY1_KEY, enabled=True)), ) @mock.patch.object(User, "get_by_name", mock.Mock(return_value=USER_DB)) def test_multiple_auth_sources(self): response = self.app.get( "/v1/actions", headers={"X-Auth-Token": TOKEN, "St2-Api-key": KEY1_KEY}, expect_errors=True, ) self.assertIn("application/json", response.headers["content-type"]) self.assertEqual(response.status_int, 200)
def test_get_uid(self): pack_db = PackDB(ref='ma_pack') self.assertEqual(pack_db.get_uid(), 'pack:ma_pack') self.assertTrue(pack_db.has_valid_uid()) sensor_type_db = SensorTypeDB(name='sname', pack='spack') self.assertEqual(sensor_type_db.get_uid(), 'sensor_type:spack:sname') self.assertTrue(sensor_type_db.has_valid_uid()) action_db = ActionDB(name='aname', pack='apack', runner_type={}) self.assertEqual(action_db.get_uid(), 'action:apack:aname') self.assertTrue(action_db.has_valid_uid()) rule_db = RuleDB(name='rname', pack='rpack') self.assertEqual(rule_db.get_uid(), 'rule:rpack:rname') self.assertTrue(rule_db.has_valid_uid()) trigger_type_db = TriggerTypeDB(name='ttname', pack='ttpack') self.assertEqual(trigger_type_db.get_uid(), 'trigger_type:ttpack:ttname') self.assertTrue(trigger_type_db.has_valid_uid()) trigger_db = TriggerDB(name='tname', pack='tpack') self.assertTrue(trigger_db.get_uid().startswith('trigger:tpack:tname:')) # Verify that same set of parameters always results in the same hash parameters = {'a': 1, 'b': 'unicode', 'c': [1, 2, 3], 'd': {'g': 1, 'h': 2}} paramers_hash = json.dumps(parameters, sort_keys=True) paramers_hash = hashlib.md5(paramers_hash.encode()).hexdigest() parameters = {'a': 1, 'b': 'unicode', 'c': [1, 2, 3], 'd': {'g': 1, 'h': 2}} trigger_db = TriggerDB(name='tname', pack='tpack', parameters=parameters) self.assertEqual(trigger_db.get_uid(), 'trigger:tpack:tname:%s' % (paramers_hash)) self.assertTrue(trigger_db.has_valid_uid()) parameters = {'c': [1, 2, 3], 'b': u'unicode', 'd': {'h': 2, 'g': 1}, 'a': 1} trigger_db = TriggerDB(name='tname', pack='tpack', parameters=parameters) self.assertEqual(trigger_db.get_uid(), 'trigger:tpack:tname:%s' % (paramers_hash)) self.assertTrue(trigger_db.has_valid_uid()) parameters = {'b': u'unicode', 'c': [1, 2, 3], 'd': {'h': 2, 'g': 1}, 'a': 1} trigger_db = TriggerDB(name='tname', pack='tpack', parameters=parameters) self.assertEqual(trigger_db.get_uid(), 'trigger:tpack:tname:%s' % (paramers_hash)) self.assertTrue(trigger_db.has_valid_uid()) parameters = OrderedDict({'c': [1, 2, 3], 'b': u'unicode', 'd': {'h': 2, 'g': 1}, 'a': 1}) trigger_db = TriggerDB(name='tname', pack='tpack', parameters=parameters) self.assertEqual(trigger_db.get_uid(), 'trigger:tpack:tname:%s' % (paramers_hash)) self.assertTrue(trigger_db.has_valid_uid()) policy_type_db = PolicyTypeDB(resource_type='action', name='concurrency') self.assertEqual(policy_type_db.get_uid(), 'policy_type:action:concurrency') self.assertTrue(policy_type_db.has_valid_uid()) policy_db = PolicyDB(pack='dummy', name='policy1') self.assertEqual(policy_db.get_uid(), 'policy:dummy:policy1') api_key_db = ApiKeyDB(key_hash='valid') self.assertEqual(api_key_db.get_uid(), 'api_key:valid') self.assertTrue(api_key_db.has_valid_uid()) api_key_db = ApiKeyDB() self.assertEqual(api_key_db.get_uid(), 'api_key:') self.assertFalse(api_key_db.has_valid_uid())
class TestTokenController(FunctionalTest): @classmethod def setUpClass(cls, **kwargs): kwargs['extra_environ'] = { 'REMOTE_USER': USERNAME } super(TestTokenController, cls).setUpClass(**kwargs) def test_token_model(self): dt = date_utils.get_datetime_utc_now() tk1 = TokenAPI(user='******', token=uuid.uuid4().hex, expiry=isotime.format(dt, offset=False)) tkdb1 = TokenAPI.to_model(tk1) self.assertIsNotNone(tkdb1) self.assertIsInstance(tkdb1, TokenDB) self.assertEqual(tkdb1.user, tk1.user) self.assertEqual(tkdb1.token, tk1.token) self.assertEqual(tkdb1.expiry, isotime.parse(tk1.expiry)) tkdb2 = Token.add_or_update(tkdb1) self.assertEqual(tkdb1, tkdb2) self.assertIsNotNone(tkdb2.id) tk2 = TokenAPI.from_model(tkdb2) self.assertEqual(tk2.user, tk1.user) self.assertEqual(tk2.token, tk1.token) self.assertEqual(tk2.expiry, tk1.expiry) def test_token_model_null_token(self): dt = date_utils.get_datetime_utc_now() tk = TokenAPI(user='******', token=None, expiry=isotime.format(dt)) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def test_token_model_null_user(self): dt = date_utils.get_datetime_utc_now() tk = TokenAPI(user=None, token=uuid.uuid4().hex, expiry=isotime.format(dt)) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def test_token_model_null_expiry(self): tk = TokenAPI(user='******', token=uuid.uuid4().hex, expiry=None) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def _test_token_post(self, path=TOKEN_V1_PATH): ttl = cfg.CONF.auth.token_ttl timestamp = date_utils.get_datetime_utc_now() response = self.app.post_json(path, {}, expect_errors=False) expected_expiry = date_utils.get_datetime_utc_now() + datetime.timedelta(seconds=ttl) expected_expiry = date_utils.add_utc_tz(expected_expiry) self.assertEqual(response.status_int, 201) self.assertIsNotNone(response.json['token']) self.assertEqual(response.json['user'], USERNAME) actual_expiry = isotime.parse(response.json['expiry']) self.assertLess(timestamp, actual_expiry) self.assertLess(actual_expiry, expected_expiry) return response def test_token_post_unauthorized(self): response = self.app.post_json(TOKEN_V1_PATH, {}, expect_errors=True, extra_environ={ 'REMOTE_USER': '' }) self.assertEqual(response.status_int, 401) @mock.patch.object( User, 'get_by_name', mock.MagicMock(side_effect=Exception())) @mock.patch.object( User, 'add_or_update', mock.Mock(return_value=UserDB(name=USERNAME))) def test_token_post_new_user(self): self._test_token_post() @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_existing_user(self): self._test_token_post() @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_success_x_api_url_header_value(self): # auth.api_url option is explicitly set cfg.CONF.set_override('api_url', override='https://example.com', group='auth') resp = self._test_token_post() self.assertEqual(resp.headers['X-API-URL'], 'https://example.com') # auth.api_url option is not set, url is inferred from listen host and port cfg.CONF.set_override('api_url', override=None, group='auth') resp = self._test_token_post() self.assertEqual(resp.headers['X-API-URL'], 'http://127.0.0.1:9101') @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_default_url_path(self): self._test_token_post(path=TOKEN_DEFAULT_PATH) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_ttl(self): timestamp = date_utils.add_utc_tz(date_utils.get_datetime_utc_now()) response = self.app.post_json(TOKEN_V1_PATH, {'ttl': 60}, expect_errors=False) expected_expiry = date_utils.get_datetime_utc_now() + datetime.timedelta(seconds=60) self.assertEqual(response.status_int, 201) actual_expiry = isotime.parse(response.json['expiry']) self.assertLess(timestamp, actual_expiry) self.assertLess(actual_expiry, expected_expiry) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_no_data_in_body_text_plain_context_type_used(self): response = self.app.post(TOKEN_V1_PATH, expect_errors=False, content_type='text/plain') self.assertEqual(response.status_int, 201) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_ttl_over_policy(self): ttl = cfg.CONF.auth.token_ttl response = self.app.post_json(TOKEN_V1_PATH, {'ttl': ttl + 60}, expect_errors=True) self.assertEqual(response.status_int, 400) message = 'TTL specified %s is greater than max allowed %s.' % ( ttl + 60, ttl ) self.assertEqual(response.json['faultstring'], message) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_bad_ttl(self): response = self.app.post_json(TOKEN_V1_PATH, {'ttl': -1}, expect_errors=True) self.assertEqual(response.status_int, 400) response = self.app.post_json(TOKEN_V1_PATH, {'ttl': 0}, expect_errors=True) self.assertEqual(response.status_int, 400) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because an API key or token is not provided in header. data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized_bad_api_key(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because the API key is bad. headers = {'St2-Api-Key': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized_bad_token(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because the token is bad. headers = {'X-Auth-Token': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) @mock.patch.object( ApiKey, 'get', mock.MagicMock(return_value=ApiKeyDB(user=USERNAME, key_hash='foobar'))) def test_token_get_auth_with_api_key(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. Use an API key to authenticate with the st2 auth get token endpoint. headers = {'St2-Api-Key': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 200) self.assertTrue(response.json['valid']) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_auth_with_token(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, {}, expect_errors=False) # Verify the token. Use a token to authenticate with the st2 auth get token endpoint. headers = {'X-Auth-Token': str(response.json['token'])} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 200) self.assertTrue(response.json['valid']) @mock.patch.object( User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) @mock.patch.object( ApiKey, 'get', mock.MagicMock(return_value=ApiKeyDB(user=USERNAME, key_hash='foobar'))) @mock.patch.object( Token, 'get', mock.MagicMock( return_value=TokenDB( user=USERNAME, token='12345', expiry=date_utils.get_datetime_utc_now() - datetime.timedelta(minutes=1)))) def test_token_get_unauthorized_bad_ttl(self): # Verify the token. 400 is expected because the token has expired. headers = {'St2-Api-Key': 'foobar'} data = {'token': '12345'} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=False) self.assertEqual(response.status_int, 200) self.assertFalse(response.json['valid'])
class TestTokenController(FunctionalTest): def setUp(self): super(TestTokenController, self).setUp() type(pecan.request).remote_user = mock.PropertyMock( return_value=USERNAME) def test_token_model(self): dt = date_utils.get_datetime_utc_now() tk1 = TokenAPI(user='******', token=uuid.uuid4().hex, expiry=isotime.format(dt, offset=False)) tkdb1 = TokenAPI.to_model(tk1) self.assertIsNotNone(tkdb1) self.assertIsInstance(tkdb1, TokenDB) self.assertEqual(tkdb1.user, tk1.user) self.assertEqual(tkdb1.token, tk1.token) self.assertEqual(tkdb1.expiry, isotime.parse(tk1.expiry)) tkdb2 = Token.add_or_update(tkdb1) self.assertEqual(tkdb1, tkdb2) self.assertIsNotNone(tkdb2.id) tk2 = TokenAPI.from_model(tkdb2) self.assertEqual(tk2.user, tk1.user) self.assertEqual(tk2.token, tk1.token) self.assertEqual(tk2.expiry, tk1.expiry) def test_token_model_null_token(self): dt = date_utils.get_datetime_utc_now() tk = TokenAPI(user='******', token=None, expiry=isotime.format(dt)) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def test_token_model_null_user(self): dt = date_utils.get_datetime_utc_now() tk = TokenAPI(user=None, token=uuid.uuid4().hex, expiry=isotime.format(dt)) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def test_token_model_null_expiry(self): tk = TokenAPI(user='******', token=uuid.uuid4().hex, expiry=None) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def _test_token_post(self, path=TOKEN_V1_PATH): ttl = cfg.CONF.auth.token_ttl timestamp = date_utils.get_datetime_utc_now() response = self.app.post_json(path, {}, expect_errors=False) expected_expiry = date_utils.get_datetime_utc_now( ) + datetime.timedelta(seconds=ttl) expected_expiry = date_utils.add_utc_tz(expected_expiry) self.assertEqual(response.status_int, 201) self.assertIsNotNone(response.json['token']) self.assertEqual(response.json['user'], USERNAME) actual_expiry = isotime.parse(response.json['expiry']) self.assertLess(timestamp, actual_expiry) self.assertLess(actual_expiry, expected_expiry) def test_token_post_unauthorized(self): type(pecan.request).remote_user = None response = self.app.post_json(TOKEN_V1_PATH, {}, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(side_effect=Exception())) @mock.patch.object(User, 'add_or_update', mock.Mock(return_value=UserDB(name=USERNAME))) def test_token_post_new_user(self): self._test_token_post() @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_existing_user(self): self._test_token_post() @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_default_url_path(self): self._test_token_post(path=TOKEN_DEFAULT_PATH) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_ttl(self): timestamp = date_utils.add_utc_tz(date_utils.get_datetime_utc_now()) response = self.app.post_json(TOKEN_V1_PATH, {'ttl': 60}, expect_errors=False) expected_expiry = date_utils.get_datetime_utc_now( ) + datetime.timedelta(seconds=60) self.assertEqual(response.status_int, 201) actual_expiry = isotime.parse(response.json['expiry']) self.assertLess(timestamp, actual_expiry) self.assertLess(actual_expiry, expected_expiry) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_ttl_over_policy(self): ttl = cfg.CONF.auth.token_ttl response = self.app.post_json(TOKEN_V1_PATH, {'ttl': ttl + 60}, expect_errors=True) self.assertEqual(response.status_int, 400) message = 'TTL specified %s is greater than max allowed %s.' % ( ttl + 60, ttl) self.assertEqual(response.json['faultstring'], message) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_bad_ttl(self): response = self.app.post_json(TOKEN_V1_PATH, {'ttl': -1}, expect_errors=True) self.assertEqual(response.status_int, 400) response = self.app.post_json(TOKEN_V1_PATH, {'ttl': 0}, expect_errors=True) self.assertEqual(response.status_int, 400) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because an API key or token is not provided in header. data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized_bad_api_key(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because the API key is bad. headers = {'St2-Api-Key': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized_bad_token(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because the token is bad. headers = {'X-Auth-Token': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) @mock.patch.object( ApiKey, 'get', mock.MagicMock(return_value=ApiKeyDB(user=USERNAME, key_hash='foobar')) ) def test_token_get_auth_with_api_key(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. Use an API key to authenticate with the st2 auth get token endpoint. headers = {'St2-Api-Key': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 200) self.assertTrue(response.json['valid']) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_auth_with_token(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. Use a token to authenticate with the st2 auth get token endpoint. headers = {'X-Auth-Token': str(response.json['token'])} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 200) self.assertTrue(response.json['valid']) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) @mock.patch.object( ApiKey, 'get', mock.MagicMock(return_value=ApiKeyDB(user=USERNAME, key_hash='foobar')) ) @mock.patch.object( Token, 'get', mock.MagicMock( return_value=TokenDB(user=USERNAME, token='12345', expiry=date_utils.get_datetime_utc_now() - datetime.timedelta(minutes=1)))) def test_token_get_unauthorized_bad_ttl(self): # Verify the token. 400 is expected because the token has expired. headers = {'St2-Api-Key': 'foobar'} data = {'token': '12345'} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=False) self.assertEqual(response.status_int, 200) self.assertFalse(response.json['valid'])
def test_get_uid(self): pack_db = PackDB(ref="ma_pack") self.assertEqual(pack_db.get_uid(), "pack:ma_pack") self.assertTrue(pack_db.has_valid_uid()) sensor_type_db = SensorTypeDB(name="sname", pack="spack") self.assertEqual(sensor_type_db.get_uid(), "sensor_type:spack:sname") self.assertTrue(sensor_type_db.has_valid_uid()) action_db = ActionDB(name="aname", pack="apack", runner_type={}) self.assertEqual(action_db.get_uid(), "action:apack:aname") self.assertTrue(action_db.has_valid_uid()) rule_db = RuleDB(name="rname", pack="rpack") self.assertEqual(rule_db.get_uid(), "rule:rpack:rname") self.assertTrue(rule_db.has_valid_uid()) trigger_type_db = TriggerTypeDB(name="ttname", pack="ttpack") self.assertEqual(trigger_type_db.get_uid(), "trigger_type:ttpack:ttname") self.assertTrue(trigger_type_db.has_valid_uid()) trigger_db = TriggerDB(name="tname", pack="tpack") self.assertTrue(trigger_db.get_uid().startswith("trigger:tpack:tname:")) # Verify that same set of parameters always results in the same hash parameters = {"a": 1, "b": "unicode", "c": [1, 2, 3], "d": {"g": 1, "h": 2}} paramers_hash = json.dumps(parameters, sort_keys=True) paramers_hash = hashlib.md5(paramers_hash.encode()).hexdigest() parameters = {"a": 1, "b": "unicode", "c": [1, 2, 3], "d": {"g": 1, "h": 2}} trigger_db = TriggerDB(name="tname", pack="tpack", parameters=parameters) self.assertEqual( trigger_db.get_uid(), "trigger:tpack:tname:%s" % (paramers_hash) ) self.assertTrue(trigger_db.has_valid_uid()) parameters = {"c": [1, 2, 3], "b": "unicode", "d": {"h": 2, "g": 1}, "a": 1} trigger_db = TriggerDB(name="tname", pack="tpack", parameters=parameters) self.assertEqual( trigger_db.get_uid(), "trigger:tpack:tname:%s" % (paramers_hash) ) self.assertTrue(trigger_db.has_valid_uid()) parameters = {"b": "unicode", "c": [1, 2, 3], "d": {"h": 2, "g": 1}, "a": 1} trigger_db = TriggerDB(name="tname", pack="tpack", parameters=parameters) self.assertEqual( trigger_db.get_uid(), "trigger:tpack:tname:%s" % (paramers_hash) ) self.assertTrue(trigger_db.has_valid_uid()) parameters = OrderedDict( {"c": [1, 2, 3], "b": "unicode", "d": {"h": 2, "g": 1}, "a": 1} ) trigger_db = TriggerDB(name="tname", pack="tpack", parameters=parameters) self.assertEqual( trigger_db.get_uid(), "trigger:tpack:tname:%s" % (paramers_hash) ) self.assertTrue(trigger_db.has_valid_uid()) policy_type_db = PolicyTypeDB(resource_type="action", name="concurrency") self.assertEqual(policy_type_db.get_uid(), "policy_type:action:concurrency") self.assertTrue(policy_type_db.has_valid_uid()) policy_db = PolicyDB(pack="dummy", name="policy1") self.assertEqual(policy_db.get_uid(), "policy:dummy:policy1") api_key_db = ApiKeyDB(key_hash="valid") self.assertEqual(api_key_db.get_uid(), "api_key:valid") self.assertTrue(api_key_db.has_valid_uid()) api_key_db = ApiKeyDB() self.assertEqual(api_key_db.get_uid(), "api_key:") self.assertFalse(api_key_db.has_valid_uid())