diff --git a/Jenkinsfile b/Jenkinsfile index 6ada015aa..095a3bbd0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -39,7 +39,7 @@ if (needSplittingFromWorkspace) { } def axes = [ - jenkinsVersions: ['lts', 'latest'], + jenkinsVersions: ['latest'], platforms: ['linux'], jdks: [17, 21], browsers: ['firefox'], diff --git a/src/main/java/org/jenkinsci/test/acceptance/junit/CspRule.java b/src/main/java/org/jenkinsci/test/acceptance/junit/CspRule.java new file mode 100644 index 000000000..7ccc57e91 --- /dev/null +++ b/src/main/java/org/jenkinsci/test/acceptance/junit/CspRule.java @@ -0,0 +1,51 @@ +package org.jenkinsci.test.acceptance.junit; + +import com.google.inject.Inject; +import com.google.inject.Injector; +import java.util.List; +import java.util.logging.Logger; +import org.jenkinsci.test.acceptance.plugins.csp.ContentSecurityPolicyReport; +import org.jenkinsci.test.acceptance.po.Jenkins; +import org.jenkinsci.test.acceptance.update_center.PluginSpec; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +@GlobalRule +public final class CspRule implements TestRule { + + private static final Logger LOGGER = Logger.getLogger(CspRule.class.getName()); + + @Inject + Injector injector; + + @Override + public Statement apply(final Statement base, final Description d) { + return new Statement() { + private Jenkins jenkins; + + @Override + public void evaluate() throws Throwable { + jenkins = injector.getInstance(Jenkins.class); + final PluginSpec plugin = new PluginSpec("csp"); + LOGGER.info("Installing plugin for test: " + plugin); + jenkins.getPluginManager().installPlugins(plugin); + // LOGGER.info("Configuring CSP plugin for test"); + // final GlobalSecurityConfig security = new GlobalSecurityConfig(jenkins); + // security.open(); + // security.disableCspReportOnly(); + // security.save(); + try { + base.evaluate(); + } finally { + ContentSecurityPolicyReport csp = new ContentSecurityPolicyReport(jenkins); + csp.open(); + List lines = csp.getReport(); + if (lines.size() > 2) { + throw new AssertionError(String.join("\n", csp.getReport())); + } + } + } + }; + } +} diff --git a/src/main/java/org/jenkinsci/test/acceptance/plugins/csp/ContentSecurityPolicyReport.java b/src/main/java/org/jenkinsci/test/acceptance/plugins/csp/ContentSecurityPolicyReport.java new file mode 100644 index 000000000..74aa9822f --- /dev/null +++ b/src/main/java/org/jenkinsci/test/acceptance/plugins/csp/ContentSecurityPolicyReport.java @@ -0,0 +1,36 @@ +package org.jenkinsci.test.acceptance.plugins.csp; + +import java.util.ArrayList; +import java.util.List; +import org.jenkinsci.test.acceptance.po.Jenkins; +import org.jenkinsci.test.acceptance.po.PageObject; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +public class ContentSecurityPolicyReport extends PageObject { + public ContentSecurityPolicyReport(Jenkins context) { + super(context, context.url("content-security-policy-reports/")); + } + + public List getReport() { + List lines = new ArrayList<>(); + WebElement table = find(By.className("bigtable")); + List headers = table.findElements(By.tagName("th")); + StringBuilder sb = new StringBuilder(); + for (WebElement header : headers) { + sb.append(header.getText()).append("\t"); + } + lines.add(sb.toString()); + sb = new StringBuilder(); + List rows = table.findElements(By.tagName("tr")); + for (WebElement row : rows) { + List cells = row.findElements(By.tagName("td")); + for (WebElement cell : cells) { + sb.append(cell.getText()).append("\t"); + } + lines.add(sb.toString()); + sb = new StringBuilder(); + } + return lines; + } +} diff --git a/src/main/java/org/jenkinsci/test/acceptance/po/GlobalSecurityConfig.java b/src/main/java/org/jenkinsci/test/acceptance/po/GlobalSecurityConfig.java index ca80929d0..3f670b8b6 100644 --- a/src/main/java/org/jenkinsci/test/acceptance/po/GlobalSecurityConfig.java +++ b/src/main/java/org/jenkinsci/test/acceptance/po/GlobalSecurityConfig.java @@ -27,6 +27,7 @@ import java.net.URL; import org.jenkinsci.test.acceptance.plugins.authorize_project.BuildAccessControl; import org.jenkinsci.test.acceptance.plugins.git_client.ssh_host_key_verification.SshHostKeyVerificationStrategy; +import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; @@ -83,6 +84,10 @@ private void maybeCheckUseSecurity() { } } + public void disableCspReportOnly() { + control(By.name("_.reportOnly")).uncheck(); + } + public T addBuildAccessControl(final Class type) { final String path = createPageArea("/jenkins-security-QueueItemAuthenticatorConfiguration/authenticators", () -> control(