diff --git a/core/src/main/java/hudson/cli/BuildCommand.java b/core/src/main/java/hudson/cli/BuildCommand.java index 6d508efbf1a72ba15a20a527343c3403be1806b4..a214dd6b3a32c967d2bf541afde81fddae3f3527 100644 --- a/core/src/main/java/hudson/cli/BuildCommand.java +++ b/core/src/main/java/hudson/cli/BuildCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,7 @@ import hudson.model.ParametersDefinitionProperty; import hudson.model.ParameterDefinition; import hudson.Extension; import hudson.AbortException; +import hudson.model.Item; import hudson.util.EditDistance; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; @@ -66,8 +67,9 @@ public class BuildCommand extends CLICommand { public Map parameters = new HashMap(); protected int run() throws Exception { - ParametersAction a = null; + job.checkPermission(Item.BUILD); + ParametersAction a = null; if (!parameters.isEmpty()) { ParametersDefinitionProperty pdp = job.getProperty(ParametersDefinitionProperty.class); if (pdp==null) @@ -106,6 +108,7 @@ public class BuildCommand extends CLICommand { ); } + // TODO: CLI can authenticate as different users, so should record which user here.. public static class CLICause extends Cause { public String getShortDescription() { return "Started by command line"; diff --git a/core/src/main/java/hudson/cli/CLICommand.java b/core/src/main/java/hudson/cli/CLICommand.java index 46a16da2e90643b3801d221e80f54be62078d98c..56f44b474d4297b2af37c7c22a681ac126b4fce2 100644 --- a/core/src/main/java/hudson/cli/CLICommand.java +++ b/core/src/main/java/hudson/cli/CLICommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,6 @@ import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.jvnet.hudson.annotation_indexer.Index; -import org.jvnet.hudson.annotation_indexer.Indexed; import org.jvnet.tiger_types.Types; import org.kohsuke.args4j.ClassParser; import org.kohsuke.args4j.CmdLineException; @@ -48,7 +47,6 @@ import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.spi.OptionHandler; import java.io.BufferedInputStream; -import java.io.IOError; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; @@ -181,6 +179,8 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { if (auth==Hudson.ANONYMOUS) auth = loadStoredAuthentication(); sc.setAuthentication(auth); // run the CLI with the right credential + if (!(this instanceof LoginCommand || this instanceof HelpCommand)) + Hudson.getInstance().checkPermission(Hudson.READ); return run(); } catch (CmdLineException e) { stderr.println(e.getMessage()); diff --git a/core/src/main/java/hudson/cli/CopyJobCommand.java b/core/src/main/java/hudson/cli/CopyJobCommand.java index 371f1380686018ad6db85052e479a6a1b03b7ff0..6564f9b07e43814eb29e8cc09ab09699f3cc183c 100644 --- a/core/src/main/java/hudson/cli/CopyJobCommand.java +++ b/core/src/main/java/hudson/cli/CopyJobCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,13 +23,12 @@ */ package hudson.cli; -import hudson.model.AbstractProject; import hudson.model.Hudson; import hudson.model.TopLevelItem; import hudson.Extension; +import hudson.model.Item; import org.kohsuke.args4j.Argument; -import java.io.Serializable; /** * Copies a job from CLI. @@ -51,6 +50,8 @@ public class CopyJobCommand extends CLICommand { protected int run() throws Exception { Hudson h = Hudson.getInstance(); + h.checkPermission(Item.CREATE); + if (h.getItem(dst)!=null) { stderr.println("Job '"+dst+"' already exists"); return -1; diff --git a/core/src/main/java/hudson/cli/CreateJobCommand.java b/core/src/main/java/hudson/cli/CreateJobCommand.java index 189e6a4ede71590fbd555eac605770d999386cee..3f0c522c02093e2a29f483983a3d68b46248668e 100644 --- a/core/src/main/java/hudson/cli/CreateJobCommand.java +++ b/core/src/main/java/hudson/cli/CreateJobCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ package hudson.cli; import hudson.model.Hudson; import hudson.Extension; +import hudson.model.Item; import org.kohsuke.args4j.Argument; /** @@ -44,6 +45,8 @@ public class CreateJobCommand extends CLICommand { protected int run() throws Exception { Hudson h = Hudson.getInstance(); + h.checkPermission(Item.CREATE); + if (h.getItem(name)!=null) { stderr.println("Job '"+name+"' already exists"); return -1; diff --git a/core/src/main/java/hudson/cli/DeleteBuildsCommand.java b/core/src/main/java/hudson/cli/DeleteBuildsCommand.java index b52eb2d541a433ff4c39bb6eda0c7ad3bfbf66bb..eae61b4062c41646cf872182422bcde06b50355d 100644 --- a/core/src/main/java/hudson/cli/DeleteBuildsCommand.java +++ b/core/src/main/java/hudson/cli/DeleteBuildsCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ package hudson.cli; import hudson.Extension; import hudson.model.AbstractBuild; +import hudson.model.Run; import java.io.IOException; import java.io.PrintStream; @@ -51,6 +52,8 @@ public class DeleteBuildsCommand extends AbstractBuildRangeCommand { @Override protected int act(List> builds) throws IOException { + job.checkPermission(Run.DELETE); + for (AbstractBuild build : builds) build.delete(); diff --git a/core/src/main/java/hudson/cli/GroovyshCommand.java b/core/src/main/java/hudson/cli/GroovyshCommand.java index fab488013b0fb2435033d42b3361ae1b73e6a565..a3703a8d8b0b68fdeabe5b798d187101461577e2 100644 --- a/core/src/main/java/hudson/cli/GroovyshCommand.java +++ b/core/src/main/java/hudson/cli/GroovyshCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,6 @@ import hudson.model.Hudson; import hudson.remoting.ChannelClosedException; import groovy.lang.Binding; import groovy.lang.Closure; -import org.acegisecurity.Authentication; import org.codehaus.groovy.tools.shell.Groovysh; import org.codehaus.groovy.tools.shell.IO; import org.codehaus.groovy.tools.shell.Shell; @@ -60,6 +59,8 @@ public class GroovyshCommand extends CLICommand { public int main(List args, Locale locale, InputStream stdin, PrintStream stdout, PrintStream stderr) { // this allows the caller to manipulate the JVM state, so require the admin privilege. Hudson.getInstance().checkPermission(Hudson.ADMINISTER); + // TODO: ^as this class overrides main() (which has authentication stuff), + // how to get ADMIN permission for this command? // this being remote means no jline capability is available System.setProperty("jline.terminal", UnsupportedTerminal.class.getName()); diff --git a/core/src/main/java/hudson/cli/HelpCommand.java b/core/src/main/java/hudson/cli/HelpCommand.java index 5f1f344e7b1e1426b03817699c5022663a5c3605..8f87fafc9a62dfc2122f57ed7db463cc6c1b3d05 100644 --- a/core/src/main/java/hudson/cli/HelpCommand.java +++ b/core/src/main/java/hudson/cli/HelpCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,7 @@ package hudson.cli; import hudson.Extension; +import hudson.model.Hudson; import java.util.Map; import java.util.TreeMap; @@ -41,6 +42,12 @@ public class HelpCommand extends CLICommand { } protected int run() { + if (!Hudson.getInstance().hasPermission(Hudson.READ)) { + stderr.println("You must authenticate to access this Hudson.\n" + + "Use --username/--password/--password-file parameters or login command."); + return 0; + } + Map commands = new TreeMap(); for (CLICommand c : CLICommand.all()) commands.put(c.getName(),c); diff --git a/core/src/main/java/hudson/cli/InstallPluginCommand.java b/core/src/main/java/hudson/cli/InstallPluginCommand.java index 409c8914b21c2a4c78d8c0e09f5a70ce98fc13da..fac26b54060b3e51fdd147461237cdcdbb898deb 100644 --- a/core/src/main/java/hudson/cli/InstallPluginCommand.java +++ b/core/src/main/java/hudson/cli/InstallPluginCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -61,6 +61,9 @@ public class InstallPluginCommand extends CLICommand { public boolean restart; protected int run() throws Exception { + Hudson h = Hudson.getInstance(); + h.checkPermission(Hudson.ADMINISTER); + for (String source : sources) { // is this a file? FilePath f = new FilePath(channel, source); @@ -90,7 +93,7 @@ public class InstallPluginCommand extends CLICommand { } // is this a plugin the update center? - UpdateSite.Plugin p = Hudson.getInstance().getUpdateCenter().getPlugin(source); + UpdateSite.Plugin p = h.getUpdateCenter().getPlugin(source); if (p!=null) { stdout.println("Installing "+source+" from update center"); p.deploy().get(); @@ -102,7 +105,7 @@ public class InstallPluginCommand extends CLICommand { } if (restart) - Hudson.getInstance().restart(); + h.restart(); return 0; // all success } diff --git a/core/src/main/java/hudson/cli/InstallToolCommand.java b/core/src/main/java/hudson/cli/InstallToolCommand.java index 0320cca86d33f1a405a404becbdde658b388bb82..58693b84a914528981adc4e6cdda97a461ce6115 100644 --- a/core/src/main/java/hudson/cli/InstallToolCommand.java +++ b/core/src/main/java/hudson/cli/InstallToolCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,7 @@ import hudson.model.Run; import hudson.model.Executor; import hudson.model.Node; import hudson.model.EnvironmentSpecific; +import hudson.model.Item; import hudson.remoting.Callable; import hudson.slaves.NodeSpecific; import hudson.util.EditDistance; @@ -63,6 +64,20 @@ public class InstallToolCommand extends CLICommand { } protected int run() throws Exception { + Hudson h = Hudson.getInstance(); + h.checkPermission(Hudson.READ); + + // where is this build running? + BuildIDs id = channel.call(new BuildIDs()); + + if (!id.isComplete()) + throw new AbortException("This command can be only invoked from a build executing inside Hudson"); + + AbstractProject p = Hudson.getInstance().getItemByFullName(id.job, AbstractProject.class); + if (p==null) + throw new AbortException("No such job found: "+id.job); + p.checkPermission(Item.CONFIGURE); + List toolTypes = new ArrayList(); for (ToolDescriptor d : ToolInstallation.all()) { toolTypes.add(d.getDisplayName()); @@ -71,7 +86,7 @@ public class InstallToolCommand extends CLICommand { for (ToolInstallation t : d.getInstallations()) { toolNames.add(t.getName()); if (t.getName().equals(toolName)) - return install(t); + return install(t, id, p); } // didn't find the right tool name @@ -96,16 +111,7 @@ public class InstallToolCommand extends CLICommand { /** * Performs an installation. */ - private int install(ToolInstallation t) throws IOException, InterruptedException { - // where is this build running? - BuildIDs id = channel.call(new BuildIDs()); - - if (!id.isComplete()) - throw new AbortException("This command can be only invoked from a build executing inside Hudson"); - - AbstractProject p = Hudson.getInstance().getItemByFullName(id.job, AbstractProject.class); - if (p==null) - throw new AbortException("No such job found: "+id.job); + private int install(ToolInstallation t, BuildIDs id, AbstractProject p) throws IOException, InterruptedException { Run b = p.getBuildByNumber(Integer.parseInt(id.number)); if (b==null) diff --git a/core/src/main/java/hudson/cli/ListChangesCommand.java b/core/src/main/java/hudson/cli/ListChangesCommand.java index e0b61ed2052e13d7394f92bee0daebdaec357233..93a286ae89db5511c253fe09000d7eade941876f 100644 --- a/core/src/main/java/hudson/cli/ListChangesCommand.java +++ b/core/src/main/java/hudson/cli/ListChangesCommand.java @@ -40,6 +40,8 @@ public class ListChangesCommand extends AbstractBuildRangeCommand { @Override protected int act(List> builds) throws IOException { + // Loading job for this CLI command requires Item.READ permission. + // No other permission check needed. switch (format) { case XML: PrintWriter w = new PrintWriter(stdout); diff --git a/core/src/main/java/hudson/cli/MailCommand.java b/core/src/main/java/hudson/cli/MailCommand.java index 0fa5d7e8ca45b4e6d23b59cfa38e7d4bb1c59ac5..44a1b8fd1d4851d5c443427cf119c24f04e9ecf4 100644 --- a/core/src/main/java/hudson/cli/MailCommand.java +++ b/core/src/main/java/hudson/cli/MailCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,8 @@ package hudson.cli; import hudson.tasks.Mailer; import hudson.Extension; +import hudson.model.Hudson; +import hudson.model.Item; import javax.mail.internet.MimeMessage; import javax.mail.Transport; @@ -44,6 +46,7 @@ public class MailCommand extends CLICommand { } protected int run() throws Exception { + Hudson.getInstance().checkPermission(Item.CONFIGURE); Transport.send(new MimeMessage(Mailer.descriptor().createSession(),stdin)); return 0; } diff --git a/core/src/main/java/hudson/cli/SetBuildResultCommand.java b/core/src/main/java/hudson/cli/SetBuildResultCommand.java index ac3d024976d070203af4030a6367bbffd6f4ca7f..29aa4bf025654ec54eee3304527c2912612babb9 100644 --- a/core/src/main/java/hudson/cli/SetBuildResultCommand.java +++ b/core/src/main/java/hudson/cli/SetBuildResultCommand.java @@ -25,7 +25,9 @@ package hudson.cli; import hudson.Extension; +import hudson.model.Item; import hudson.model.Result; +import hudson.model.Run; import org.kohsuke.args4j.Argument; /** @@ -45,7 +47,9 @@ public class SetBuildResultCommand extends CommandDuringBuild { @Override protected int run() throws Exception { - getCurrentlyBuilding().setResult(result); + Run r = getCurrentlyBuilding(); + r.getParent().checkPermission(Item.BUILD); + r.setResult(result); return 0; } } diff --git a/core/src/main/java/hudson/cli/VersionCommand.java b/core/src/main/java/hudson/cli/VersionCommand.java index ce735a77f25fe3d97b79b34a9a5e28f25adf547d..fe7aa96121821621d8f99833a264e9884f4ce391 100644 --- a/core/src/main/java/hudson/cli/VersionCommand.java +++ b/core/src/main/java/hudson/cli/VersionCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,6 +39,7 @@ public class VersionCommand extends CLICommand { } protected int run() { + // CLICommand.main checks Hudson.READ permission.. no other check needed. stdout.println(Hudson.VERSION); return 0; } diff --git a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java index 67e339764588eff5259c341c34cb0fe6f92dce33..4b84b5f7e026494af669417be91fd63b3ca260e8 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java +++ b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2004-2010, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -149,6 +149,7 @@ public class CLIRegisterer extends ExtensionFinder { parser.parseArgument(args); sc.setAuthentication(authenticator.authenticate()); // run the CLI with the right credential + hudson.checkPermission(Hudson.READ); // resolve them Object instance = null; diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index db40bd7b70993cd38e4f5e94bc9ab73e61dcff40..fcda31458e42dc4aad9fcecd960cf8c266365080 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -1,7 +1,8 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Daniel Dyer, Tom Huybrechts + * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, + * Daniel Dyer, Tom Huybrechts * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -243,11 +244,13 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet /** * Deletes this item. */ + @CLIMethod(name="delete-job") public void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, InterruptedException { checkPermission(DELETE); requirePOST(); delete(); - rsp.sendRedirect2(req.getContextPath()+"/"+getParent().getUrl()); + if (rsp != null) // null for CLI + rsp.sendRedirect2(req.getContextPath()+"/"+getParent().getUrl()); } public void delete( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { @@ -262,7 +265,6 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet /** * Deletes this item. */ - @CLIMethod(name="delete-job") public synchronized void delete() throws IOException, InterruptedException { performDelete(); diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index d1b14a23ebba770787a75cfe6ff00a086db1a288..a44ce04ef614af27b6ff78323f86a3fb42bcd816 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -1,7 +1,9 @@ /* * The MIT License * - * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Erik Ramfelt, Ertan Deniz, Jean-Baptiste Quenot, Luca Domenico Milanesio, R. Tyler Ballance, Stephen Connolly, Tom Huybrechts, id:cactusman + * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, + * Brian Westrich, Erik Ramfelt, Ertan Deniz, Jean-Baptiste Quenot, + * Luca Domenico Milanesio, R. Tyler Ballance, Stephen Connolly, Tom Huybrechts, id:cactusman * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -503,12 +505,10 @@ public abstract class AbstractProject

,R extends A save(); } - @CLIMethod(name="disable-job") public void disable() throws IOException { makeDisabled(true); } - @CLIMethod(name="enable-job") public void enable() throws IOException { makeDisabled(false); } @@ -1572,6 +1572,7 @@ public abstract class AbstractProject

,R extends A } } + @CLIMethod(name="disable-job") public HttpResponse doDisable() throws IOException, ServletException { requirePOST(); checkPermission(CONFIGURE); @@ -1579,6 +1580,7 @@ public abstract class AbstractProject

,R extends A return new HttpRedirect("."); } + @CLIMethod(name="enable-job") public HttpResponse doEnable() throws IOException, ServletException { requirePOST(); checkPermission(CONFIGURE); diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index a79cdbb6cb463049709ceb98caf16b0f4bc4530c..0ffa44d15329ba9120330a9dd4249062ce650c05 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -1,7 +1,8 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts + * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, + * Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -281,6 +282,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces */ @CLIMethod(name="connect-node") public void cliConnect(@Option(name="-f",usage="Cancel any currently pending connect operation and retry from scratch") boolean force) throws ExecutionException, InterruptedException { + checkPermission(Hudson.ADMINISTER); connect(force).get(); } @@ -336,6 +338,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces */ @CLIMethod(name="disconnect-node") public void cliDisconnect(@Option(name="-m",usage="Record the note about why you are disconnecting this node") String cause) throws ExecutionException, InterruptedException { + checkPermission(Hudson.ADMINISTER); disconnect(new ByCLI(cause)).get(); } @@ -344,11 +347,13 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces */ @CLIMethod(name="offline-node") public void cliOffline(@Option(name="-m",usage="Record the note about why you are disconnecting this node") String cause) throws ExecutionException, InterruptedException { + checkPermission(Hudson.ADMINISTER); setTemporarilyOffline(true,new ByCLI(cause)); } @CLIMethod(name="online-node") public void cliOnline() throws ExecutionException, InterruptedException { + checkPermission(Hudson.ADMINISTER); setTemporarilyOffline(false,null); } diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 8b81ca4b4d8293551118392fa88dbfd47963a44b..5217a135de1a028f5a5df3c3d11480b05c70e040 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -152,6 +152,7 @@ import org.jvnet.hudson.reactor.Milestone; import org.jvnet.hudson.reactor.Reactor; import org.jvnet.hudson.reactor.ReactorListener; import org.jvnet.hudson.reactor.TaskGraphBuilder.Handle; +import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import org.kohsuke.stapler.Ancestor; import org.kohsuke.stapler.HttpRedirect; @@ -1340,7 +1341,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl } @CLIResolver - public Computer getComputer(String name) { + public Computer getComputer(@Argument(required=true,metaVar="NAME",usage="Node name") String name) { if(name.equals("(master)")) name = ""; @@ -2862,6 +2863,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl * For debugging. Expose URL to perform GC. */ public void doGc(StaplerResponse rsp) throws IOException { + checkPermission(Hudson.ADMINISTER); System.gc(); rsp.setStatus(HttpServletResponse.SC_OK); rsp.setContentType("text/plain"); @@ -2874,7 +2876,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl * Handles HTTP requests for duplex channels for CLI. */ public void doCli(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { - if(!"POST".equals(Stapler.getCurrentRequest().getMethod())) { + if (!"POST".equals(req.getMethod())) { // for GET request, serve _cli.jelly, assuming this is a browser checkPermission(READ); req.getView(this,"_cli.jelly").forward(req,rsp); @@ -2918,16 +2920,18 @@ public final class Hudson extends Node implements ItemGroup, Stapl * * This first replaces "app" to {@link HudsonIsRestarting} */ + @CLIMethod(name="restart") public void doRestart(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, RestartNotSupportedException { checkPermission(ADMINISTER); - if(Stapler.getCurrentRequest().getMethod().equals("GET")) { + if (req != null && req.getMethod().equals("GET")) { req.getView(this,"_restart.jelly").forward(req,rsp); return; } restart(); - rsp.sendRedirect2("."); + if (rsp != null) // null for CLI + rsp.sendRedirect2("."); } /** @@ -2937,22 +2941,23 @@ public final class Hudson extends Node implements ItemGroup, Stapl * * @since 1.332 */ + @CLIMethod(name="safe-restart") public void doSafeRestart(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, RestartNotSupportedException { checkPermission(ADMINISTER); - if(Stapler.getCurrentRequest().getMethod().equals("GET")) { + if (req != null && req.getMethod().equals("GET")) { req.getView(this,"_safeRestart.jelly").forward(req,rsp); return; } safeRestart(); - rsp.sendRedirect2("."); + if (rsp != null) // null for CLI + rsp.sendRedirect2("."); } /** * Performs a restart. */ - @CLIMethod(name="restart") public void restart() throws RestartNotSupportedException { final Lifecycle lifecycle = Lifecycle.get(); lifecycle.verifyRestartable(); // verify that Hudson is restartable @@ -2982,7 +2987,6 @@ public final class Hudson extends Node implements ItemGroup, Stapl * Queues up a restart to be performed once there are no builds currently running. * @since 1.332 */ - @CLIMethod(name="safe-restart") public void safeRestart() throws RestartNotSupportedException { final Lifecycle lifecycle = Lifecycle.get(); lifecycle.verifyRestartable(); // verify that Hudson is restartable diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index fc6e08d9915668058cec65794f14fbaba762fc70..d392f283261c6467ec1d565a5f89f019cffec5ae 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -335,6 +335,7 @@ public class Queue extends ResourceController implements Saveable { */ @CLIMethod(name="clear-queue") public synchronized void clear() { + Hudson.getInstance().checkPermission(Hudson.ADMINISTER); for (WaitingItem i : waitingList) i.onCancelled(); waitingList.clear(); diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index 6349f81209eb96e46ffcdc3ab9cf76d362b5b016..e9862a4c734636a01270f60bcf71aaf0bab8f267 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -1553,8 +1553,6 @@ public abstract class Run ,RunT extends Run,RunT extends Run