def setUp(self): self.testuser = '******' self.account_alias = 'aws-account-alias' self.role = 'role' self.account_config = {'aws-account-alias': {'id': '123456789'}} proxy_logger = logging.getLogger('proxy_logger') self.handler = TestHandler() proxy_logger.addHandler(self.handler) proxy_logger.setLevel(logging.INFO) self.proxy = AWSFederationProxy(user=self.testuser, config=self.config, account_config=self.account_config, logger=proxy_logger) self.test_access_key = "unencoded string;" self.test_secret_key = "another weird string" self.test_session_token = "string with special characters %&;?" self.credentials = CredentialDict({ 'access_key': self.test_access_key, 'secret_key': self.test_secret_key, 'session_token': self.test_session_token })
def setUp(self): self.testuser = '******' self.account_alias = 'aws-account-alias' self.role = 'role' self.account_config = { 'aws-account-alias': { 'id': '123456789' } } proxy_logger = logging.getLogger('proxy_logger') self.handler = TestHandler() proxy_logger.addHandler(self.handler) proxy_logger.setLevel(logging.INFO) self.proxy = AWSFederationProxy( user=self.testuser, config=self.config, account_config=self.account_config, logger=proxy_logger) self.test_access_key = "unencoded string;" self.test_secret_key = "another weird string" self.test_session_token = "string with special characters %&;?" self.credentials = CredentialDict({ 'access_key': self.test_access_key, 'secret_key': self.test_secret_key, 'session_token': self.test_session_token })
def test_instantiate_provider_with_proper_parameters(self): user = "******" config = { 'provider': { 'module': 'aws_federation_proxy.provider.base_provider', 'class': 'GroupTestProvider', 'regex': '(?P<account>.*)-(?P<role>.*)' } } proxy = AWSFederationProxy(user=user, config=config, account_config={}) provider = proxy.provider self.assertEqual(user, provider.user) self.assertEqual(proxy.application_config['provider'], provider.config) self.assertIs(proxy.logger, provider.logger)
def initialize_federation_proxy(user=None): """Get needed config parts and initialize AWSFederationProxy""" config_path = request.environ.get('CONFIG_PATH') if config_path is None: raise Exception("No Config Path specified") config = yaml_load(config_path) try: logger = setup_logging(config, logger_name=LOGGER_NAME) except Exception as exc: raise ConfigurationError(str(exc)) if user is None: user = get_user(config['api']['user_identification']) account_config_path = request.environ.get('ACCOUNT_CONFIG_PATH') if account_config_path is None: raise Exception("No Account Config Path specified") account_config = yaml_load(account_config_path) proxy = AWSFederationProxy(user=user, config=config, account_config=account_config, logger=logger) return proxy
class BaseAFPTest(object): def setUp(self): self.testuser = '******' self.account_alias = 'aws-account-alias' self.role = 'role' self.account_config = { 'aws-account-alias': { 'id': '123456789' } } proxy_logger = logging.getLogger('proxy_logger') self.handler = TestHandler() proxy_logger.addHandler(self.handler) proxy_logger.setLevel(logging.INFO) self.proxy = AWSFederationProxy( user=self.testuser, config=self.config, account_config=self.account_config, logger=proxy_logger) self.test_access_key = "unencoded string;" self.test_secret_key = "another weird string" self.test_session_token = "string with special characters %&;?" self.credentials = CredentialDict({ 'access_key': self.test_access_key, 'secret_key': self.test_secret_key, 'session_token': self.test_session_token }) def test_check_user_permissions_ok(self): self.proxy.check_user_permissions('testaccount', 'testrole') self.assertIn(self.testuser, self.handler.logged_messages) self.assertIn('testrole', self.handler.logged_messages) self.assertIn('testaccount', self.handler.logged_messages) self.proxy.check_user_permissions('testaccount1', 'testrole2') self.assertIn('testrole2', self.handler.logged_messages) self.assertIn('testaccount', self.handler.logged_messages) def test_check_user_permissions_wrong_account(self): self.assertRaisesRegexp( Exception, 'noaccount', self.proxy.check_user_permissions, 'noaccount', 'testrole') self.assertIn('noaccount', self.handler.logged_messages) self.assertIn('testrole', self.handler.logged_messages) self.assertIn(self.testuser, self.handler.logged_messages) self.handler.logged_messages = "" self.assertRaisesRegexp( Exception, '(noaccount|norole)', self.proxy.check_user_permissions, 'noaccount', 'norole') self.assertIn('noaccount', self.handler.logged_messages) self.assertIn('norole', self.handler.logged_messages) self.assertIn(self.testuser, self.handler.logged_messages) def test_check_user_permissions_wrong_role(self): self.assertRaisesRegexp( Exception, 'norole', self.proxy.check_user_permissions, 'testaccount', 'norole') self.assertRaisesRegexp( Exception, '(noaccount|norole)', self.proxy.check_user_permissions, 'noaccount', 'norole') @patch("aws_federation_proxy.aws_federation_proxy.STSConnection") @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials_uses_correct_arn( self, mock_check_user_permissions, mock_sts_connection): arn = "arn:aws:iam::{account_id}:role/{role}" arn = arn.format( account_id=self.account_config[self.account_alias]['id'], role=self.role) self.proxy.get_aws_credentials(self.account_alias, self.role) mock_sts_connection.return_value.assume_role.assert_called_with( role_arn=arn, role_session_name=self.testuser) @patch("aws_federation_proxy.aws_federation_proxy.STSConnection") @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials_handles_403_permission_denied( self, mock_check_user_permissions, mock_sts_connection): """403 Permission Denied must raise PermissionError""" class FakeHTTPError(Exception): status = 403 mock_sts_connection.side_effect = FakeHTTPError self.assertRaises( PermissionError, self.proxy.get_aws_credentials, self.account_alias, self.role) @patch("aws_federation_proxy.aws_federation_proxy.STSConnection") @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials_handles_sts_errors( self, mock_check_user_permissions, mock_sts_connection): """Other errors must raise AWSError and log the AWS request ID""" fake_boto_error = boto.exception.AWSConnectionError("AWS message") fake_boto_error.request_id = "111222333" mock_sts_connection.side_effect = fake_boto_error with self.assertLogs(level='ERROR') as cm: self.assertRaises( AWSError, self.proxy.get_aws_credentials, self.account_alias, self.role) all_log_messages = "".join(cm.output) self.assertIn(fake_boto_error.request_id, all_log_messages) @mock_sts @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials(self, mock_check_user_permissions): session_token = ( 'BQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfr' 'Rh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBan' 'LiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/' 'AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE') expected_result = { 'access_key': u'AKIAIOSFODNN7EXAMPLE', 'secret_key': u'aJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY', 'session_token': session_token } result = self.proxy.get_aws_credentials('aws-account-alias', 'role') self.assertEqual( result.access_key, expected_result['access_key'], 'Should be the same AWS access_key') self.assertEqual( result.secret_key, expected_result['secret_key'], 'Should be the same AWS secret_key') self.assertEqual( result.session_token, expected_result['session_token'], 'Should be the same AWS session_token') # Check that exception is raised if account is not configured self.assertRaisesRegexp(Exception, 'account-alias-not-configured', self.proxy.get_aws_credentials, 'account-alias-not-configured', 'role') # Check that exception is raised if user has no permissions mock_check_user_permissions.side_effect = Exception self.assertRaises( Exception, self.proxy.get_aws_credentials, 'aws-account-alias', 'role') def test_encode_json_credentials_returned(self): expected_credential_dict = { 'sessionId': self.test_access_key, 'sessionKey': self.test_secret_key, 'sessionToken': self.test_session_token } returned_credentialstring = self.proxy._generate_urlencoded_json_credentials(self.credentials) decoded_credentialstring = unquote_plus( returned_credentialstring) self.assertNotEqual( decoded_credentialstring, returned_credentialstring) credential_dict = json.loads(decoded_credentialstring) self.assertEqual(credential_dict, expected_credential_dict) def test_encode_json_credentials_throws_exception_on_missing_parameter(self): credential_dict = CredentialDict({ 'access_key': self.test_access_key, 'secret_key': self.test_secret_key, }) self.assertRaisesRegexp( Exception, 'session_token', self.proxy._generate_urlencoded_json_credentials, credential_dict ) @patch("aws_federation_proxy.aws_federation_proxy.requests.get") def test_get_signin_token(self, mock_get): token = "abcdefg123" mock_get.return_value = Mock(text=u'{"SigninToken": "%s"}' % token, status_code=200, reason="Ok") returned_token = self.proxy._get_signin_token(self.credentials) self.assertEqual(token, returned_token) @patch("aws_federation_proxy.aws_federation_proxy.requests.get") def test_get_signin_token_throws_exception_on_error(self, mock_get): token = "abcdefg123" reason = "Bad request" mock_get.return_value = Mock(text=u'{"SigninToken": "%s"}' % token, status_code=400, reason=reason) self.assertRaisesRegexp(Exception, reason, self.proxy._get_signin_token, self.credentials) def test_construct_console_url(self): token = "abcdefg123" callback_url = 'http://callback_url' encoded_callback_url = quote_plus(callback_url) expected_return = ( 'https://signin.aws.amazon.com/federation?' 'Action=login&Issuer={callback_url}&' 'Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&' 'SigninToken={token}') expected_return = expected_return.format( token=token, callback_url=encoded_callback_url) result_url = self.proxy._construct_console_url(token, callback_url) self.assertEqual( result_url, expected_return, "Should return correct signin URL, got {0}".format(result_url)) def test_get_console_url(self): token = "abcdefg123" callback_url = 'http://callback_url' encoded_callback_url = quote_plus(callback_url) self.proxy._get_signin_token = Mock(return_value=token) console_url = self.proxy.get_console_url( self.credentials, callback_url) expected_console_url = ( 'https://signin.aws.amazon.com/federation?' 'Action=login&Issuer={callback_url}&' 'Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&' 'SigninToken={token}') expected_console_url = expected_console_url.format( token=token, callback_url=encoded_callback_url) self.assertEqual(console_url, expected_console_url)
class BaseAFPTest(object): def setUp(self): self.testuser = '******' self.account_alias = 'aws-account-alias' self.role = 'role' self.account_config = {'aws-account-alias': {'id': '123456789'}} proxy_logger = logging.getLogger('proxy_logger') self.handler = TestHandler() proxy_logger.addHandler(self.handler) proxy_logger.setLevel(logging.INFO) self.proxy = AWSFederationProxy(user=self.testuser, config=self.config, account_config=self.account_config, logger=proxy_logger) self.test_access_key = "unencoded string;" self.test_secret_key = "another weird string" self.test_session_token = "string with special characters %&;?" self.credentials = CredentialDict({ 'access_key': self.test_access_key, 'secret_key': self.test_secret_key, 'session_token': self.test_session_token }) def test_check_user_permissions_ok(self): self.proxy.check_user_permissions('testaccount', 'testrole') self.assertIn(self.testuser, self.handler.logged_messages) self.assertIn('testrole', self.handler.logged_messages) self.assertIn('testaccount', self.handler.logged_messages) self.proxy.check_user_permissions('testaccount1', 'testrole2') self.assertIn('testrole2', self.handler.logged_messages) self.assertIn('testaccount', self.handler.logged_messages) def test_check_user_permissions_wrong_account(self): self.assertRaisesRegexp(Exception, 'noaccount', self.proxy.check_user_permissions, 'noaccount', 'testrole') self.assertIn('noaccount', self.handler.logged_messages) self.assertIn('testrole', self.handler.logged_messages) self.assertIn(self.testuser, self.handler.logged_messages) self.handler.logged_messages = "" self.assertRaisesRegexp(Exception, '(noaccount|norole)', self.proxy.check_user_permissions, 'noaccount', 'norole') self.assertIn('noaccount', self.handler.logged_messages) self.assertIn('norole', self.handler.logged_messages) self.assertIn(self.testuser, self.handler.logged_messages) def test_check_user_permissions_wrong_role(self): self.assertRaisesRegexp(Exception, 'norole', self.proxy.check_user_permissions, 'testaccount', 'norole') self.assertRaisesRegexp(Exception, '(noaccount|norole)', self.proxy.check_user_permissions, 'noaccount', 'norole') @patch("aws_federation_proxy.aws_federation_proxy.STSConnection") @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials_uses_correct_arn(self, mock_check_user_permissions, mock_sts_connection): arn = "arn:aws:iam::{account_id}:role/{role}" arn = arn.format( account_id=self.account_config[self.account_alias]['id'], role=self.role) self.proxy.get_aws_credentials(self.account_alias, self.role) mock_sts_connection.return_value.assume_role.assert_called_with( role_arn=arn, role_session_name=self.testuser) @patch("aws_federation_proxy.aws_federation_proxy.STSConnection") @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials_handles_403_permission_denied( self, mock_check_user_permissions, mock_sts_connection): """403 Permission Denied must raise PermissionError""" class FakeHTTPError(Exception): status = 403 mock_sts_connection.side_effect = FakeHTTPError self.assertRaises(PermissionError, self.proxy.get_aws_credentials, self.account_alias, self.role) @patch("aws_federation_proxy.aws_federation_proxy.STSConnection") @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials_handles_sts_errors( self, mock_check_user_permissions, mock_sts_connection): """Other errors must raise AWSError and log the AWS request ID""" fake_boto_error = boto.exception.AWSConnectionError("AWS message") fake_boto_error.request_id = "111222333" mock_sts_connection.side_effect = fake_boto_error with self.assertLogs(level='ERROR') as cm: self.assertRaises(AWSError, self.proxy.get_aws_credentials, self.account_alias, self.role) all_log_messages = "".join(cm.output) self.assertIn(fake_boto_error.request_id, all_log_messages) @mock_sts @patch("aws_federation_proxy.AWSFederationProxy.check_user_permissions") def test_get_aws_credentials(self, mock_check_user_permissions): session_token = ( 'BQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfr' 'Rh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBan' 'LiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/' 'AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE') expected_result = { 'access_key': u'AKIAIOSFODNN7EXAMPLE', 'secret_key': u'aJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY', 'session_token': session_token } result = self.proxy.get_aws_credentials('aws-account-alias', 'role') self.assertEqual(result.access_key, expected_result['access_key'], 'Should be the same AWS access_key') self.assertEqual(result.secret_key, expected_result['secret_key'], 'Should be the same AWS secret_key') self.assertEqual(result.session_token, expected_result['session_token'], 'Should be the same AWS session_token') # Check that exception is raised if account is not configured self.assertRaisesRegexp(Exception, 'account-alias-not-configured', self.proxy.get_aws_credentials, 'account-alias-not-configured', 'role') # Check that exception is raised if user has no permissions mock_check_user_permissions.side_effect = Exception self.assertRaises(Exception, self.proxy.get_aws_credentials, 'aws-account-alias', 'role') def test_encode_json_credentials_returned(self): expected_credential_dict = { 'sessionId': self.test_access_key, 'sessionKey': self.test_secret_key, 'sessionToken': self.test_session_token } returned_credentialstring = self.proxy._generate_urlencoded_json_credentials( self.credentials) decoded_credentialstring = unquote_plus(returned_credentialstring) self.assertNotEqual(decoded_credentialstring, returned_credentialstring) credential_dict = json.loads(decoded_credentialstring) self.assertEqual(credential_dict, expected_credential_dict) def test_encode_json_credentials_throws_exception_on_missing_parameter( self): credential_dict = CredentialDict({ 'access_key': self.test_access_key, 'secret_key': self.test_secret_key, }) self.assertRaisesRegexp( Exception, 'session_token', self.proxy._generate_urlencoded_json_credentials, credential_dict) @patch("aws_federation_proxy.aws_federation_proxy.requests.get") def test_get_signin_token(self, mock_get): token = "abcdefg123" mock_get.return_value = Mock(text=u'{"SigninToken": "%s"}' % token, status_code=200, reason="Ok") returned_token = self.proxy._get_signin_token(self.credentials) self.assertEqual(token, returned_token) @patch("aws_federation_proxy.aws_federation_proxy.requests.get") def test_get_signin_token_throws_exception_on_error(self, mock_get): token = "abcdefg123" reason = "Bad request" mock_get.return_value = Mock(text=u'{"SigninToken": "%s"}' % token, status_code=400, reason=reason) self.assertRaisesRegexp(Exception, reason, self.proxy._get_signin_token, self.credentials) def test_construct_console_url(self): token = "abcdefg123" callback_url = 'http://callback_url' encoded_callback_url = quote_plus(callback_url) expected_return = ( 'https://signin.aws.amazon.com/federation?' 'Action=login&Issuer={callback_url}&' 'Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&' 'SigninToken={token}') expected_return = expected_return.format( token=token, callback_url=encoded_callback_url) result_url = self.proxy._construct_console_url(token, callback_url) self.assertEqual( result_url, expected_return, "Should return correct signin URL, got {0}".format(result_url)) def test_get_console_url(self): token = "abcdefg123" callback_url = 'http://callback_url' encoded_callback_url = quote_plus(callback_url) self.proxy._get_signin_token = Mock(return_value=token) console_url = self.proxy.get_console_url(self.credentials, callback_url) expected_console_url = ( 'https://signin.aws.amazon.com/federation?' 'Action=login&Issuer={callback_url}&' 'Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&' 'SigninToken={token}') expected_console_url = expected_console_url.format( token=token, callback_url=encoded_callback_url) self.assertEqual(console_url, expected_console_url)