package hudson.security;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import static org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import com.gargoylesoftware.htmlunit.html.HtmlFormUtil;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
import org.jvnet.hudson.test.recipes.PresetData;
import org.jvnet.hudson.test.recipes.PresetData.DataSet;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.net.URL;
/**
* @author Kohsuke Kawaguchi
*/
public class LoginTest {
@Rule
public JenkinsRule j = new JenkinsRule();
/**
* Requesting a loginError page directly should result in a redirect,
* on a non-secured Hudson.
*/
@Test
public void loginErrorRedirect1() throws Exception {
verifyNotError(j.createWebClient());
}
private void verifyNotError(WebClient wc) throws IOException, SAXException {
HtmlPage p = wc.goTo("loginError");
URL url = p.getUrl();
System.out.println(url);
assertFalse(url.toExternalForm().contains("login"));
}
/**
* Same as {@link #loginErrorRedirect1()} if the user has already successfully authenticated.
*/
@Test
@PresetData(DataSet.ANONYMOUS_READONLY)
public void loginErrorRedirect2() throws Exception {
// in a secured Hudson, the error page should render.
WebClient wc = j.createWebClient();
wc.assertFails("loginError", SC_UNAUTHORIZED);
// but not once the user logs in.
verifyNotError(wc.login("alice"));
}
private HtmlForm prepareLoginFormWithRememberMeChecked(WebClient wc) throws IOException, org.xml.sax.SAXException {
wc.getCookieManager().setCookiesEnabled(true);
HtmlPage page = wc.goTo("login");
HtmlForm form = page.getFormByName("login");
form.getInputByName("j_username").setValueAttribute("alice");
form.getInputByName("j_password").setValueAttribute("alice");
((HtmlCheckBoxInput)form.getInputByName("remember_me")).setChecked(true);
return form;
}
/**
* Returns the 'remember me' cookie if set, otherwise return null. We don't care about the type, only whether it's null
*/
private Object getRememberMeCookie(WebClient wc) {
return wc.getCookieManager().getCookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
}
/**
* Test 'remember me' cookie
*/
@Test
@PresetData(DataSet.SECURED_ACEGI)
public void loginRememberMe() throws Exception {
WebClient wc = j.createWebClient();
HtmlFormUtil.submit(prepareLoginFormWithRememberMeChecked(wc), null);
assertNotNull(getRememberMeCookie(wc));
}
/**
* Test that 'remember me' cookie will not be set if disabled even if requested by user.
* This models the case when the feature is disabled between another user loading and submitting the login page.
*/
@Test
@PresetData(DataSet.SECURED_ACEGI)
public void loginDisabledRememberMe() throws Exception {
WebClient wc = j.createWebClient();
HtmlForm form = prepareLoginFormWithRememberMeChecked(wc);
j.jenkins.setDisableRememberMe(true);
HtmlFormUtil.submit(form, null);
assertNull(getRememberMeCookie(wc));
}
}