com.sourceclear.plugins.DefaultLifecycle Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of srcclr-maven-plugin Show documentation
Show all versions of srcclr-maven-plugin Show documentation
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.
/*
* © 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;
}
}