Skip to content

Commit

Permalink
Automate prompt for mfa, app, role selections
Browse files Browse the repository at this point in the history
  • Loading branch information
odg0318 committed Jun 18, 2022
1 parent 9606411 commit 02639fa
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ A configuration wizard will prompt you to enter the necessary configuration para
- sms - OTP via SMS message
- web - DUO uses localhost webbrowser to support push|call|passcode
- passcode - DUO uses `OKTA_MFA_CODE` or `--mfa-code` if set, or prompts user for passcode(OTP).
preffered_mfa_provider - automatically select a mfa provider when prompted for MFA

- resolve_aws_alias - y or n. If yes, gimme-aws-creds will try to resolve AWS account ids with respective alias names (default: n). This option can also be set interactively in the command line using `-r` or `--resolve` parameter
- include_path - (optional) Includes full role path to the role name in AWS credential profile name. (default: n). If `y`: `<acct>-/some/path/administrator`. If `n`: `<acct>-administrator`
Expand Down
11 changes: 10 additions & 1 deletion gimme_aws_creds/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def __init__(self, gac_ui, create_config=True):
self.action_output_format = False
self.output_format = 'export'
self.roles = []
self.okta_app = None
self.okta_role = None

if self.ui.environ.get("OKTA_USERNAME") is not None:
self.username = self.ui.environ.get("OKTA_USERNAME")
Expand Down Expand Up @@ -145,6 +147,8 @@ def get_args(self):
'--action-setup-fido-authenticator', action='store_true',
help='Sets up a new FIDO WebAuthn authenticator in Okta'
)
parser.add_argument('--okta-app', type=int)
parser.add_argument('--okta-role', type=int)
args = parser.parse_args(self.ui.args)

self.action_configure = args.action_configure
Expand Down Expand Up @@ -173,6 +177,11 @@ def get_args(self):
self.output_format = args.output_format
if args.roles is not None:
self.roles = [role.strip() for role in args.roles.split(',') if role.strip()]
if args.okta_app is not None:
self.okta_app = args.okta_app
if args.okta_role is not None:
self.okta_role = args.okta_role

self.conf_profile = args.profile or 'DEFAULT'

def _handle_config(self, config, profile_config, include_inherits = True):
Expand Down Expand Up @@ -578,4 +587,4 @@ def fail_if_profile_not_found(self, profile_config, conf_profile, default_sectio
"""
if not profile_config and conf_profile == default_section:
raise errors.GimmeAWSCredsError(
'DEFAULT profile is missing! This is profile is required when not using --profile')
'DEFAULT profile is missing! This is profile is required when not using --profile')
11 changes: 11 additions & 0 deletions gimme_aws_creds/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ def _choose_app(self, aws_info):
if len(aws_info) == 1:
return aws_info[0] # auto select when only 1 choice

if self.config.okta_app is not None:
self.ui.info("Detected app in config: {}".format(aws_info[self.config.okta_app]['name']))
return aws_info[self.config.okta_app]

app_strs = []
for i, app in enumerate(aws_info):
app_strs.append('[{}] {}'.format(i, app["name"]))
Expand Down Expand Up @@ -415,6 +419,10 @@ def _choose_roles(self, roles):
self.ui.info("Detected single role: {}".format(single_role))
return {single_role}

if self.config.okta_role is not None:
self.ui.info("Detected role in config: {}".format(roles[self.config.okta_role].role))
return {roles[self.config.okta_role].role}

# Gather the roles available to the user.
role_strs = self.resolver._display_role(roles)

Expand Down Expand Up @@ -549,6 +557,9 @@ def okta(self):
if self.conf_dict.get('preferred_mfa_type'):
okta.set_preferred_mfa_type(self.conf_dict['preferred_mfa_type'])

if self.conf_dict.get('preffered_mfa_provider'):
okta.set_preferred_mfa_provider(self.conf_dict['preffered_mfa_provider'])

if self.config.mfa_code is not None:
okta.set_mfa_code(self.config.mfa_code)
elif self.conf_dict.get('okta_mfa_code'):
Expand Down
9 changes: 8 additions & 1 deletion gimme_aws_creds/okta.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def __init__(self, gac_ui, okta_org_url, verify_ssl_certs=True, device_token=Non
self._username = None
self._password = None
self._preferred_mfa_type = None
self._preferred_mfa_provider = None
self._mfa_code = None
self._remember_device = None

Expand Down Expand Up @@ -102,6 +103,9 @@ def set_password(self, password):
def set_preferred_mfa_type(self, preferred_mfa_type):
self._preferred_mfa_type = preferred_mfa_type

def set_preferred_mfa_provider(self, preferred_mfa_provider):
self._preferred_mfa_provider = preferred_mfa_provider

def set_mfa_code(self, mfa_code):
self._mfa_code = mfa_code

Expand Down Expand Up @@ -787,6 +791,9 @@ def _choose_factor(self, factors):
factor_name = self._build_factor_name(preferred_factors[0])
self.ui.info(factor_name + ' selected')
selection = factors.index(preferred_factors[0])
elif self._preferred_mfa_provider is not None:
self.ui.info('Detected preferred provider in config: {}'.format(self._preferred_mfa_provider))
selection = factors.index([v for v in factors if v['provider'] == self._preferred_mfa_provider][0])
else:
self.ui.info("Pick a factor:")
# print out the factors and let the user select
Expand Down Expand Up @@ -1028,7 +1035,7 @@ def _introspect_factors(self, state_token):
@staticmethod
def _extract_state_token_from_http_response(http_res):
saml_soup = BeautifulSoup(http_res.text, "html.parser")

mfa_string = (
'Dodatečné ověření',
'Ekstra verificering',
Expand Down

0 comments on commit 02639fa

Please sign in to comment.