Skip to content

Commit

Permalink
JAVA-8886 fix config and configure task inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianPhillips2020 committed Dec 20, 2024
1 parent 0cf6610 commit c433217
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
package com.contrastsecurity.gradle.plugin;

import com.contrastsecurity.gradle.plugin.extensions.ContrastConfigurationExtension;
import com.contrastsecurity.sdk.ContrastSDK;
import com.contrastsecurity.sdk.UserAgentProduct;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.TaskProvider;

/**
* Gradle plugin for contrast utilities. The goals for this plugin are defined here <a
* href=https://contrast.atlassian.net/browse/JAVA-8252>JAVA-8252</a>
*/
public class ContrastGradlePlugin implements Plugin<Project> {

ContrastConfigurationExtension extension;

public void apply(final Project target) {

extension = target.getExtensions().create(EXTENSION_NAME, ContrastConfigurationExtension.class);

//initialize instance of the ContrastSDK
ContrastSDKService.initializeSdk(extension.getUsername(), extension.getServiceKey(), extension.getApiKey(), extension.getApiUrl());

target.getTasks().register("installAgent", InstallAgentTask.class);
target.getTasks().register("resolveAgent", ResolveAgentTask.class);

target.getExtensions().create(EXTENSION_NAME, ContrastConfigurationExtension.class);

TaskProvider<ResolveAgentTask> resolveAgentTask = target.getTasks().register("resolveAgent", ResolveAgentTask.class);
target
.getTasks()
.register("installAgent", InstallAgentTask.class)
.configure(task -> {
//Ensure resolve agent task runs before attempting to install the agent
task.dependsOn(ResolveAgentTask.class);
//set input for the agent file as the output from the resolve agent task
task.getInputFile().set(resolveAgentTask.flatMap(ResolveAgentTask::getAgentFile));
});
}

public static final String EXTENSION_NAME = "contrastConfiguration";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
package com.contrastsecurity.gradle.plugin;

import com.contrastsecurity.gradle.plugin.extensions.ContrastConfigurationExtension;
import com.contrastsecurity.sdk.ContrastSDK;
import com.contrastsecurity.sdk.UserAgentProduct;

public class ContrastSDKService {

private static ContrastSDK INSTANCE = null;
public static ContrastSDK INSTANCE;

public static void initializeSdk(
final String username, final String serviceKey, final String apiKey, final String apiUrl) {
public static void initializeSdk(final ContrastConfigurationExtension extension) {
if (extension.getUsername() == null
|| extension.getServiceKey() == null
|| extension.getApiKey() == null) {
INSTANCE = NOOP;
return;
}
final UserAgentProduct gradle = UserAgentProduct.of("contrast-gradle-plugin");
INSTANCE =
new ContrastSDK.Builder(username, serviceKey, apiKey)
.withApiUrl(apiUrl + "/api")
final String url = extension.getApiUrl() == null ? DEFAULT_URL : extension.getApiUrl() + "/api";
INSTANCE =
new ContrastSDK.Builder(
extension.getUsername(), extension.getServiceKey(), extension.getApiKey())
.withApiUrl(url)
// TODO JAVA-8883 figure out how to define this proxy
// .withProxy(proxy) //with proxy?
.withUserAgentProduct(gradle)
.build();
}

public static ContrastSDK getSdk() {
public static ContrastSDK getInstance(ContrastConfigurationExtension extension) {
if (INSTANCE == null) {
initializeSdk(extension);
}
return INSTANCE;
}

static final String DEFAULT_URL = "https://app.contrastsecurity.com/Contrast/api";
public static final ContrastSDK NOOP =
new ContrastSDK.Builder("noop", "noop", "noop").withApiUrl(DEFAULT_URL).build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.contrastsecurity.gradle.plugin.extensions.ContrastConfigurationExtension;
import com.contrastsecurity.models.AgentType;
import com.contrastsecurity.sdk.ContrastSDK;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
Expand All @@ -18,9 +20,14 @@
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.logging.Logger;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.testing.Test;
import org.gradle.internal.impldep.org.tomlj.internal.TomlParser;
import org.jetbrains.annotations.VisibleForTesting;

/**
Expand All @@ -32,12 +39,19 @@ public class InstallAgentTask extends DefaultTask {
final ContrastConfigurationExtension config =
(ContrastConfigurationExtension) getProject().getExtensions().getByName(EXTENSION_NAME);

@TaskAction
@InputFile
final RegularFileProperty agent;

public RegularFileProperty getInputFile(){
return agent;
}

@TaskAction
void installAgent() {

logger.debug("Running installAgentTask");
// create sdk object for connecting to Contrast
final ContrastSDK sdk = ContrastSDKService.getSdk();
final ContrastSDK sdk = ContrastSDKService.getInstance(config);

logger.debug("Connected to Contrast at: " + sdk.getRestApiURL());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,106 @@
package com.contrastsecurity.gradle.plugin;

import static com.contrastsecurity.gradle.plugin.ContrastGradlePlugin.EXTENSION_NAME;

import com.contrastsecurity.gradle.plugin.extensions.ContrastConfigurationExtension;
import com.contrastsecurity.models.AgentType;
import com.contrastsecurity.sdk.ContrastSDK;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.logging.Logger;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.jetbrains.annotations.VisibleForTesting;

public class ResolveAgentTask extends DefaultTask {

@TaskAction
void resolveAgent() {
System.out.println("Resolved Agent");
final ContrastConfigurationExtension config =
(ContrastConfigurationExtension) getProject().getExtensions().getByName(EXTENSION_NAME);

@OutputFile
RegularFileProperty agentFile = getProject().getObjects().fileProperty();

RegularFileProperty getAgentFile(){
return agentFile;
}

private void setAgentFile(final File file){
this.agentFile.set(file);
}

@TaskAction
void resolveAgent() {
final ContrastSDK sdk = ContrastSDKService.getInstance(config);

retrieveAgent(sdk, config.getJarPath(), config.getOrgUuid(), getProject());
}



/** Use ContrastSDK to download agent and return the path where agent jar is stored */
@VisibleForTesting
public static Path retrieveAgent(
final ContrastSDK connection,
final String jarPath,
final String uuid,
final Project project) {

final Logger logger = project.getLogger();
// Initially attempt to get agent from the previously configured location
if (jarPath != null) {
final Path agent = Paths.get(jarPath);
if (!Files.exists(agent)) {
throw new GradleException("Unable to find java agent at " + jarPath);
}
logger.debug("Agent provided via configuration retrieved");
return agent;
}

logger.debug("No agent path provided, checking for cached agent");

final Path agent = Paths.get(project.getProjectDir().getPath()).resolve(AGENT_NAME);
if (Files.exists(agent)) {
System.out.println("Agent jar found at " + project.getProjectDir().getPath());
return agent;
}

logger.debug("Attempting to retrieve agent from TeamServer");
// If no jar is provided, and no jarpath configured, attempt to retrieve the agent from TS
final byte[] bytes;
Path downloadedAgent;
try {
bytes = connection.getAgent(AgentType.JAVA, uuid);

// Save the jar to the 'target' directory
final Path target = Paths.get(project.getProjectDir().getPath());

try {
Files.createFile(target);
} catch (FileAlreadyExistsException e) {
logger.debug("Project dir already exists");
}

downloadedAgent = target.resolve(AGENT_NAME);

Files.write(downloadedAgent, bytes, StandardOpenOption.CREATE, StandardOpenOption.WRITE);

} catch (RuntimeException | IOException e) {
throw new GradleException("Failed to download java agent from the Contrast api: " + e);
}

logger.debug("Agent retrieved from TeamServer");
return downloadedAgent;
}

private static final String AGENT_NAME = "contrast.jar";
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void verify_attaches_agent_to_tests() throws IOException {
testRunner.forwardOutput();
testRunner.withPluginClasspath();
// outputs debug logs to stdout for testing
testRunner.withArguments("installAgent");
testRunner.withArguments("installAgent", "--debug");
testRunner.withDebug(true);
testRunner.withProjectDir(projectDir);
final BuildResult result = testRunner.build();
Expand Down

0 comments on commit c433217

Please sign in to comment.