Beispiel #1
0
def fetch_session_token(mfa_token: str) -> Result:
    result = Result()
    credentials_file = _load_credentials_file()
    logger.info('fetch session-token')
    profile = 'session-token'

    try:
        secrets = _get_session_token(mfa_token)
    except ClientError:
        error_text = 'could not fetch session token'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result
    except ParamValidationError:
        error_text = 'invalid mfa token'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result
    except NoCredentialsError:
        error_text = 'access_key credentials invalid'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result

    _add_profile_credentials(credentials_file, profile, secrets)
    _write_credentials_file(credentials_file)
    logger.info('session-token successfully fetched')
    result.set_success()
    return result
Beispiel #2
0
 def test_error(self):
     result = Result()
     error_message = 'there was an error'
     result.error(error_message)
     self.assertEqual(False, result.was_success)
     self.assertEqual(True, result.was_error)
     self.assertEqual(error_message, result.error_message)
Beispiel #3
0
    def login(self, profile_group: ProfileGroup,
              mfa_callback: Callable) -> Result:
        result = Result()
        logger.info(f'start login {profile_group.name}')
        self.active_profile_group = profile_group

        access_key_result = credentials.check_access_key()
        if not access_key_result.was_success:
            return access_key_result

        session_result = credentials.check_session()
        if session_result.was_error:
            return session_result
        if not session_result.was_success:
            renew_session_result = self._renew_session(mfa_callback)
            if not renew_session_result.was_success:
                return renew_session_result

        user_name = credentials.get_user_name()
        role_result = credentials.fetch_role_credentials(
            user_name, profile_group)
        if not role_result.was_success:
            return role_result

        set_region_result = self.set_region(self.region_override)
        if not set_region_result.was_success:
            return set_region_result

        logger.info('login success')
        self._handle_support_files(profile_group)
        result.set_success()
        return result
Beispiel #4
0
    def rotate_access_key() -> Result:
        result = Result()
        logger.info('initiate key rotation')
        logger.info('check access key')
        access_key_result = credentials.check_access_key()
        if not access_key_result.was_success:
            return access_key_result

        logger.info('check session')
        check_session_result = credentials.check_session()
        if not check_session_result.was_success:
            check_session_result.error('Access Denied. Please log first')
            return check_session_result

        logger.info('create key')
        user = credentials.get_user_name()
        create_access_key_result = iam.create_access_key(user)
        if not create_access_key_result.was_success:
            return create_access_key_result

        logger.info('delete key')
        previous_access_key_id = credentials.get_access_key_id()
        iam.delete_iam_access_key(user, previous_access_key_id)

        logger.info('save key')
        credentials.set_access_key(
            key_id=create_access_key_result.payload['AccessKeyId'],
            access_key=create_access_key_result.payload['SecretAccessKey'])

        result.set_success()
        return result
Beispiel #5
0
 def set_region(self, region: str) -> Result:
     self.region_override = region
     if not self.active_profile_group:
         result = Result()
         result.set_success()
         return result
     return credentials.write_profile_config(self.active_profile_group,
                                             self.get_region())
Beispiel #6
0
 def _renew_session(self, mfa_callback: Callable) -> Result:
     logger.info('renew session')
     logger.info('get mfa from console')
     token = mfa.fetch_mfa_token_from_shell(self.config.mfa_shell_command)
     if not token:
         logger.info('get mfa from user')
         token = mfa_callback()
         if not token:
             result = Result()
             result.error('invalid mfa token')
             return result
     session_result = credentials.fetch_session_token(token)
     return session_result
Beispiel #7
0
    def logout(self):
        result = Result()
        logger.info(f'start logout')

        role_result = credentials.fetch_role_credentials(
            user_name='none', profile_group=self.empty_profile_group)
        if not role_result.was_success:
            return role_result

        config_result = credentials.write_profile_config(
            profile_group=self.empty_profile_group, region='')
        if not config_result.was_success:
            return config_result

        logger.info('logout success')
        result.set_success()
        return result
Beispiel #8
0
def fetch_role_credentials(user_name: str,
                           profile_group: ProfileGroup) -> Result:
    result = Result()
    credentials_file = _load_credentials_file()
    logger.info('fetch role credentials')

    try:
        for profile in profile_group.profiles:
            logger.info(f'fetch {profile.profile}')
            source_profile = profile.source or 'session-token'
            secrets = _assume_role(source_profile, user_name, profile.account,
                                   profile.role)
            _add_profile_credentials(credentials_file, profile.profile,
                                     secrets)
            if profile.default:
                _add_profile_credentials(credentials_file, 'default', secrets)
            _write_credentials_file(credentials_file)

        credentials_file = _remove_unused_profiles(credentials_file,
                                                   profile_group)
    except Exception:
        error_text = 'error while fetching role credentials'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result

    _write_credentials_file(credentials_file)
    result.set_success()
    return result
Beispiel #9
0
    def test_rotate_access_key__successful_rotate(self, mock_credentials, mock_iam):
        mock_credentials.check_access_key.return_value = self.success_result
        mock_credentials.check_session.return_value = self.success_result
        mock_credentials.get_user_name.return_value = 'test-user'
        mock_credentials.get_access_key_id.return_value = '12345'

        access_key_result = Result()
        access_key_result.add_payload({
            'AccessKeyId': 12345,
            'SecretAccessKey': 67890
        })
        access_key_result.set_success()

        mock_iam.create_access_key.return_value = access_key_result

        result = self.core.rotate_access_key()

        expected = [call.check_access_key(),
                    call.check_session(),
                    call.get_user_name(),
                    call.get_access_key_id(),
                    call.set_access_key(key_id=12345, access_key=67890)]
        self.assertEqual(expected, mock_credentials.mock_calls)

        expected = [call.create_access_key('test-user'),
                    call.delete_iam_access_key('test-user', '12345')]
        self.assertEqual(expected, mock_iam.mock_calls)

        self.assertEqual(True, result.was_success)
        self.assertEqual(False, result.was_error)
Beispiel #10
0
def create_access_key(user_name) -> Result:
    result = Result()
    session = boto3.Session(profile_name='session-token')
    client = session.client('iam')

    try:
        response = client.create_access_key(UserName=user_name)
    except client.exceptions.LimitExceededException:
        error_text = 'key limit reached, creation failed'
        logger.warning(error_text)
        result.error(error_text)
        return result

    if 'AccessKey' not in response:
        error_text = 'unknown error with iam'
        logger.error(error_text)
        logger.error(response)
        result.error(error_text)
        return result

    result.add_payload(response['AccessKey'])
    result.set_success()
    return result
Beispiel #11
0
 def edit_config(self, config: Config) -> Result:
     result = Result()
     try:
         self.config = config
         self.config.save_to_disk()
     except Exception as error:
         logger.error(str(error), exc_info=True)
         result.error('could not save config')
         return result
     result.set_success()
     return result
Beispiel #12
0
def has_access_key() -> Result:
    logger.info('has access key')
    result = Result()
    credentials_file = _load_credentials_file()

    if not credentials_file.has_section('access-key'):
        error_text = 'could not find profile \'access-key\' in .aws/credentials'
        result.error(error_text)
        logger.warning(error_text)
        return result
    result.set_success()
    return result
Beispiel #13
0
def check_access_key() -> Result:
    logger.info('check access key')
    access_key_result = has_access_key()
    if not access_key_result.was_success:
        return access_key_result

    result = Result()
    try:
        client = _get_client('access-key', 'sts', timeout=2, retries=2)
        client.get_caller_identity()
    except ClientError:
        error_text = 'access key is not valid'
        result.error(error_text)
        logger.warning(error_text)
        return result
    except (EndpointConnectionError, ReadTimeoutError):
        error_text = 'could not reach sts service'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result
    result.set_success()
    return result
Beispiel #14
0
def delete_iam_access_key(user_name, key_id):
    result = Result()
    session = boto3.Session(profile_name='session-token')
    client = session.client('iam')

    try:
        client.delete_access_key(UserName=user_name, AccessKeyId=key_id)
    except Exception:
        error_text = 'could not remove old key'
        logger.error(error_text, exc_info=True)
        result.error(error_text)
        return result

    result.set_success()
    return result
Beispiel #15
0
def write_profile_config(profile_group: ProfileGroup, region: str):
    result = Result()
    config_file = _load_config_file()

    try:
        for profile in profile_group.profiles:
            logger.info(f'add config for {profile.profile}')
            _add_profile_config(config_file, profile.profile, region)
            if profile.default:
                _add_profile_config(config_file, 'default', region)
        config_file = _remove_unused_configs(config_file, profile_group)
    except Exception:
        error_text = 'error writing config'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result

    _write_config_file(config_file)
    result.set_success()
    return result
Beispiel #16
0
def check_session() -> Result:
    result = Result()
    credentials_file = _load_credentials_file()
    if not credentials_file.has_section('session-token'):
        logger.warning('no session token found')
        return result

    try:
        client = _get_client('session-token', 'sts', timeout=2, retries=2)
        client.get_caller_identity()
    except ClientError:
        # this is the normal case when the session token is not valid. Proceed then to fetch a new one
        return result
    except (EndpointConnectionError, ReadTimeoutError):
        error_text = 'could not reach sts service'
        result.error(error_text)
        logger.error(error_text, exc_info=True)
        return result

    result.set_success()
    return result
Beispiel #17
0
def get_failed_result() -> Result:
    return Result()
Beispiel #18
0
def get_error_result() -> Result:
    result = Result()
    result.error('some error')
    return result
Beispiel #19
0
def get_success_result() -> Result:
    result = Result()
    result.set_success()
    return result
Beispiel #20
0
 def test___unsuccessful_by_default(self):
     result = Result()
     self.assertEqual(False, result.was_success)
     self.assertEqual(False, result.was_error)
Beispiel #21
0
 def test_set_success(self):
     result = Result()
     result.set_success()
     self.assertEqual(True, result.was_success)
     self.assertEqual(False, result.was_error)
Beispiel #22
0
 def test_add_payload(self):
     result = Result()
     result.add_payload('test')
     self.assertEqual(False, result.was_success)
     self.assertEqual(False, result.was_error)
     self.assertEqual('test', result.payload)