示例#1
0
 def __init__(self, context: FiggyContext):
     self._cache_mgr = CacheManager(file_override=DEFAULTS_FILE_CACHE_PATH)
     self._config_mgr, self.c = ConfigManager.figgy(), Utils.default_colors()
     self._session_mgr = None
     self._session_provider = None
     self._secrets_mgr = SecretsManager()
     self._figgy_context = context
示例#2
0
    def configure(mfa_enabled: bool = False) -> "GoogleProviderConfig":
        config, c = ConfigManager(CONFIG_OVERRIDE_FILE_PATH), Utils.default_colors()

        idp_id = config.get_property(Config.Section.Google.IDP_ID)
        sp_id = config.get_property(Config.Section.Google.SP_ID)

        if idp_id and idp_id != FAKE_GOOGLE_IDP_ID:
            idp_id = config.get_or_prompt(Config.Section.Google.IDP_ID, GoogleProviderConfig.get_idp_id)
        else:
            idp_id = config.get_or_prompt(Config.Section.Google.IDP_ID, GoogleProviderConfig.get_idp_id, force_prompt=True)

        if sp_id and sp_id != FAKE_GOOGLE_SP_ID:
            sp_id = config.get_or_prompt(Config.Section.Google.SP_ID, GoogleProviderConfig.get_sp_id)
        else:
            sp_id = config.get_or_prompt(Config.Section.Google.SP_ID, GoogleProviderConfig.get_sp_id, force_prompt=True)

        return GoogleProviderConfig(idp_id=idp_id, sp_id=sp_id)
示例#3
0
    def configure(mfa_enabled: bool = False) -> "OktaProviderConfig":
        config, c = ConfigManager(CONFIG_OVERRIDE_FILE_PATH), Utils.default_colors()
        app_link = config.get_property(Config.Section.Google.IDP_ID)
        if app_link and app_link != FAKE_OKTA_APP_LINK:
            app_link = config.get_or_prompt(Config.Section.Okta.APP_LINK, OktaProviderConfig.get_app_link,
                                            desc=OKTA_APP_LINK_DESC)
        else:
            app_link = config.get_or_prompt(Config.Section.Okta.APP_LINK, OktaProviderConfig.get_app_link,
                                            force_prompt=True, desc=OKTA_APP_LINK_DESC)

        if mfa_enabled:
            factor_type = config.get_or_prompt(Config.Section.Okta.FACTOR_TYPE, OktaProviderConfig.get_factor_type,
                                               desc=OKTA_MFA_TYPE_DESC)
        else:
            factor_type = None

        return OktaProviderConfig(app_link=app_link, factor_type=factor_type)
示例#4
0
 def configure(mfa_enabled: bool = False) -> "BastionProviderConfig":
     config, c = ConfigManager(CONFIG_OVERRIDE_FILE_PATH), Utils.default_colors()
     profile = config.get_or_prompt(Config.Section.Bastion.PROFILE, BastionProviderConfig.get_profile)
     return BastionProviderConfig(profile_name=profile)
示例#5
0
 def __init__(self, color: Color = Color(False)):
     self.init_files()
     self.c = color
     self._config = ConfigManager(AWS_CONFIG_FILE_PATH)
     self._creds = ConfigManager(AWS_CREDENTIALS_FILE_PATH)
示例#6
0
class AWSConfig:
    """
    Utility methods for interacting with AWSCLI resources, such as the ~/.aws/credentials and ~/.aws/config files
    """
    def __init__(self, color: Color = Color(False)):
        self.init_files()
        self.c = color
        self._config = ConfigManager(AWS_CONFIG_FILE_PATH)
        self._creds = ConfigManager(AWS_CREDENTIALS_FILE_PATH)

    @staticmethod
    def init_files():
        os.makedirs(os.path.dirname(AWS_CREDENTIALS_FILE_PATH), exist_ok=True)

        if not os.path.exists(AWS_CREDENTIALS_FILE_PATH):
            with open(AWS_CREDENTIALS_FILE_PATH, "w+") as file:
                file.write("")

        if not os.path.exists(AWS_CONFIG_FILE_PATH):
            with open(AWS_CONFIG_FILE_PATH, "w+") as file:
                file.write("")

    def _is_temporary_session(self, profile_name: str):
        if self._creds.has_section(profile_name):
            return self._creds.has_option(profile_name, AWS_CFG_TOKEN)
        return False

    def _backup_section(self, section: str):
        backup_name, backup_profile = f'{section}-figgy-backup', f'profile {section}-figgy-backup'
        profile_name = f'profile {section}'
        if self._creds.has_section(section):
            for opt in self._creds.options(section):
                self._creds.set_config(backup_name, opt,
                                       self._creds.get_option(section, opt))

        if self._config.has_section(profile_name):
            for opt in self._config.options(profile_name):
                self._config.set_config(
                    backup_profile, opt,
                    self._config.get_option(profile_name, opt))

    def restore(self, profile_name: str):
        """
        Restore a credentials previously backed up by Figgy
        """
        config_profile = f'profile {profile_name}'
        backup_name, backup_profile = f'{profile_name}-figgy-backup', f'profile {profile_name}-figgy-backup'
        creds_restored, config_restored = False, False
        if self._creds.has_section(backup_name):
            for opt in self._creds.options(backup_name):
                self._creds.set_config(
                    profile_name, opt,
                    self._creds.get_option(backup_name, opt))
                creds_restored = True

        if self._config.has_section(backup_profile):
            for opt in self._config.options(backup_profile):
                self._config.set_config(
                    config_profile, opt,
                    self._config.get_option(backup_profile, opt))
                config_restored = True

        self._creds.delete(profile_name, AWS_CFG_TOKEN)
        self._creds.save()
        self._config.save()

        if creds_restored and config_restored:
            print(f"\n{self.c.fg_gr}Restoration successful!{self.c.rs}")
        else:
            print(
                f"\n{self.c.fg_yl}Unable to restore credentials. Profile: "
                f"{self.c.fg_bl}[{backup_name}]{self.c.rs}{self.c.fg_yl} was not found in either the "
                f"~/.aws/credentials or ~/.aws/config files.{self.c.rs}")

    def write_credentials(self,
                          access_key: str,
                          secret_key: str,
                          token: str,
                          region: str,
                          profile_name: str = 'default') -> None:
        """
        Overwrite credentials stored in the [default] profile in both ~/.aws/config and ~/.aws/credentials file
        with the provided temporary credentials. This method also CREATES these files if they do not already exist.
        """

        if not self._is_temporary_session(profile_name):
            print(
                f"\n{self.c.fg_yl}Existing AWS Profile {self.c.fg_bl}[{profile_name}]{self.c.rs}{self.c.fg_yl} "
                f"was found with long-lived access keys "
                f"in file: {self.c.fg_bl}~/.aws/credentials{self.c.rs}{self.c.fg_yl}.\n"
                f"To avoid overwriting these keys, they will be moved under profile: "
                f"{self.c.rs}{self.c.fg_bl}[{profile_name}-figgy-backup]{self.c.rs}{self.c.fg_yl}.{self.c.rs}\n\n"
                f"These old keys may be restored with: {self.c.fg_bl}`"
                f"{CLI_NAME} iam restore`{self.c.rs}.")
            self._backup_section(profile_name)

        self._creds.set_config(profile_name, AWS_CFG_ACCESS_KEY_ID, access_key)
        self._creds.set_config(profile_name, AWS_CFG_SECRET_KEY, secret_key)
        self._creds.set_config(profile_name, AWS_CFG_TOKEN, token)

        config_section = f'profile {profile_name}'
        self._config.set_config(config_section, AWS_CFG_REGION, region)
        self._config.set_config(config_section, AWS_CFG_OUTPUT, 'json')

        print(
            f"\n\n{self.c.fg_gr}Successfully updated: {AWS_CREDENTIALS_FILE_PATH}{self.c.rs}"
        )
        print(
            f"{self.c.fg_gr}Successfully updated: {AWS_CONFIG_FILE_PATH}{self.c.rs}"
        )
示例#7
0
    def login_sandbox(self):
        """
        If user provides --role flag, skip role & env selection for a smoother user experience.
        """
        EnvironmentValidator(self._defaults).validate_environment_variables()

        Utils.wipe_vaults() or Utils.wipe_defaults(
        ) or Utils.wipe_config_cache()

        self._out.print(
            f"{self.c.fg_bl}Logging you into the Figgy Sandbox environment.{self.c.rs}"
        )
        user = Input.input("Please input a user name: ", min_length=2)
        colors = Input.select_enable_colors()

        # Prompt user for role if --role not provided
        if commands.role not in self.context.options:
            role = Input.select("\n\nPlease select a role to impersonate: ",
                                valid_options=SANDBOX_ROLES)
        else:
            role = self.context.role.role
            self._utils.validate(
                role in SANDBOX_ROLES,
                f"Provided role: >>>`{role}`<<< is not a valid sandbox role."
                f" Please choose from {SANDBOX_ROLES}")

        params = {'role': role, 'user': user}
        result = requests.get(GET_SANDBOX_CREDS_URL, params=params)

        if result.status_code != 200:
            self._utils.error_exit(
                "Unable to get temporary credentials from the Figgy sandbox. If this problem "
                f"persists please notify us on our GITHUB: {FIGGY_GITHUB}")

        data = result.json()
        response = SandboxLoginResponse(**data)
        self._aws_cfg.write_credentials(
            access_key=response.AWS_ACCESS_KEY_ID,
            secret_key=response.AWS_SECRET_ACCESS_KEY,
            token=response.AWS_SESSION_TOKEN,
            region=FIGGY_SANDBOX_REGION,
            profile_name=FIGGY_SANDBOX_PROFILE)

        defaults = CLIDefaults.sandbox(user=user, role=role, colors=colors)
        self._setup.save_defaults(defaults)

        run_env = RunEnv(
            env='dev',
            account_id=SANDBOX_DEV_ACCOUNT_ID) if self.context.role else None

        config_mgr = ConfigManager.figgy()
        config_mgr.set(Config.Section.Bastion.PROFILE, FIGGY_SANDBOX_PROFILE)
        defaults = self._setup.configure_extras(defaults)
        defaults = self._setup.configure_roles(current_defaults=defaults,
                                               role=Role(role=role),
                                               run_env=run_env)
        defaults = self._setup.configure_figgy_defaults(defaults)
        self._setup.save_defaults(defaults)

        self._out.success(
            f"\nLogin successful. Your sandbox session will last for [[1 hour]]."
        )

        self._out.print(
            f"\nIf your session expires, you may rerun `{CLI_NAME} login sandbox` to get another sandbox session. "
            f"\nAll previous figgy sessions have been disabled, you'll need to run {CLI_NAME} "
            f"--configure to leave the sandbox.")