diff --git a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java index 5868d62b9ad6..63539b06d5df 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java +++ b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java @@ -32,10 +32,11 @@ import hudson.cli.CLICommand; import hudson.cli.CloneableCLICommand; import hudson.model.Hudson; +import hudson.security.ACL; +import hudson.security.CliAuthenticator; import jenkins.ExtensionComponentSet; import jenkins.ExtensionRefreshException; import jenkins.model.Jenkins; -import hudson.security.CliAuthenticator; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.acegisecurity.BadCredentialsException; @@ -44,8 +45,8 @@ import org.jvnet.hudson.annotation_indexer.Index; import org.jvnet.localizer.ResourceBundleHolder; import org.kohsuke.args4j.ClassParser; -import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; import java.io.IOException; import java.io.InputStream; @@ -60,12 +61,12 @@ import java.util.Locale; import java.util.MissingResourceException; import java.util.Stack; -import static java.util.logging.Level.SEVERE; - import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; +import static java.util.logging.Level.SEVERE; + /** * Discover {@link CLIMethod}s and register them as {@link CLICommand} implementations. * @@ -214,8 +215,10 @@ public int main(List args, Locale locale, InputStream stdin, PrintStream parser.parseArgument(args); Authentication auth = authenticator.authenticate(); - if (auth == Jenkins.ANONYMOUS) + // isAnonymous requires non null value, but authenticate does not provide contract + if (auth == null || ACL.isAnonymous(auth)) { auth = loadStoredAuthentication(); + } sc.setAuthentication(auth); // run the CLI with the right credential hudson.checkPermission(Jenkins.READ); diff --git a/test/src/test/java/hudson/cli/CLIRegistererTest.java b/test/src/test/java/hudson/cli/CLIRegistererTest.java index fd5a427ba298..4b183e40c67e 100644 --- a/test/src/test/java/hudson/cli/CLIRegistererTest.java +++ b/test/src/test/java/hudson/cli/CLIRegistererTest.java @@ -1,37 +1,43 @@ package hudson.cli; -import static hudson.cli.CLICommandInvoker.Matcher.failedWith; -import static hudson.cli.CLICommandInvoker.Matcher.succeededSilently; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; - -import jenkins.model.Jenkins; -import hudson.cli.CLICommandInvoker; import hudson.cli.CLICommandInvoker.Result; - +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; +import static hudson.cli.CLICommandInvoker.Matcher.failedWith; +import static hudson.cli.CLICommandInvoker.Matcher.succeededSilently; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + public class CLIRegistererTest { @Rule public JenkinsRule j = new JenkinsRule(); + /** + * See also {@link ClientAuthenticationCacheTest#overHttpAlsoForRegisterer()} for the equivalent using remoting / authenticationCache, i.e. login+logout + */ @Test - public void testAuthWithSecurityRealmCLIAuthenticator() { - j.getInstance().setSecurityRealm(j.createDummySecurityRealm()); + public void testAuthWithSecurityRealmCLIAuthenticator() throws Exception { + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); + FreeStyleProject project = j.createFreeStyleProject(); + FreeStyleBuild build1 = j.buildAndAssertSuccess(project); + assertFalse("By default the build log should not be kept", build1.isKeepLog()); - CLICommandInvoker command = new CLICommandInvoker(j, "quiet-down"); + CLICommandInvoker command = new CLICommandInvoker(j, "keep-build"); - Result invocation = command.invokeWithArgs("--username", "foo", "--password", "invalid"); + Result invocation = command.invokeWithArgs(project.getName(), build1.getNumber() + "", "--username", "foo", "--password", "invalid"); assertThat(invocation, failedWith(7)); assertThat(invocation.stderr(), containsString("ERROR: Bad Credentials. Search the server log for ")); - assertThat("Unauthorized command was executed", Jenkins.getInstance().isQuietingDown(), is(false)); + assertFalse("The command should have not been executed", build1.isKeepLog()); - invocation = command.invokeWithArgs("--username", "foo", "--password", "foo"); + invocation = command.invokeWithArgs(project.getName(), build1.getNumber() + "", "--username", "foo", "--password", "foo"); assertThat(invocation, succeededSilently()); - assertThat("Authorized command was not executed", Jenkins.getInstance().isQuietingDown(), is(true)); + assertTrue("The command should have been executed", build1.isKeepLog()); } } diff --git a/test/src/test/java/hudson/cli/ClientAuthenticationCacheTest.java b/test/src/test/java/hudson/cli/ClientAuthenticationCacheTest.java index 077e5314685f..f1b79f98e729 100644 --- a/test/src/test/java/hudson/cli/ClientAuthenticationCacheTest.java +++ b/test/src/test/java/hudson/cli/ClientAuthenticationCacheTest.java @@ -25,35 +25,43 @@ package hudson.cli; import com.google.common.collect.Lists; - import hudson.ExtensionList; import hudson.Launcher; +import hudson.cli.declarative.CLIRegisterer; +import hudson.model.FreeStyleBuild; +import hudson.model.FreeStyleProject; import hudson.security.FullControlOnceLoggedInAuthorizationStrategy; import hudson.util.Secret; import hudson.util.StreamTaskListener; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; -import javax.annotation.CheckForNull; import jenkins.model.JenkinsLocationConfiguration; import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.TeeOutputStream; -import static org.hamcrest.Matchers.containsString; - import org.junit.Before; -import org.junit.Test; -import static org.junit.Assert.*; import org.junit.Ignore; import org.junit.Rule; +import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.jvnet.hudson.test.For; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.LoggerRule; +import javax.annotation.CheckForNull; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + public class ClientAuthenticationCacheTest { @Rule @@ -119,6 +127,28 @@ public void overHttp() throws Exception { } } + @Test + @Issue("JENKINS-54176") + @For(CLIRegisterer.class) + public void overHttpAlsoForRegisterer() throws Exception { + File jar = tmp.newFile("jenkins-cli.jar"); + FileUtils.copyURLToFile(r.jenkins.getJnlpJars("jenkins-cli.jar").getURL(), jar); + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy()); + r.jenkins.setSlaveAgentPort(-1); + assertCLI(0, null, jar, "login", "--username", "admin", "--password", "admin"); + try { + FreeStyleProject project = r.createFreeStyleProject(); + FreeStyleBuild build1 = r.buildAndAssertSuccess(project); + assertFalse("By default the build's log should not be kept", build1.isKeepLog()); + + assertCLI(0, null, jar, "keep-build", project.getName(), build1.getNumber() + ""); + assertTrue("After invocation the build's log should be kept", build1.isKeepLog()); + } finally { + assertCLI(0, null, jar, "logout"); + } + } + @Test public void getPropertyKey() throws Exception { ClientAuthenticationCache cache = new ClientAuthenticationCache(null);