Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
package hudson.security.csrf.GlobalCrumbIssuerConfiguration

import hudson.security.csrf.CrumbIssuer
import hudson.security.csrf.DefaultCrumbIssuer

def f=namespace(lib.FormTagLib)
def f = namespace(lib.FormTagLib)
def all = CrumbIssuer.all()
def disableCsrf =
hudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION

if (!all.isEmpty()) {
def onlyDefaultIssuer =
all.size() == 1 && all[0].clazz == DefaultCrumbIssuer

def showCsrfConfig = !onlyDefaultIssuer || disableCsrf

if (showCsrfConfig) {
f.section(title: _("CSRF Protection")) {
if (hudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION) {
if (disableCsrf) {
f.entry {
p(raw(_('disabled')))
p(_('unsupported'))
}
} else {
f.dropdownDescriptorSelector(title: _("Crumb Issuer"), descriptors: all, field: 'crumbIssuer')
f.dropdownDescriptorSelector(
title: _("Crumb Issuer"),
descriptors: all,
field: 'crumbIssuer'
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package hudson.security.csrf;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

import jakarta.servlet.ServletRequest;
import org.htmlunit.html.HtmlPage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestExtension;
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;

@WithJenkins
class GlobalCrumbIssuerConfigurationTest {

private JenkinsRule j;

@BeforeEach
void setUp(JenkinsRule rule) {
j = rule;
}

@Test
void csrfSectionShownWhenNonDefaultIssuerConfigured() throws Exception {
// DefaultCrumbIssuer is default, but other CrumbIssuer descriptors exist in test environment
// so the CSRF section should be visible
j.jenkins.setCrumbIssuer(new DefaultCrumbIssuer(false));

JenkinsRule.WebClient wc = j.createWebClient();
HtmlPage page = wc.goTo("configureSecurity");
String pageContent = page.asNormalizedText();

// With multiple CrumbIssuer descriptors available (from test extensions),
// the CSRF Protection section should always be shown
assertThat("CSRF Protection section should be shown when multiple issuers are available",
pageContent, containsString("CSRF Protection"));
}

@Test
void csrfSectionShownWhenCsrfProtectionDisabled() throws Exception {
boolean original = GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION;
try {
GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION = true;

JenkinsRule.WebClient wc = j.createWebClient();
HtmlPage page = wc.goTo("configureSecurity");
String pageContent = page.asNormalizedText();

assertThat("CSRF section should be shown when CSRF protection is disabled",
pageContent, containsString("CSRF Protection"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should specifically assert the placeholder message, see other comment.

} finally {
GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION = original;
}
}

@TestExtension
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Limit to #csrfSectionShownWhenNonDefaultIssuerConfigured otherwise #csrfSectionShownWhenCsrfProtectionDisabled is unconvincing. I expect that would pass even if you never set the flag.

public static class DummyCrumbIssuer extends CrumbIssuer {

@Override
public String getCrumbRequestField() {
return "dummy";
}

@Override
public String issueCrumb(ServletRequest request, String salt) {
return "dummy-crumb";
}

public static class DescriptorImpl extends CrumbIssuerDescriptor<DummyCrumbIssuer> {

DescriptorImpl() {
super(
DummyCrumbIssuer.class.getName(),
"Dummy Crumb Issuer"
);
}

@Override
public String getDisplayName() {
return "Dummy Crumb Issuer";
}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add trailing newline.