package hudson.security;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import hudson.cli.CLI;
import hudson.cli.CLICommand;
import hudson.cli.ClientAuthenticationCache;
import hudson.cli.LoginCommand;
import hudson.cli.LogoutCommand;
import jenkins.model.Jenkins;
import org.acegisecurity.Authentication;
import org.apache.commons.io.input.NullInputStream;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.For;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestExtension;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
/**
* @author Kohsuke Kawaguchi
*/
public class CliAuthenticationTest {
@Rule
public JenkinsRule j = new JenkinsRule();
@Test
public void test() throws Exception {
// dummy security realm that authenticates when username==password
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
successfulCommand("test","--username","abc","--password","abc");
}
private void successfulCommand(String... args) throws Exception {
assertEquals(0, command(args));
}
private int command(String... args) throws Exception {
CLI cli = new CLI(j.getURL());
try {
return cli.execute(args);
} finally {
cli.close();
}
}
private String commandAndOutput(String... args) throws Exception {
CLI cli = new CLI(j.getURL());
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
cli.execute(Arrays.asList(args), new NullInputStream(0), baos, baos);
return baos.toString();
} finally {
cli.close();
}
}
@TestExtension
public static class TestCommand extends CLICommand {
@Override
public String getShortDescription() {
return "test command";
}
@Override
protected int run() throws Exception {
Authentication auth = Jenkins.getAuthentication();
assertNotSame(Jenkins.ANONYMOUS,auth);
assertEquals("abc", auth.getName());
return 0;
}
}
@TestExtension
public static class AnonymousCommand extends CLICommand {
@Override
public String getShortDescription() {
return "makes sure that the command is running as anonymous user";
}
@Override
protected int run() throws Exception {
Authentication auth = Jenkins.getAuthentication();
assertSame(Jenkins.ANONYMOUS,auth);
return 0;
}
}
@Test
@For({LoginCommand.class, LogoutCommand.class, ClientAuthenticationCache.class})
public void login() throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
successfulCommand("login","--username","abc","--password","abc");
successfulCommand("test"); // now we can run without an explicit credential
successfulCommand("logout");
successfulCommand("anonymous"); // now we should run as anonymous
}
/**
* Login failure shouldn't reveal information about the existence of user
*/
@Test
public void security110() throws Exception {
HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false,false,null);
j.jenkins.setSecurityRealm(realm);
j.jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy());
realm.createAccount("alice","alice");
String out1 = commandAndOutput("help", "--username", "alice", "--password", "bogus");
String out2 = commandAndOutput("help", "--username", "bob", "--password", "bogus");
assertTrue(out1.contains("Bad Credentials. Search the server log for"));
assertTrue(out2.contains("Bad Credentials. Search the server log for"));
}
}