Пример #1
0
def add_profile(args):
    if args.external_id and not args.role_to_assume:
        _print_error("Error: Cannot use --external-id without --role.")
        sys.exit(1)

    keyring = Keyring()
    if keyring.get_profile(args.profile):
        _print_error(f"Error: Profile \"{args.profile}\" already exists. If you want to modify "
                     "the profile, remove the profile and add it again.")
        sys.exit(1)

    jumpcloud_url = args.url or input(f"Enter the JumpCloud SSO URL for \"{args.profile}\": ")
    jumpcloud_url = jumpcloud_url.strip()
    if not jumpcloud_url.startswith("https://sso.jumpcloud.com/saml2/"):
        _print_error("Error: That's not a valid JumpCloud SSO URL. SSO URLs must "
                     "start with \"https://sso.jumpcloud.com/saml2/\".")
        sys.exit(1)
    if args.role_to_assume:
        if is_arn(args.role_to_assume):
            arn_parts = parse_arn(args.role_to_assume)
            assumed_role = AssumedRole(aws_account_id=arn_parts.aws_account_id,
                                       aws_role=arn_parts.aws_role,
                                       external_id=args.external_id)
        else:
            assumed_role = AssumedRole(aws_account_id=None,
                                       aws_role=args.role_to_assume,
                                       external_id=args.external_id)
    else:
        assumed_role = None
    profile = Profile(args.profile, jumpcloud_url, assumed_role)
    keyring.store_profile(profile)
    print(f"Profile \"{args.profile}\" added.")
Пример #2
0
def _login_to_aws(keyring, profile):
    # Returns an AWSSession with temporary credentials for the given profile.
    session = _login_to_jumpcloud(profile.name)
    sys.stderr.write("Attempting SSO authentication to Amazon Web Services...\n")
    try:
        saml_assertion = session.get_aws_saml_assertion(profile)
    except JumpCloudError as e:
        sys.stderr.write("\n")
        _print_error(f"Error: {e.message}")
        if isinstance(e, JumpCloudServerError):
            _print_error(f"- JumpCloud error message: {e.jumpcloud_error_message or e.response.text}")
        elif isinstance(e, JumpCloudMissingSAMLResponse):
            sys.stderr.write("\n")
            _print_error("You may have been removed from the Single-Sign On Application for the profile "
                         f"\"{profile.name}\", or its URL may be be incorrect. You can check the URL by "
                         "visiting the JumpCloud Console in your web browser and confirming that one of "
                         f"the Single Sign-On Applications has the URL \"{profile.jumpcloud_url}\". If "
                         "the URL is correct, aws-jumpcloud may need to be updated.")
        sys.exit(1)
    roles = get_assertion_roles(saml_assertion)

    # Warning: It's a valid JumpCloud configuration to present more than one
    # role in the assertion, but we don't use that feature right now. We
    # should handle that situation properly at some point.
    assert(len(roles) == 1)
    role = roles[0]

    # Update the AWS account ID and role name if they've changed
    r = parse_arn(role.role_arn)
    if profile.aws_account_id != r.aws_account_id:
        profile.aws_account_id = r.aws_account_id
        keyring.store_profile(profile)
    if profile.aws_role != r.aws_role:
        profile.aws_role = r.aws_role
        keyring.store_profile(profile)

    session = assume_role_with_saml(role, saml_assertion, profile.override_session_duration)

    # Update the AWS account alias on each login. The alias refers to the
    # account used to login, not any assumed role (which happens below).
    alias = get_account_alias(session)
    if alias != profile.aws_account_alias:
        profile.aws_account_alias = alias
        keyring.store_profile(profile)

    if profile.role_to_assume:
        if not profile.role_to_assume.aws_account_id:
            profile.role_to_assume.aws_account_id = profile.aws_account_id
            keyring.store_profile(profile)
        sys.stderr.write(f"Assuming role {profile.role_to_assume.arn}...\n")
        email = keyring.get_jumpcloud_email()
        role_session_name = get_role_session_name(email)
        session = assume_role(session, profile.role_to_assume, role_session_name)

    keyring.store_session(profile.name, session)
    sys.stderr.write("\n")
    return session