All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sourceclear.plugins.DefaultLifecycle Maven / Gradle / Ivy

Go to download

The SRC:CLR Maven Plugin analyzes the dependencies of your project, both immediate and transitive, to see if you are including any known security vulnerabilities through third-party packages in your project.

There is a newer version: 3.1.25
Show newest version
/*
 * © Copyright -  SourceClear Inc
 */

package com.sourceclear.plugins;

import com.google.common.annotations.VisibleForTesting;
import com.sourceclear.api.client.Client;
import com.sourceclear.api.client.SourceClearClient;
import com.sourceclear.api.data.LicenseData;
import com.sourceclear.api.data.evidence.BuildType;
import com.sourceclear.api.data.evidence.LanguageType;
import com.sourceclear.engine.scan.LibraryGraphContainerScanner;
import com.sourceclear.engine.scan.SrcclrScanFailureException;
import com.sourceclear.engine.scan.SrcclrScanUnexpectedCondition;
import com.sourceclear.util.config.ConfigException;
import com.sourceclear.util.config.EnvironmentProvider;
import com.sourceclear.util.config.LicenseDataCheck;
import com.sourceclear.util.config.LicenseDataException;
import com.sourceclear.util.config.ScanConfig;
import com.sourceclear.util.config.Verbosity;
import com.srcclr.sdk.LibraryGraphContainer;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.settings.Settings;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;

import static com.sourceclear.plugins.Utils.maybeSetProxy;
import static java.lang.String.format;

/**
 * The default behavior of the maven plugin. i.e. When not invoked in a headless manner.
 * Unlike the headless mode, the default behavior requires the api token to be given
 * for it to communicate with the API server.
 */
class DefaultLifecycle implements Lifecycle {

  ///////////////////////////// Class Attributes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

  ////////////////////////////// Class Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

  //////////////////////////////// Attributes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

  private ScanConfig scanConfig;

  private Client sourceclearClient;

  private final Config config;

  private final Log logger;

  private boolean withPolicy = false;

  // the environment variable value will take precedence over the parameter supplied
  private static final String API_TOKEN_ENV_VAR = "SRCCLR_API_TOKEN";

  private static final String API_URL_ENV_VAR = "SRCCLR_API_URL";

  private static final String LEGACY_MODE_ENV_VAR = "SRCCLR_LEGACY_MODE";

  private static final String WORKSPACE_SLUG = "SRCCLR_WORKSPACE_SLUG";

  /////////////////////////////// Constructors \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

  public DefaultLifecycle(Config config) {
    this.config = config;
    this.logger = config.getLogger();
  }

  ////////////////////////////////// Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

  @Override
  public void configure(EnvironmentProvider environmentProvider) throws MojoFailureException {
    final String apiToken;
    final String apiTokenEnvVarValue = environmentProvider.getenv(API_TOKEN_ENV_VAR);
    if (!config.useOnlyMavenParams() && StringUtils.isNotBlank(apiTokenEnvVarValue)) {
      apiToken = apiTokenEnvVarValue;
    } else if (StringUtils.isBlank(config.getApiToken())) {
      throw new MojoFailureException("Could not perform scan because an apiToken was not provided. Please provide it either through the \"apiToken\" Maven parameter or the \"" + API_TOKEN_ENV_VAR + "\" environment variable");
    } else {
      apiToken = config.getApiToken();
    }

    final URI apiURL;
    final String apiUrlEnvVarValue = environmentProvider.getenv(API_URL_ENV_VAR);
    if (!config.useOnlyMavenParams() && StringUtils.isNotBlank(apiUrlEnvVarValue)) {
      try {
        apiURL = new URI(apiUrlEnvVarValue);
      } catch (URISyntaxException ex) {
        throw new MojoFailureException(format("Invalid apiUrl value: %s", apiUrlEnvVarValue), ex);
      }
    } else {
      // might be null, but it is ok for apiURL to be null. The default will be used in SourceClearClient.
      apiURL = config.getApiURL();
    }

    final String workspaceSlug;
    final String wsEnvVarValue = environmentProvider.getenv(WORKSPACE_SLUG);
    if (!config.useOnlyMavenParams() && StringUtils.isNotBlank(wsEnvVarValue)) {
      workspaceSlug = wsEnvVarValue;
    } else {
      workspaceSlug = config.getWorkspaceSlug().orElse(null);
    }

    ScanConfig.Builder configBuilder = new ScanConfig.Builder()
        .withLanguage(LanguageType.JAVA)
        .withScanStart(System.currentTimeMillis())
        .withPathToTop(config.getPathToTop())
        .withApiURL(apiURL)
        .withFailureThreshold(config.getFailureThreshold())
        .withProjectName(config.getProjectName())
        .withUserProjectID(config.getUserProjectID())
        .withUpload(config.getUpload())
        .withApiToken(apiToken)
        .withScanID(format("maven-plugin-%s", UUID.randomUUID()))
        .requireApiToken(true)
        .withVerbosity(config.verbose() ? Verbosity.VERBOSE : Verbosity.NORMAL)
        .withWorkspaceSlug(workspaceSlug)
        .withClientType(BuildType.MAVEN);

    createClient(environmentProvider, apiToken, apiURL, config.getSettings());

    if (!config.licenseProvided()) {
      try {
        final LicenseData licenseData = sourceclearClient.license();
        LicenseDataCheck.checkLicenseIsPaidOrThrow(licenseData);
        configBuilder.withLicenseData(licenseData);
      } catch (IOException ex) {
        throw new MojoFailureException("Could not acquire Team license data.", ex);
      } catch (LicenseDataException lde) {
        throw new MojoFailureException(lde.getMessage(), lde);
      }
    }

    try {
      scanConfig = configBuilder.build();
    } catch (ConfigException e) {
      throw new MojoFailureException("Encountered problem during configuration: ", e);
    }
  }

  @Override
  public void execute(LibraryGraphContainer dependencyTree) throws MojoFailureException, MojoExecutionException {
    LibraryGraphContainerScanner scanner = new LibraryGraphContainerScanner(scanConfig, sourceclearClient, withPolicy);
    try {
      scanner.consumeAndReport(dependencyTree);
    } catch (SrcclrScanFailureException e) {
      throw new MojoFailureException(e.getMessage());
    } catch (SrcclrScanUnexpectedCondition e) {
      throw new MojoExecutionException(e.getMessage());
    }
  }

  //------------------------ Implements:

  //------------------------ Overrides:

  //---------------------------- Abstract Methods -----------------------------

  //---------------------------- Utility Methods ------------------------------

  /**
   * Creates a new client to communicate with the api.
   * Enables the policy feature in the client if the feature is enabled in the org and the environment variable is set.
   */
  private void createClient(EnvironmentProvider environmentProvider, String apiToken, URI apiURL, Settings settings) throws MojoFailureException {
    // Create a client to check if the org has policies enabled
    SourceClearClient.Builder builder = SourceClearClient.builder()
        .withClientType(SourceClearClient.Type.MAVEN)
        .withClientVersion(config.getPluginVersion())
        .withApiToken(apiToken)
        .withBaseURI(apiURL);
    maybeSetProxy(builder, settings.getProxies());

    final boolean withPolicy = !Boolean.valueOf(environmentProvider.getenv(LEGACY_MODE_ENV_VAR));

    if (withPolicy) {
      logger.debug("Policy enabled");
      this.withPolicy = true;
    } else {
      logger.debug("Legacy mode enabled.");
    }

    sourceclearClient = builder.withPolicy(withPolicy).build();
  }

  //---------------------------- Property Methods -----------------------------

  @VisibleForTesting
  ScanConfig getScanConfig() {
    return scanConfig;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy