def test_set_role(self): assertion = mock.Mock() assertion.roles.return_value = [{"role": "", "principle": ""}] session = aws.Session("BogusAssertion") session.assertion = assertion session.set_role("0") self.assertEquals("", session.role["role"])
def test_assume_role_multiple(self, mock_write): mock_write.return_value = None assertion = mock.Mock() roles = [{ "role": "1", "principle": "" }, { "role": "2", "principle": "" }] assertion.roles.return_value = roles session = aws.Session("BogusAssertion") session.assertion = assertion sts = { "Credentials": { "AccessKeyId": "AKI", "SecretAccessKey": "squirrel", "SessionToken": "token", "Expiration": "never", } } session.sts = mock.Mock() session.sts.assume_role_with_saml.return_value = sts with self.assertRaises(aws.MultipleRoles): session.assume_role()
def test_set_role(self): assertion = mock.Mock() assertion.roles.return_value = [{'role': '', 'principle': ''}] session = aws.Session('BogusAssertion') session.assertion = assertion session.set_role('0') self.assertEquals('', session.role['role'])
def test_assume_role(self, mock_write): mock_write.return_value = None assertion = mock.Mock() assertion.roles.return_value = [{"role": "", "principle": ""}] session = aws.Session("BogusAssertion") session.assertion = assertion sts = { "Credentials": { "AccessKeyId": "AKI", "SecretAccessKey": "squirrel", "SessionToken": "token", "Expiration": "never", } } session.sts = mock.Mock() session.sts.assume_role_with_saml.return_value = sts ret = session.assume_role() self.assertEquals(None, ret) self.assertEquals("AKI", session.aws_access_key_id) self.assertEquals("squirrel", session.aws_secret_access_key) self.assertEquals("token", session.session_token) self.assertEquals("never", session.expiration) # Verify _write is called correctly mock_write.assert_has_calls([mock.call()])
def test_assume_role_multiple(self, mock_write): mock_write.return_value = None assertion = mock.Mock() roles = [{ 'role': '1', 'principle': '' }, { 'role': '2', 'principle': '' }] assertion.roles.return_value = roles session = aws.Session('BogusAssertion') session.assertion = assertion sts = { 'Credentials': { 'AccessKeyId': 'AKI', 'SecretAccessKey': 'squirrel', 'SessionToken': 'token', 'Expiration': 'never' } } session.sts = mock.Mock() session.sts.assume_role_with_saml.return_value = sts with self.assertRaises(aws.MultipleRoles): session.assume_role()
def test_assume_role(self, mock_write): mock_write.return_value = None assertion = mock.Mock() assertion.roles.return_value = [{'role': '', 'principle': ''}] session = aws.Session('BogusAssertion') session.assertion = assertion sts = { 'Credentials': { 'AccessKeyId': 'AKI', 'SecretAccessKey': 'squirrel', 'SessionToken': 'token', 'Expiration': 'never' } } session.sts = mock.Mock() session.sts.assume_role_with_saml.return_value = sts ret = session.assume_role() self.assertEquals(None, ret) self.assertEquals('AKI', session.aws_access_key_id) self.assertEquals('squirrel', session.aws_secret_access_key) self.assertEquals('token', session.session_token) self.assertEquals('never', session.expiration) # Verify _write is called correctly mock_write.assert_has_calls([mock.call()])
def test_is_valid_false_missing_expiration(self): session = aws.Session("BogusAssertion") # Set expiration to None like we failed to set the value session.expiration = None # Should return False - the time comparison isn't possible if # expiration hasn't been set yet. ret = session.is_valid self.assertEquals(False, ret)
def test_available_roles(self): assertion = mock.Mock() roles = [{ "role": "1", "principle": "" }, { "role": "2", "principle": "" }] assertion.roles.return_value = roles session = aws.Session("BogusAssertion") session.assertion = assertion result = session.available_roles() self.assertEquals(roles, result)
def test_available_roles(self): assertion = mock.Mock() roles = [{ 'role': '1', 'principle': '' }, { 'role': '2', 'principle': '' }] assertion.roles.return_value = roles session = aws.Session('BogusAssertion') session.assertion = assertion result = session.available_roles() self.assertEquals(roles, result)
def test_write(self, mock_add_profile): session = aws.Session('BogusAssertion') ret = session._write() self.assertEquals(None, ret) # Verify add_profile is called with the correct args mock_add_profile.assert_has_calls([ mock.call(access_key=None, name='default', region='us-east-1', secret_key=None, session_token=None) ])
def test_is_valid_false(self): session = aws.Session("BogusAssertion") # Mock out the expiration time to 4:10PM UTC expir_mock = datetime.datetime(2017, 7, 25, 16, 10, 00, 000000) # Now set our current time to 4:05PM UTC mock_now = datetime.datetime(2017, 7, 25, 16, 4, 00, 000000) # Should return False - less than 600 seconds away from expiration with mock.patch("datetime.datetime") as dt_mock: dt_mock.utcnow.return_value = mock_now dt_mock.strptime.return_value = expir_mock ret = session.is_valid self.assertEquals(False, ret)
def test_is_valid_true(self): session = aws.Session("BogusAssertion") # Mock out the expiration time to 4:10PM UTC expir_mock = datetime.datetime(2017, 7, 25, 16, 10, 00, 000000) # Now set our current time to 3:55PM UTC mock_now = datetime.datetime(2017, 7, 25, 15, 55, 00, 000000) # Should return True - more than 600 seconds to expiration with mock.patch("datetime.datetime") as dt_mock: dt_mock.utcnow.return_value = mock_now dt_mock.strptime.return_value = expir_mock ret = session.is_valid self.assertEquals(True, ret)
def main(argv): # Generate our logger first, and write out our app name and version log = setup_logging() log.info('%s v%s' % (__desc__, __version__)) # Get our configuration object based on the CLI options. This handles # parsing arguments and ensuring the user supplied the required params. config = get_config_parser(argv) if config.debug: log.setLevel(logging.DEBUG) # Ask the user for their password.. we do this once at the beginning, and # we keep it in memory for as long as this tool is running. Its never ever # written out or cached to disk anywhere. password = getpass.getpass() # Generate our initial OktaSaml client and handle any exceptions thrown. # Generally these are input validation issues. try: okta_client = okta.OktaSaml(config.org, config.username, password) except okta.EmptyInput: log.error('Cannot enter a blank string for any input') sys.exit(1) # Authenticate the Okta client. If necessary, we will ask for MFA input. try: okta_client.auth() except okta.InvalidPassword: log.error('Invalid Username ({user}) or Password'.format( user=config.username)) sys.exit(1) except okta.PasscodeRequired as e: log.warning('MFA Requirement Detected - Enter your passcode here') verified = False while not verified: passcode = getpass.getpass('MFA Passcode: ') verified = okta_client.validate_mfa(e.fid, e.state_token, passcode) # Once we're authenticated with an OktaSaml client object, we can use that # object to get a fresh SAMLResponse repeatedly and refresh our AWS # Credentials. session = None while True: # If an AWS Session object has been created already, lets check if its # still valid. If it is, sleep a bit and skip to the next execution of # the loop. if session and session.is_valid: log.debug('Credentials are still valid, sleepingt') time.sleep(15) continue log.info('Getting SAML Assertion from {org}'.format(org=config.org)) try: assertion = okta_client.get_assertion(appid=config.appid, apptype='amazon_aws') session = aws.Session(assertion, profile=config.name) session.assume_role() except requests.exceptions.ConnectionError as e: log.warning('Connection error... will retry') time.sleep(5) continue # If we're not running in re-up mode, once we have the assertion # and creds, go ahead and quit. if not config.reup: break time.sleep(5)
def test_assume_role_bad_assertion_raises_invalidsaml(self): session = aws.Session("BogusAssertion") with self.assertRaises(aws.InvalidSaml): session.assume_role()
def main(argv): # Generate our logger first, and write out our app name and version log = setup_logging() log.info('%s v%s' % (__desc__, __version__)) # Get our configuration object based on the CLI options. This handles # parsing arguments and ensuring the user supplied the required params. config = get_config_parser(argv) if config.debug: log.setLevel(logging.DEBUG) # Ask the user for their password.. we do this once at the beginning, and # we keep it in memory for as long as this tool is running. Its never ever # written out or cached to disk anywhere. password = getpass.getpass() # Generate our initial OktaSaml client and handle any exceptions thrown. # Generally these are input validation issues. try: okta_client = okta.OktaSaml(config.org, config.username, password) except okta.EmptyInput: log.error('Cannot enter a blank string for any input') sys.exit(1) # Authenticate the Okta client. If necessary, we will ask for MFA input. try: okta_client.auth() except okta.InvalidPassword: log.error('Invalid Username ({user}) or Password'.format( user=config.username)) sys.exit(1) except okta.ExhaustedFactors as e: log.error(e.message) sys.exit(1) # Once we're authenticated with an OktaSaml client object, we can use that # object to get a fresh SAMLResponse repeatedly and refresh our AWS # Credentials. session = None role_selection = None while True: # If an AWS Session object has been created already, lets check if its # still valid. If it is, sleep a bit and skip to the next execution of # the loop. if session and session.is_valid: log.debug('Credentials are still valid, sleeping') time.sleep(15) continue log.info('Getting SAML Assertion from {org}'.format(org=config.org)) try: assertion = okta_client.get_assertion(appid=config.appid, apptype='amazon_aws') session = aws.Session(assertion, profile=config.name) # If role_selection is set we're in a reup loop. Re-set the role on # the session to prevent the user being prompted for the role again # on each subsequent renewal. if role_selection is not None: session.set_role(role_selection) session.assume_role() except aws.MultipleRoles: log.warning('Multiple AWS roles found; please select one') roles = session.available_roles() for role_index, role in enumerate(roles): print("[{}] Role: {}".format(role_index, role["role"])) role_selection = user_input('Select a role from above: ') session.set_role(role_selection) session.assume_role() except requests.exceptions.ConnectionError: log.warning('Connection error... will retry') time.sleep(5) continue # If we're not running in re-up mode, once we have the assertion # and creds, go ahead and quit. if not config.reup: break log.info('Reup enabled, sleeping...') time.sleep(5)
def login( aws_profile: str, okta_appid: str, okta_org: str, username: str, reup: bool, debug: bool = False, ): # Generate our logger first, and write out our app name and version log = setup_logging() log.info("%s v%s" % (__desc__, __version__)) if debug: log.setLevel(logging.DEBUG) # Ask the user for their password.. we do this once at the beginning, and # we keep it in memory for as long as this tool is running. Its never ever # written out or cached to disk anywhere. password = getpass.getpass() # Generate our initial OktaSaml client and handle any exceptions thrown. # Generally these are input validation issues. try: okta_client = okta.OktaSaml(okta_org, username, password) except okta.EmptyInput: log.error("Cannot enter a blank string for any input") raise # Authenticate the Okta client. If necessary, we will ask for MFA input. try: okta_client.auth() except okta.InvalidPassword: log.error( "Invalid Username ({user}) or Password".format(user=username)) raise except okta.ExhaustedFactors as e: log.error(e) raise # Once we're authenticated with an OktaSaml client object, we can use that # object to get a fresh SAMLResponse repeatedly and refresh our AWS # Credentials. session = None role_selection = None while True: # If an AWS Session object has been created already, lets check if its # still valid. If it is, sleep a bit and skip to the next execution of # the loop. if session and session.is_valid: log.debug("Credentials are still valid, sleeping") time.sleep(15) continue log.info("Getting SAML Assertion from {org}".format(org=okta_org)) try: assertion = okta_client.get_assertion(appid=okta_appid, apptype="amazon_aws") session = aws.Session(assertion, profile=aws_profile) # If role_selection is set we're in a reup loop. Re-set the role on # the session to prevent the user being prompted for the role again # on each subsequent renewal. if role_selection is not None: session.set_role(role_selection) session.assume_role() except aws.MultipleRoles: log.warning("Multiple AWS roles found; please select one") roles = session.available_roles() for role_index, role in enumerate(roles): print("[{}] Role: {}".format(role_index, role["role"])) role_selection = user_input("Select a role from above: ") session.set_role(role_selection) session.assume_role() except requests.exceptions.ConnectionError: log.warning("Connection error... will retry") time.sleep(5) continue # If we're not running in re-up mode, once we have the assertion # and creds, go ahead and quit. if not reup: break log.info("Reup enabled, sleeping...") time.sleep(5)