Skip to content

Commit

Permalink
Merge pull request #185 from Dohbedoh/JENKINS-68748
Browse files Browse the repository at this point in the history
[JENKINS-68748] Adapt Test LDAP functionality to 2.346.x and later
  • Loading branch information
jtnord authored Mar 14, 2023
2 parents f59933c + 3f3b43f commit 2a9192a
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 53 deletions.
22 changes: 1 addition & 21 deletions src/main/java/hudson/security/LDAPSecurityRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import hudson.util.ListBoxModel;
import hudson.util.Scrambler;
import hudson.util.Secret;
import hudson.util.VersionNumber;
import jenkins.model.IdStrategy;
import jenkins.model.Jenkins;
import jenkins.security.SecurityListener;
Expand Down Expand Up @@ -1515,20 +1514,6 @@ public SecurityRealm newInstance(StaplerRequest req, JSONObject formData) throws
return super.newInstance(req, formData);
}

/**
* Used by config.jelly to determine whether we are running on a Jenkins with Enable Security checkbox or not.
* It impacts the json structure to send when checking the ldap configuration in the filter attribute of the
* validate element
* @return true if this Jenkins has Enable Security checkbox
*/
@Restricted(NoExternalUse.class)
public boolean hasEnableSecurityForm() {
// make spotbugs happy and if the version is not computed, we assume we are on a modern version, without
// the enable security form
VersionNumber currentVersion = Jenkins.getVersion();
return currentVersion != null && currentVersion.isOlderThan(new VersionNumber("2.214"));
}

@RequirePOST
public FormValidation doValidate(StaplerRequest req) throws Exception {
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
Expand All @@ -1539,12 +1524,7 @@ public FormValidation doValidate(StaplerRequest req) throws Exception {
JSONObject json = JSONObject.fromObject(IOUtils.toString(req.getInputStream(), Util.fixNull(req.getCharacterEncoding(), StandardCharsets.UTF_8.name())));
String user = json.getString("testUser");
String password = json.getString("testPassword");
JSONObject realmCfg;
if (hasEnableSecurityForm()) {
realmCfg = json.getJSONObject("useSecurity").getJSONObject("realm");
} else {
realmCfg = json.getJSONObject("realm");
}
JSONObject realmCfg = json.getJSONObject("securityRealm");

// instantiate the realm
LDAPSecurityRealm realm = req.bindJSON(LDAPSecurityRealm.class, realmCfg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,8 @@ THE SOFTWARE.
</f:entry>
</f:repeatable>
</f:entry>
<j:choose>
<j:when test="${descriptor.hasEnableSecurityForm()}">
<j:set var="validateFilter" value="useSecurity.realm" />
</j:when>
<j:otherwise>
<j:set var="validateFilter" value="realm" />
</j:otherwise>
</j:choose>

<v:validate name="validateLdapSettings" method="validate" filter="${validateFilter}"
<v:validate name="validateLdapSettings" method="validate" filter="securityRealm"
title="${%Test LDAP settings}"
dialog="${%Test LDAP settings}"
submit="${%Test}">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,6 @@
<img src="${imagesURL}/spinner.gif"/>
${attrs.progress}
</div>
<div id="${uid}_result"><!-- this is where the error message goes --></div>
</f:entry>
<script>
// HACK: can be removed once base version of Jenkins has fix of https://issues.jenkins-ci.org/browse/JENKINS-26578
// conditionally include the adjunct resources as AdjunctManager doesn't do this correctly for CSS
if (!document.getElementById('jenkins.security.plugins.ldap.validation.validate')) {
var link = document.createElement('link');
link.id = 'jenkins.security.plugins.ldap.validation.validate';
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = "${request.contextPath+'/'+app.getAdjuncts(null).rootURL+'/jenkins/security/plugins/ldap/validation/validate/validate.css'}";
link.media = 'all';
document.getElementsByTagName('head')[0].appendChild(link);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = "${request.contextPath+'/'+app.getAdjuncts(null).rootURL+'/jenkins/security/plugins/ldap/validation/validate/validate.js'}";
document.getElementsByTagName('body')[0].appendChild(script);
}
</script>
<st:adjunct includes="jenkins.security.plugins.ldap.validation.validate.validate" />
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ function ldapValidateButton(checkUrl, formFilter, button, id) {
var buttons = dialogDiv.getElementsByTagName("BUTTON");
buttons[buttons.length-1].onclick = function () {
var spinner = document.getElementById(id + "_spinner");
var target = document.getElementById(id+"_result");
target.style.display = "none";
target.innerHTML = '';
var target = spinner.closest('.jenkins-form-item').querySelector(".validation-error-area");
spinner.style.display = "block";
for (var i = 0; i < inputs.length; i++) {
json[inputs[i].name] = inputs[i].value;
Expand All @@ -87,8 +85,8 @@ function ldapValidateButton(checkUrl, formFilter, button, id) {
postBody: Object.toJSON(json),
onComplete: function (rsp) {
spinner.style.display = "none";
applyErrorMessage(target, rsp);
target.style.display = "block";
target.innerHTML = `<div class="validation-error-area" />`;
updateValidationArea(target, rsp.responseText);
layoutUpdateCallback.call();
var s = rsp.getResponseHeader("script");
try {
Expand Down
94 changes: 94 additions & 0 deletions src/test/java/hudson/security/LDAPEmbeddedTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
package hudson.security;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlButton;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.model.User;
import hudson.tasks.MailAddressResolver;
import hudson.tasks.Mailer;
Expand Down Expand Up @@ -63,6 +69,7 @@
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
Expand Down Expand Up @@ -618,6 +625,93 @@ public void validate() throws Exception {
assertThat("Always report outer kind as OK", validation.kind, is(FormValidation.Kind.OK));
}

@Test
@Issue("JENKINS-68748")
@LDAPSchema(ldif = "sevenSeas", id = "sevenSeas", dn = "o=sevenSeas")
public void validateUI() throws Exception {
LDAPSecurityRealm realm = new LDAPSecurityRealm(
ads.getUrl(),
null,
null,
null,
null,
null,
new FromGroupSearchLDAPGroupMembershipStrategy(null),
"uid=admin,ou=system",
Secret.fromString("pass"),
false,
false,
new LDAPSecurityRealm.CacheConfiguration(100, 1000),
new LDAPSecurityRealm.EnvironmentProperty[0],
"cn",
null,
IdStrategy.CASE_INSENSITIVE,
IdStrategy.CASE_INSENSITIVE);
realm.setDisableRolePrefixing(true);
r.jenkins.setSecurityRealm(realm);
r.jenkins.getSecurityRealm().createSecurityComponents();

try(JenkinsRule.WebClient c = r.createWebClient().withJavaScriptEnabled(true)) {

final HtmlPage security = c.goTo("configureSecurity");
final HtmlForm form = security.getFormByName("config");

HtmlButton testButton = form.getButtonByName("validateLdapSettings");
assertThat(testButton, notNullValue());
testButton.click();

c.waitForBackgroundJavaScript(2000);

final HtmlInput testUser = security.getElementByName("testUser");
testUser.setAttribute("value", "hnelson");
final HtmlInput testPassword = security.getElementByName("testPassword");
testPassword.setAttribute("value", "pass");

HtmlButton submitElement = null;
for (DomElement e : security.getElementsByTagName("button")) {
if ("submit".equals(e.getAttribute("type")) && "Test".equals(e.getTextContent())) {
submitElement = (HtmlButton) e;
break;
}
}

assertThat(submitElement, notNullValue());
submitElement.click();

c.waitForBackgroundJavaScript(2000);

Document validationDoc = Jsoup.parse(security.asXml());
assertThat(validationDoc.select("[data-test='authentication']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='authentication-username']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='authentication-dn']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='authentication-displayname']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='authentication-email']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='authentication-groups']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='lookup']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='lookup-username']").attr("class"),
is(""));
assertThat(validationDoc.select("[data-test='lookup-dn']").attr("class"),
is(""));
assertThat(validationDoc.select("[data-test='lookup-displayname']").attr("class"),
is(""));
assertThat(validationDoc.select("[data-test='lookup-email']").attr("class"),
is(""));
assertThat(validationDoc.select("[data-test='lookup-groups']").attr("class"),
is(""));
assertThat(validationDoc.select("[data-test='consistency']").attr("class"),
containsString("validation-ok"));
assertThat(validationDoc.select("[data-test='resolve-groups']").attr("class"),
containsString("validation-ok"));
}
}

@Test
@LDAPSchema(ldif = "planetexpress", id = "planetexpress", dn = "dc=planetexpress,dc=com")
public void usingEnvironmentProperties() throws Exception {
Expand Down

0 comments on commit 2a9192a

Please sign in to comment.