"""Test token model.""" from unittest.mock import MagicMock from boto import exception from boto.sts import STSConnection as boto_sts from moto import mock_sts from oto import response import pytest from assets import config from assets.connectors import sentry from assets.connectors import sts from assets.models import token @pytest.fixture def fixture_set_iam_role(): """Fixture to set IAM role.""" config.IAM_ROLE = 'a_role' @pytest.fixture def fixture_filename(): """Fixture to generate a filename.""" return 'a_filename' @pytest.fixture def fixture_error(): """Fixture to generate unsuccessful response.""" return response.create_fatal_response() @pytest.fixture def fixture_token_dict(): """Fixture for a token.""" return { 'token': 'a token', 'aws_access_key_id': 'access key', 'aws_secret_access_key': 'secret key', 'expiration': 'today' } @pytest.fixture def fixture_policy(bucket, filename): """Fixture for iam policy for s3. Args: bucket (string): name of bucket. filename (string): name of filename. Returns: dict: Expected structure of iam policy for s3. """ return { 'Version': '2012-10-17', 'Statement': [ { 'Effect': 'Allow', 'Action': [ 's3:PutObject' ], 'Resource': 'arn:aws:s3:::{bucket}/{filename}.*'.format( bucket=bucket, filename=filename) } ] } def test__to_dict(): """Test converting an aws credential object.""" session_token = 'a session token' access_key = 'access' secret_key = 'shhhhh' expiration = 'in 900 seconds' credentials = { 'session_token': session_token, 'access_key': access_key, 'secret_key': secret_key, 'expiration': expiration } result = token._to_dict(credentials) assert result.get('token') == session_token assert result.get('aws_access_key_id') == access_key assert result.get('aws_secret_access_key') == secret_key assert result.get('expiration') == expiration def test__prepare_iam_policy_s3(monkeypatch): """Test iam policy for s3 uses bucket name and filename.""" expected = { 'Version': '2012-10-17', 'Statement': [ { 'Effect': 'Allow', 'Action': [ 's3:PutObject' ], 'Resource': 'arn:aws:s3:::bucket/filename.*' } ] } result = token._prepare_iam_policy_s3('bucket', 'filename') assert result == expected def test_get_s3_token_fails_no_sts( monkeypatch, fixture_error, fixture_filename): """Test get_s3_token fails when no sts connection.""" monkeypatch.setattr(sts, 'connect_to_sts', MagicMock( return_value=fixture_error)) result = token.get_s3_token(fixture_filename) assert result.status == 500 def test_get_s3_token_fails_server_error( monkeypatch, fixture_set_iam_role, fixture_filename): """Test get_s3_token fails when server error.""" sentry_mock = MagicMock(return_value='ok') monkeypatch.setattr(sentry.sentry_client, 'captureException', sentry_mock) with mock_sts(): monkeypatch.setattr( boto_sts, 'assume_role', MagicMock( side_effect=exception.BotoServerError('fail', 'test'))) result = token.get_s3_token(fixture_filename) assert not result sentry_mock.assert_called() def test_get_s3_token( monkeypatch, fixture_token_dict, fixture_set_iam_role, fixture_filename): """Test get_s3_token succeeds.""" policy = fixture_policy('a_bucket', fixture_filename) monkeypatch.setattr( token, '_prepare_iam_policy_s3', MagicMock(return_value=policy)) token_to_dict = MagicMock(return_value=fixture_token_dict) monkeypatch.setattr( token, '_to_dict', token_to_dict) with mock_sts(): result = token.get_s3_token(fixture_filename) assert result assert result.message == fixture_token_dict credentials = token_to_dict.call_args[0][0] assert credentials['session_token'] assert credentials['access_key'] assert credentials['secret_key'] assert credentials['expiration']