def run(self): assert_listen_port_is_available(self.listen_port) self.request_authorization() if self.tokens: json.dump(self.tokens, stdout) else: fatal('no token retrieved')
def cli(verbose, configuration): logging.basicConfig(format='%(levelname)s:%(message)s', level=(logging.DEBUG if verbose else logging.INFO)) setting.filename = '.pkce-login' setting.SECTION = configuration if not setting.exists: fatal('no configuration %s found in .pcke-login', configuration)
def get_cognito_credentials_for_identity(self, identity: str, role_arn: str) -> AWSCredentials: if not role_arn or role_arn not in self.roles: available_roles = ', '.join(self.roles.keys()) fatal( f'Role {role_arn} not granted, choose one of {available_roles}' ) cognito = boto3.client('cognito-identity') try: # TODO: find out why this does not work. response = cognito.get_credentials_for_identity( IdentityId=identity, CustomRoleArn=role_arn, Logins={self.roles[role_arn]: self.saml_response}) except ClientError as e: fatal( f'failed to get credentials for identity {identity} in role {role_arn}, %s', e) c = response['Credentials'] return AWSCredentials(access_key=c['AccessKeyId'], secret_key=c['SecretKey'], session_token=c['SessionToken'], expiration=c['Expiration'])
def run(self): assert_listen_port_is_available(self.listen_port) self.request_authorization() if self.saml_response: print(self.saml_response) else: fatal('no SAML response retrieved')
def get_cognito_id(self, account: str, identity_pool: str) -> str: provider = self.roles.get(next(iter(self.roles.keys()), None)) cognito = boto3.client('cognito-identity') try: response = cognito.get_id(IdentityPoolId=identity_pool, Logins={provider: self.saml_response}) return response['IdentityId'] except ClientError as e: fatal('failed to get cognito identity from {identity_pool}, %s', e)
def run(self): if not (self.account and self.role and self.profile): fatal('--account, --role and --profile are required.') self.request_authorization() credentials = self.saml_response.assume_role(self.role_arn, setting.ROLE_DURATION) write_aws_credentials(credentials, self.profile) if self.open_console: open_aws_console(self.profile)
def available_roles(self) -> List[AvailableRole]: result = [] for role in self.roles: match = self.role_arn_pattern.match(role) if match: result.append( AvailableRole(arn=role, provider=self.roles[role], account=match.group('account'), name=match.group('name'))) else: fatal('expected a role arn, found %s', role) return result
def parse_xml_response(saml_response: str) -> ElementTree.Element: """ returns the XML root node of the SAML response, as returned by the SAML idp. """ result = None try: xml = base64.b64decode(saml_response) logging.debug(xml) result = ElementTree.fromstring(xml) except binascii.Error as e: fatal('failed to parse the SAML response, %s', e) except ElementTree.ParseError as e: fatal('failed to parse the SAML response, %s', e.msg) return result
def get_statements( root: ElementTree.Element) -> List[Dict[str, List[str]]]: """ returns all SAML attribute values from the saml_response. """ statements = [] for statement in root.findall('.//saml:AttributeStatement', AWSSAMLAssertion.namespaces): if isinstance(statement, ElementTree.Element): statements.append(AWSSAMLAssertion.get_attributes(statement)) else: fatal( 'malformed XML: AttributeStatement {statement} is not a XML element' ) return statements
def assume_role(self, role_arn: str, duration: int = 3600) -> AWSCredentials: if not role_arn or role_arn not in self.roles: available_roles = ', '.join(self.roles.keys()) fatal( f'Role {role_arn} not granted, choose one of {available_roles}' ) sts = boto3.client('sts') try: response = sts.assume_role_with_saml( RoleArn=role_arn, PrincipalArn=self.roles[role_arn], SAMLAssertion=self.saml_response, DurationSeconds=duration) except ClientError as e: fatal('failed to assume role {role_arn}, %s', e) c = response['Credentials'] return AWSCredentials(access_key=c['AccessKeyId'], secret_key=c['SecretAccessKey'], session_token=c['SessionToken'], expiration=c['Expiration'])
def run(self): if not self.audience: fatal('audience is required') super(PKCEGetAccessTokenCommand, self).run()