Skip to content

Commit

Permalink
Merge pull request #3175 from Wadeck/JENKINS-48383_LOGGED_IN_AFTER_AC…
Browse files Browse the repository at this point in the history
…COUNT_CREATION

[JENKINS-48383] Add loggedIn event on self-registration
  • Loading branch information
oleg-nenashev committed Dec 12, 2017
2 parents 7d7848a + 6c04293 commit cc6c508
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
Expand Up @@ -41,6 +41,7 @@
import hudson.util.Protector;
import hudson.util.Scrambler;
import hudson.util.XStream2;
import jenkins.security.SecurityListener;
import net.sf.json.JSONObject;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
Expand Down Expand Up @@ -258,6 +259,8 @@ private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) t
a = this.getSecurityComponents().manager.authenticate(a);
SecurityContextHolder.getContext().setAuthentication(a);

SecurityListener.fireLoggedIn(u.getId());

// then back to top
req.getView(this,"success.jelly").forward(req,rsp);
}
Expand Down
126 changes: 126 additions & 0 deletions test/src/test/java/hudson/security/HudsonPrivateSecurityRealmTest.java
Expand Up @@ -25,33 +25,57 @@
package hudson.security;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.HttpMethod;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
import com.gargoylesoftware.htmlunit.xml.XmlPage;
import hudson.ExtensionList;
import hudson.model.User;
import hudson.remoting.Base64;
import static hudson.security.HudsonPrivateSecurityRealm.CLASSIC;
import static hudson.security.HudsonPrivateSecurityRealm.PASSWORD_ENCODER;
import hudson.security.pages.SignupPage;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import jenkins.security.ApiTokenProperty;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.xml.HasXPath.hasXPath;
import static org.junit.Assert.*;

import jenkins.security.SecurityListener;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
import org.jvnet.hudson.test.TestExtension;
import org.jvnet.hudson.test.WithoutJenkins;
import org.jvnet.hudson.test.recipes.LocalData;

import javax.annotation.Nonnull;

public class HudsonPrivateSecurityRealmTest {

@Rule
public JenkinsRule j = new JenkinsRule();

private SpySecurityListenerImpl spySecurityListener;

@Before
public void linkExtension() throws Exception {
spySecurityListener = ExtensionList.lookup(SecurityListener.class).get(SpySecurityListenerImpl.class);
}

/**
* Tests the data compatibility with Hudson before 1.283.
* Starting 1.283, passwords are now stored hashed.
Expand Down Expand Up @@ -259,4 +283,106 @@ public void fullNameOfUnknownCantSignup() throws Exception {
assertNull(User.get("unknown2",false, Collections.emptyMap()));
}

@Issue("JENKINS-48383")
@Test
public void selfRegistrationTriggerLoggedIn() throws Exception {
HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(true, false, null);
j.jenkins.setSecurityRealm(securityRealm);
j.jenkins.setCrumbIssuer(null);

assertTrue(spySecurityListener.loggedInUsernames.isEmpty());

createFirstAccount("admin");
assertTrue(spySecurityListener.loggedInUsernames.get(0).equals("admin"));

createAccountByAdmin("alice");
// no new event in such case
assertTrue(spySecurityListener.loggedInUsernames.isEmpty());

selfRegistration("bob");
assertTrue(spySecurityListener.loggedInUsernames.get(0).equals("bob"));
}

private void createFirstAccount(String login) throws Exception {
assertNull(User.getById(login, false));

JenkinsRule.WebClient wc = j.createWebClient();

HudsonPrivateSecurityRealm.SignupInfo info = new HudsonPrivateSecurityRealm.SignupInfo();
info.username = login;
info.password1 = login;
info.password2 = login;
info.fullname = StringUtils.capitalize(login);

WebRequest request = new WebRequest(new URL(wc.getContextPath() + "securityRealm/createFirstAccount"), HttpMethod.POST);
request.setRequestParameters(Arrays.asList(
new NameValuePair("username", login),
new NameValuePair("password1", login),
new NameValuePair("password2", login),
new NameValuePair("fullname", StringUtils.capitalize(login)),
new NameValuePair("email", login + "@" + login + ".com")
));

HtmlPage p = wc.getPage(request);
assertEquals(200, p.getWebResponse().getStatusCode());
assertTrue(p.getDocumentElement().getElementsByAttribute("div", "class", "error").isEmpty());

assertNotNull(User.getById(login, false));
}

private void createAccountByAdmin(String login) throws Exception {
// user should not exist before
assertNull(User.getById(login, false));

JenkinsRule.WebClient wc = j.createWebClient();
wc.login("admin");

spySecurityListener.loggedInUsernames.clear();

HtmlPage page = wc.goTo("securityRealm/addUser");
HtmlForm form = page.getForms().stream()
.filter(htmlForm -> htmlForm.getActionAttribute().endsWith("/securityRealm/createAccountByAdmin"))
.findFirst()
.orElseThrow(() -> new AssertionError("Form must be present"));

form.getInputByName("username").setValueAttribute(login);
form.getInputByName("password1").setValueAttribute(login);
form.getInputByName("password2").setValueAttribute(login);
form.getInputByName("fullname").setValueAttribute(StringUtils.capitalize(login));
form.getInputByName("email").setValueAttribute(login + "@" + login + ".com");

HtmlPage p = j.submit(form);
assertEquals(200, p.getWebResponse().getStatusCode());
assertTrue(p.getDocumentElement().getElementsByAttribute("div", "class", "error").isEmpty());

assertNotNull(User.getById(login, false));
}

private void selfRegistration(String login) throws Exception {
// user should not exist before
assertNull(User.getById(login, false));

JenkinsRule.WebClient wc = j.createWebClient();
SignupPage signup = new SignupPage(wc.goTo("signup"));
signup.enterUsername(login);
signup.enterPassword(login);
signup.enterFullName(StringUtils.capitalize(login));
signup.enterEmail(login + "@" + login + ".com");

HtmlPage p = signup.submit(j);
assertEquals(200, p.getWebResponse().getStatusCode());
assertTrue(p.getDocumentElement().getElementsByAttribute("div", "class", "error").isEmpty());

assertNotNull(User.getById(login, false));
}

@TestExtension
public static class SpySecurityListenerImpl extends SecurityListener {
private List<String> loggedInUsernames = new ArrayList<>();

@Override
protected void loggedIn(@Nonnull String username) {
loggedInUsernames.add(username);
}
}
}

0 comments on commit cc6c508

Please sign in to comment.