Пример #1
0
def fetch_registry_data():
    get_default_org()
    url = f"{get_base_url()}/api/v1/analyzers/"
    r = auth_get(url)

    response_json = handle_request_with_error_message(r)
    if response_json["status"] == "success":
        return response_json["analyzers"]
    else:
        raise ValueError("Couldn't parse analyzer registry response")
Пример #2
0
def do_login(org: Optional[str] = None,
             login_token: Optional[str] = None) -> Optional[str]:
    # ensure org
    if org is None:
        org = get_default_org()
        if org is None:
            org = PLATFORM_ANALYZER_PREFIX
    if not login_token:
        if click.confirm(
                "Opening web browser to get login token. Do you want to continue?",
                default=True,
        ):
            open_browser_login(org)
        else:
            url = get_authentication_url(org)
            print_msg(f"Visit {url} and enter the token below")
        # prompt for token
        for attempt in range(MAX_RETRIES):
            # validate token
            token = check_valid_token_with_logging(
                org, click.prompt("Please enter the API token",
                                  hide_input=True))
            if token:
                return token
        print_error_exit(
            "Max attempts exceeded. Please contact R2C support for help")
    else:
        return check_valid_token_with_logging(org, login_token)

    return None
Пример #3
0
def get_base_url(org: Optional[str] = get_default_org()) -> str:
    """Return the base url for an org or the public instance."""
    if org and org != PLATFORM_ANALYZER_PREFIX:
        return f"https://{org}.massive.ret2.co"
    else:
        logger.info(
            f"Using {PLATFORM_ANALYZER_PREFIX} org with base {PLATFORM_BASE_URL}"
        )
        return PLATFORM_BASE_URL
Пример #4
0
def fetch_latest_version() -> Optional[str]:
    try:
        org = get_default_org()

        url = f"{get_base_url()}/api/cli/version/latest"
        r = auth_get(url)
        response_json = handle_request_with_error_message(r)
        return response_json.get("latest")
    except Exception as e:
        return None
Пример #5
0
def init(ctx, analyzer_name, author_name, author_email, run_on, output_type):
    """
    Creates an example analyzer for analyzing JavaScript/TypeScript.

    You may use any language to write your analysis and run it from `src/analyze.sh`.

    Once you create your analyzer, you can navigate to your analyzer directory
    and run 'r2c' commands inside that directory.

    Type `r2c -—help` to see all of the commands available.
    """
    debug = ctx.obj["DEBUG"]
    default_name, default_email = get_git_author()
    if not analyzer_name:
        analyzer_name = click.prompt("Analyzer name", default="example")
    if not author_name:
        author_name = click.prompt("Author name", default=default_name)
    if not author_email:
        author_email = click.prompt("Author email", default=default_email)
    if not run_on:
        run_on = click.prompt(
            "Will your analyzer produce: \n"
            + "- output for a particular `git` repository\n"
            + "- output for a particular git `commit` in a repo\n"
            + "- the same `constant` output regardless of commit or repo?",
            default="commit",
            type=click.Choice(["git", "commit", "constant"]),
        )
    if not output_type:
        output_type = click.prompt(
            "Does your analyzer output \n"
            + "- a single schema-compliant JSON file \n"
            + "- a full filesystem output?",
            default="json",
            type=click.Choice(["json", "filesystem"]),
        )
    create_template_analyzer(
        get_default_org(), analyzer_name, author_name, author_email, run_on, output_type
    )
    print_success(f"Done! Your analyzer can be found in the {analyzer_name} directory")
Пример #6
0
def logout(org=None):
    """Log out of the R2C analysis platform.

    Logging out will remove all authentication tokens.
    If --org is specified, you will only log out of that org.
    """
    try:
        success = True
        success = delete_creds(org) and success
        # remove default org
        if org is None or get_default_org() == org:
            success = delete_default_org() and success
        if success:
            if org:
                print_success(f"logged out of {org}")
            else:
                print_success("logged out of all orgs")
        else:
            print_error_exit("Unexpected error. Please contact us")
    except Exception as e:
        logger.exception(e)
        print_error_exit("Unexpected error. Please contact us")
Пример #7
0
def push(ctx, analyzer_directory, env_args_string):
    """
    Push the analyzer in the current directory to the R2C platform.

    You must log in to push analyzers.

    This command will validate your analyzer and privately publish your analyzer
    to your org with the name specified in analyzer.json.

    Your analyzer name must follow {org}/{name}.
    """
    debug = ctx.obj["DEBUG"]
    env_args_dict = parse_remaining(env_args_string)

    manifest, analyzer_directory = find_and_open_analyzer_manifest(
        analyzer_directory, ctx
    )
    analyzer_org = get_org_from_analyzer_name(manifest.analyzer_name)

    # TODO(ulzii): let's decide which source of truth we're using for analyzer_name above and/or check consistency.
    # can't have both dir name and what's in analyzer.json
    print_msg(f"Pushing analyzer in {analyzer_directory}...")

    default_org = get_default_org()
    if default_org != analyzer_org:
        print_error_exit(
            f"Attempting to push to organization: `{default_org}`. However, the org specified as the prefix of the analyzer name in `analyzer.json` does not match it. "
            + f"Replace `{analyzer_org}` with `{default_org}` and try again."
            + "Please ask for help from R2C support"
        )

    try:
        # upload analyzer.json
        artifact_link = upload_analyzer_manifest(manifest)
    except Exception as e:
        message = getattr(e, "message", repr(e))
        print_error_exit(f"There was an error uploading your analyzer: {message}")
    if artifact_link is None:
        print_error_exit(
            "There was an error uploading your analyzer. Please ask for help from R2C support"
        )
    # get docker login creds
    creds = get_docker_creds(artifact_link)
    if creds is None:
        print_error_exit(
            "There was an error getting Docker credentials. Please ask for help from R2C support"
        )
    # docker login
    successful_login = docker_login(creds)
    if not successful_login:
        print_error_exit(
            "There was an error logging into Docker. Please ask for help from R2C support"
        )
    # docker build and tag
    abort_on_build_failure(
        build_docker(
            manifest.analyzer_name,
            manifest.version,
            os.path.relpath(analyzer_directory, os.getcwd()),
            env_args_dict={**DEFAULT_ENV_ARGS_TO_DOCKER, **env_args_dict},
            verbose=debug,
        )
    )
    # docker push
    image_id = VersionedAnalyzer(manifest.analyzer_name, manifest.version).image_id
    successful_push = docker_push(image_id)
    if not successful_push:
        print_error_exit(
            "There was an error pushing the Docker image. Please ask for help from R2C support"
        )
    # mark uploaded with API
    # TODO figure out how to determine org from analyzer.json
    try:
        uploaded_url = f"{get_base_url()}/api/v1/analyzers/{manifest.analyzer_name}/{manifest.version}/uploaded"
        r = auth_put(uploaded_url)
        data = handle_request_with_error_message(r)
        if data.get("status") == "uploaded":
            web_url = data["links"]["web_url"]
            # display status to user and give link to view in web UI
            print_success(f"Successfully uploaded analyzer! Visit: {web_url}")
        else:
            print_error_exit(
                "Error confirming analyzer was successfully uploaded. Please contact us with the following information: failed to confirm analyzer finished uploading."
            )
    except Exception as e:
        message = getattr(e, "message", repr(e))
        print_error_exit(
            f"Error confirming analyzer was successfully uploaded: {message}"
        )
Пример #8
0
            .decode("utf-8")
            .strip()
        )
        return (git_name, git_email)
    except Exception as e:
        get_logger().info(e)
        return (None, None)


def validate_analyzer_name(analyzer_name: str) -> bool:
    return not INVALID_ANALYZER_NAME_REGEX.search(analyzer_name)


@cli.command()
@click.option("--analyzer-name", hidden=True)
@click.option("--org", hidden=True, default=get_default_org())
@click.option("--author-name", hidden=True)
@click.option("--author-email", hidden=True)
@click.option("--run-on", hidden=True)
@click.option("--output-type", hidden=True)
@click.pass_context
def init(ctx, analyzer_name, org, author_name, author_email, run_on, output_type):
    """
    Creates an example analyzer for analyzing JavaScript/TypeScript.

    You may use any language to write your analysis and run it from `src/analyze.sh`.

    Once you create your analyzer, you can navigate to your analyzer directory
    and run 'r2c' commands inside that directory.

    Type `r2c -—help` to see all of the commands available.
Пример #9
0
def push(ctx, analyzer_directory, force, squash, env_args_string):
    """
    Push the analyzer in the current directory to the R2C platform.

    You must log in to push analyzers.

    This command will validate your analyzer and privately publish your analyzer
    to your org with the name specified in analyzer.json.

    Your analyzer name must follow {org}/{name}.
    """
    env_args_dict = parse_remaining(env_args_string)

    manifest, analyzer_directory = find_and_open_analyzer_manifest(
        analyzer_directory, ctx
    )
    readme = find_and_open_analyzer_readme(analyzer_directory, ctx)
    analyzer_org = get_org_from_analyzer_name(manifest.analyzer_name)

    overwriting_message = (
        " and forcing overwrite if the analyzer version exists and is pending upload."
    )
    # TODO(ulzii): let's decide which source of truth we're using for analyzer_name above and/or check consistency.
    # can't have both dir name and what's in analyzer.json
    print_msg(
        f"📌 Pushing analyzer in {analyzer_directory}{overwriting_message if force else ''}..."
    )

    default_org = get_default_org()
    if default_org is None:
        print_error_exit(
            f"You are not logged in. Please run `r2c login` to be able to push your analyzer"
        )

    if default_org != analyzer_org:
        if analyzer_org != PLATFORM_ANALYZER_PREFIX:
            print_error_exit(
                f"You're logged in to the common r2c platform. The org specified as the prefix of your analyzer name in `analyzer.json` must be `{PLATFORM_ANALYZER_PREFIX}`. "
                + f"Replace `{analyzer_org}` with `{PLATFORM_ANALYZER_PREFIX}` and try again."
                + "Please ask for help from r2c support"
            )
    try:
        # upload analyzer.json
        artifact_link = _upload_analyzer_manifest(manifest, force, readme)
    except Exception as e:
        print_exception_exit("There was an error uploading your analyzer", e)
    if artifact_link is None:
        print_error_exit(
            "There was an error uploading your analyzer. Please ask for help from R2C support"
        )
    get_logger().info(f"using artifact link: {artifact_link}")
    # get docker login creds
    creds = get_docker_creds(artifact_link)
    if creds is None:
        print_error_exit(
            "There was an error getting Docker credentials. Please ask for help from R2C support"
        )
    else:
        print_success_step("Successfully fetched credentials.")

    # docker login
    successful_login = docker_login(creds)
    if not successful_login:
        print_error_exit(
            "There was an error logging into Docker. Please ask for help from R2C support"
        )
    else:
        print_success_step("Successfully logged in to docker.")

    print_msg("🔨 Building docker container")
    # docker build and tag
    abort_on_build_failure(
        build_docker(
            manifest.analyzer_name,
            manifest.version,
            os.path.relpath(analyzer_directory, os.getcwd()),
            env_args_dict=env_args_dict,
            squash=squash,
        )
    )
    # docker push
    image_id = VersionedAnalyzer(manifest.analyzer_name, manifest.version).image_id
    print_msg(f"Pushing docker container to `{analyzer_org}`")
    successful_push = _docker_push(image_id)
    if not successful_push:
        print_error_exit(
            "There was an error pushing the Docker image. Please ask for help from R2C support"
        )
    else:
        print_success_step("Successfully pushed to R2C.")
    # mark uploaded with API
    # TODO figure out how to determine org from analyzer.json
    try:
        uploaded_url = f"{get_base_url()}/api/v1/analyzers/{manifest.analyzer_name}/{manifest.version}/uploaded"
        r = auth_put(uploaded_url)
        data = handle_request_with_error_message(r)
        if data.get("status") == "uploaded":
            web_url = data["links"]["web_url"]
            # display status to user and give link to view in web UI
            print_success(
                f"Upload finished successfully for analyzer! Visit: {web_url}"
            )
        else:
            print_error_exit("Error confirming analyzer was successfully uploaded.")
    except Exception as e:
        print_exception_exit("Error confirming analyzer was successfully uploaded", e)