Esempio n. 1
0
class TestConfig(unittest.TestCase):
    """Class to test Config Class.
       Mock is used to mock external calls"""
    def setUp(self):
        """Set up for the unit tests"""
        self.config = Config(ui=ui.cli)

    def tearDown(self):
        """Run Clean Up"""
        self.config.clean_up()

    @patch(
        "argparse.ArgumentParser.parse_args",
        return_value=argparse.Namespace(
            username="******",
            profile=None,
            insecure=False,
            resolve=None,
            mfa_code=None,
            remember_device=False,
            output_format=None,
            roles=None,
            action_register_device=False,
            action_configure=False,
            action_list_profiles=False,
            action_list_roles=False,
            action_store_json_creds=False,
        ),
    )
    def test_get_args_username(self, mock_arg):
        """Test to make sure username gets returned"""
        self.config.get_args()
        assert_equals(self.config.username, "ann")
Esempio n. 2
0
class TestConfig(unittest.TestCase):
    """Class to test Config Class.
       Mock is used to mock external calls"""

    def setUp(self):
        """Set up for the unit tests"""
        self.config = Config()

    def tearDown(self):
        """Run Clean Up"""
        self.config.clean_up()

    @patch('argparse.ArgumentParser.parse_args',
           return_value=argparse.Namespace(username='******', configure=False, profile=None, insecure=False, resolve=None, mfa_code=None, register_device=False))
    def test_get_args_username(self, mock_arg):
        """Test to make sure username gets returned"""
        self.config.get_args()
        assert_equals(self.config.username, 'ann')
Esempio n. 3
0
    def run(self):
        """ Pulling it all together to make the CLI """
        config = Config()
        config.get_args()
        # Create/Update config when configure arg set
        if config.configure is True:
            config.update_config_file()
            exit()

        # get the config dict
        conf_dict = config.get_config_dict()

        if not conf_dict.get('okta_org_url'):
            print(
                'No Okta organization URL in configuration.  Try running --config again.'
            )
            exit(1)

        if not conf_dict.get('gimme_creds_server'):
            print(
                'No Gimme-Creds server URL in configuration.  Try running --config again.'
            )
            exit(1)

        okta = OktaClient(conf_dict['okta_org_url'], config.verify_ssl_certs)
        if config.resolve == True:
            self.resolver = AwsResolver(config.verify_ssl_certs)
        else:
            if conf_dict.get('resolve_aws_alias') and str(
                    conf_dict['resolve_aws_alias']) == 'True':
                self.resolver = AwsResolver(config.verify_ssl_certs)

        if config.username is not None:
            okta.set_username(config.username)
        else:
            if conf_dict.get('okta_username'):
                okta.set_username(conf_dict['okta_username'])

        if conf_dict.get('preferred_mfa_type'):
            okta.set_preferred_mfa_type(conf_dict['preferred_mfa_type'])

        if config.mfa_code is not None:
            okta.set_mfa_code(config.mfa_code)

        # AWS Default session duration ....
        if conf_dict.get('aws_default_duration'):
            config.aws_default_duration = int(
                conf_dict['aws_default_duration'])
        else:
            config.aws_default_duration = 3600

        # Call the Okta APIs and proces data locally
        if conf_dict.get('gimme_creds_server') == 'internal':
            # Okta API key is required when calling Okta APIs internally
            if config.api_key is None:
                print('OKTA_API_KEY environment variable not found!')
                exit(1)
            # Authenticate with Okta
            auth_result = okta.auth_session()

            print("Authentication Success! Getting AWS Accounts")
            aws_results = self._get_aws_account_info(conf_dict['okta_org_url'],
                                                     config.api_key,
                                                     auth_result['username'])

        elif conf_dict.get('gimme_creds_server') == 'appurl':
            # bypass lambda & API call
            # Apps url is required when calling with appurl
            if conf_dict.get('app_url'):
                config.app_url = conf_dict['app_url']
            if config.app_url is None:
                print('app_url is not defined in your config !')
                exit(1)

            # Authenticate with Okta
            auth_result = okta.auth_session()
            print("Authentication Success! Getting AWS Accounts")

            # build app list
            aws_results = []
            newAppEntry = {}
            newAppEntry['id'] = "fakeid"  # not used anyway
            newAppEntry['name'] = "fakelabel"  #not used anyway
            newAppEntry['links'] = {}
            newAppEntry['links']['appLink'] = config.app_url
            aws_results.append(newAppEntry)

        # Use the gimme_creds_lambda service
        else:
            if not conf_dict.get('client_id'):
                print(
                    'No OAuth Client ID in configuration.  Try running --config again.'
                )
            if not conf_dict.get('okta_auth_server'):
                print(
                    'No OAuth Authorization server in configuration.  Try running --config again.'
                )

            # Authenticate with Okta and get an OAuth access token
            okta.auth_oauth(conf_dict['client_id'],
                            authorization_server=conf_dict['okta_auth_server'],
                            access_token=True,
                            id_token=False,
                            scopes=['openid'])

            # Add Access Tokens to Okta-protected requests
            okta.use_oauth_access_token(True)

            print("Authentication Success! Calling Gimme-Creds Server...")
            aws_results = self._call_gimme_creds_server(
                okta, conf_dict['gimme_creds_server'])

        aws_app = self._get_selected_app(conf_dict.get('aws_appname'),
                                         aws_results)
        saml_data = okta.get_saml_response(aws_app['links']['appLink'])
        # aws_signin_page = aws_signin.get_signinpage(saml_data['SAMLResponse'])
        roles = self.resolver._enumerate_saml_roles(saml_data['SAMLResponse'],
                                                    saml_data['TargetUrl'])
        aws_role = self._get_selected_role(conf_dict.get('aws_rolename'),
                                           roles)
        aws_partition = self._get_partition_from_saml_acs(
            saml_data['TargetUrl'])

        for _, role in enumerate(roles):
            # Skip irrelevant roles
            if aws_role != 'all' and aws_role not in role.role:
                continue

            try:
                aws_creds = self._get_sts_creds(aws_partition,
                                                saml_data['SAMLResponse'],
                                                role.idp, role.role,
                                                config.aws_default_duration)
            except ClientError as ex:
                if ex.response['Error'][
                        'Message'] == 'The requested DurationSeconds exceeds the MaxSessionDuration set for this role.':
                    print(
                        "The requested session duration was too long for this role.  Falling back to 1 hour."
                    )
                    aws_creds = self._get_sts_creds(aws_partition,
                                                    saml_data['SAMLResponse'],
                                                    role.idp, role.role, 3600)

            deriv_profname = re.sub('arn:aws:iam:.*/', '', role.role)

            # check if write_aws_creds is true if so
            # get the profile name and write out the file
            if str(conf_dict['write_aws_creds']) == 'True':
                # set the profile name
                # Note if there are multiple roles, and 'default' is
                # selected it will be overwritten multiple times and last role
                # wins.
                if conf_dict['cred_profile'].lower() == 'default':
                    profile_name = 'default'
                elif conf_dict['cred_profile'].lower() == 'role':
                    profile_name = deriv_profname
                else:
                    profile_name = conf_dict['cred_profile']

                # Write out the AWS Config file
                print('writing role {} to {}'.format(role.role,
                                                     self.AWS_CONFIG))
                self._write_aws_creds(profile_name, aws_creds['AccessKeyId'],
                                      aws_creds['SecretAccessKey'],
                                      aws_creds['SessionToken'])
            else:
                #Print out temporary AWS credentials.  Credentials are printed to stderr to simplify
                #redirection for use in automated scripts
                print("export AWS_ACCESS_KEY_ID=" + aws_creds['AccessKeyId'],
                      file=sys.stderr)
                print("export AWS_SECRET_ACCESS_KEY=" +
                      aws_creds['SecretAccessKey'],
                      file=sys.stderr)
                print("export AWS_SESSION_TOKEN=" + aws_creds['SessionToken'],
                      file=sys.stderr)
                print("export AWS_SECURITY_TOKEN=" + aws_creds['SessionToken'],
                      file=sys.stderr)

        config.clean_up()
Esempio n. 4
0
    def run(self):
        """ Pulling it all together to make the CLI """
        config = Config()
        config.get_args()
        # Create/Update config when configure arg set
        if config.configure is True:
            config.update_config_file()
            exit()

        # get the config dict
        conf_dict = config.get_config_dict()

        if not conf_dict.get('okta_org_url'):
            print(
                'No Okta organization URL in configuration.  Try running --config again.'
            )
            exit(1)

        if not conf_dict.get('gimme_creds_server'):
            print(
                'No Gimme-Creds server URL in configuration.  Try running --config again.'
            )
            exit(1)

        okta = OktaClient(conf_dict['okta_org_url'], config.verify_ssl_certs)

        if config.username is not None:
            okta.set_username(config.username)
        else:
            if conf_dict.get('okta_username'):
                okta.set_username(conf_dict['okta_username'])

        # Call the Okta APIs and proces data locally
        if conf_dict.get('gimme_creds_server') == 'internal':
            # Okta API key is required when calling Okta APIs internally
            if config.api_key is None:
                print('OKTA_API_KEY environment variable not found!')
                exit(1)
            # Authenticate with Okta
            auth_result = okta.auth_session()

            print("Authentication Success! Getting AWS Accounts")
            aws_results = self._get_aws_account_info(conf_dict['okta_org_url'],
                                                     config.api_key,
                                                     auth_result['username'])

        # Use the gimme_creds_lambda service
        else:
            if not conf_dict.get('client_id'):
                print(
                    'No OAuth Client ID in configuration.  Try running --config again.'
                )
            if not conf_dict.get('okta_auth_server'):
                print(
                    'No OAuth Authorization server in configuration.  Try running --config again.'
                )

            # Authenticate with Okta and get an OAuth access token
            okta.auth_oauth(conf_dict['client_id'],
                            authorization_server=conf_dict['okta_auth_server'],
                            access_token=True,
                            id_token=False,
                            scopes=['openid'])

            # Add Access Tokens to Okta-protected requests
            okta.use_oauth_access_token(True)

            print("Authentication Success! Calling Gimme-Creds Server...")
            aws_results = self._call_gimme_creds_server(
                okta, conf_dict['gimme_creds_server'])

        aws_app = self._get_selected_app(conf_dict.get('aws_appname'),
                                         aws_results)
        saml_data = okta.get_saml_response(aws_app['links']['appLink'])
        roles = self._enumerate_saml_roles(saml_data['SAMLResponse'])
        aws_role = self._get_selected_role(conf_dict.get('aws_rolename'),
                                           roles)
        aws_partition = self._get_partition_from_saml_acs(
            saml_data['TargetUrl'])

        for _, role in enumerate(roles):
            # Skip irrelevant roles
            if aws_role != 'all' and aws_role not in role.role:
                continue

            aws_creds = self._get_sts_creds(aws_partition,
                                            saml_data['SAMLResponse'],
                                            role.idp, role.role)
            deriv_profname = re.sub('arn:aws:iam:.*/', '', role.role)

            # check if write_aws_creds is true if so
            # get the profile name and write out the file
            if str(conf_dict['write_aws_creds']) == 'True':
                # set the profile name
                # Note if there are multiple roles, and 'default' is
                # selected it will be overwritten multiple times and last role
                # wins.
                if conf_dict['cred_profile'].lower() == 'default':
                    profile_name = 'default'
                elif conf_dict['cred_profile'].lower() == 'role':
                    profile_name = deriv_profname
                else:
                    profile_name = conf_dict['cred_profile']

                # Write out the AWS Config file
                print('writing role {} to {}'.format(role.role,
                                                     self.AWS_CONFIG))
                self._write_aws_creds(profile_name, aws_creds['AccessKeyId'],
                                      aws_creds['SecretAccessKey'],
                                      aws_creds['SessionToken'])
            else:
                #Print out temporary AWS credentials.  Credentials are printed to stderr to simplify
                #redirection for use in automated scripts
                print("export AWS_ACCESS_KEY_ID=" + aws_creds['AccessKeyId'],
                      file=sys.stderr)
                print("export AWS_SECRET_ACCESS_KEY=" +
                      aws_creds['SecretAccessKey'],
                      file=sys.stderr)
                print("export AWS_SESSION_TOKEN=" + aws_creds['SessionToken'],
                      file=sys.stderr)

        config.clean_up()
Esempio n. 5
0
class TestConfig(unittest.TestCase):
    """Class to test Config Class.
       Mock is used to mock external calls"""
    def setUp(self):
        """Set up for the unit tests"""
        self.config = Config(gac_ui=ui.cli, create_config=False)

    def tearDown(self):
        """Run Clean Up"""
        self.config.clean_up()

    @patch(
        "argparse.ArgumentParser.parse_args",
        return_value=argparse.Namespace(
            username="******",
            profile=None,
            insecure=False,
            resolve=None,
            mfa_code=None,
            remember_device=False,
            output_format=None,
            roles=None,
            action_register_device=False,
            action_configure=False,
            action_list_profiles=False,
            action_list_roles=False,
            action_store_json_creds=False,
        ),
    )
    def test_get_args_username(self, mock_arg):
        """Test to make sure username gets returned"""
        self.config.get_args()
        assert_equals(self.config.username, "ann")

    def test_read_config(self):
        """Test to make sure getting config works"""
        test_ui = MockUserInterface(argv=[
            "--profile",
            "myprofile",
        ])
        with open(test_ui.HOME + "/.okta_aws_login_config",
                  "w") as config_file:
            config_file.write("""
[myprofile]
client_id = foo
""")
        config = Config(gac_ui=test_ui, create_config=False)
        config.conf_profile = "myprofile"
        profile_config = config.get_config_dict()
        self.assertEqual(profile_config, {"client_id": "foo"})

    def test_read_config_inherited(self):
        """Test to make sure getting config works when inherited"""
        test_ui = MockUserInterface(argv=[
            "--profile",
            "myprofile",
        ])
        with open(test_ui.HOME + "/.okta_aws_login_config",
                  "w") as config_file:
            config_file.write("""
[mybase]
client_id = bar
aws_appname = baz
[myprofile]
inherits = mybase
client_id = foo
aws_rolename = myrole
""")
        config = Config(gac_ui=test_ui, create_config=False)
        config.conf_profile = "myprofile"
        profile_config = config.get_config_dict()
        self.assertEqual(profile_config, {
            "client_id": "foo",
            "aws_appname": "baz",
            "aws_rolename": "myrole",
        })

    def test_read_nested_config_inherited(self):
        """Test to make sure getting config works when inherited"""
        test_ui = MockUserInterface(argv=[
            "--profile",
            "myprofile",
        ])
        with open(test_ui.HOME + "/.okta_aws_login_config",
                  "w") as config_file:
            config_file.write("""
[mybase-level1]
client_id = bar
[mybase-level2]
inherits = mybase-level1
aws_appname = baz
[myprofile]
inherits = mybase-level2
client_id = foo
aws_rolename = myrole
""")
        config = Config(gac_ui=test_ui, create_config=False)
        config.conf_profile = "myprofile"
        profile_config = config.get_config_dict()
        self.assertEqual(profile_config, {
            "client_id": "foo",
            "aws_appname": "baz",
            "aws_rolename": "myrole",
        })