diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 2d47c1b9c2..6e893e2979 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -189,6 +189,10 @@ public class Functions { return Node.Mode.values(); } + public static Node.JNLPSecurityMode[] getJNLPSecurityModes() { + return Node.JNLPSecurityMode.values(); + } + public static String getProjectListString(List projects) { return Items.toNameList(projects); } @@ -196,7 +200,7 @@ public class Functions { public static Object ifThenElse(boolean cond, Object thenValue, Object elseValue) { return cond ? thenValue : elseValue; } - + public static String appendIfNotNull(String text, String suffix, String nullText) { return text == null ? nullText : text + suffix; } @@ -271,7 +275,7 @@ public class Functions { * * @param noAutoRefresh * On certain pages, like a page with forms, will have annoying interference - * with auto refresh. On those pages, disable auto-refresh. + * with auto refresh. On those pages, disable auto-refresh. */ public static void configureAutoRefresh(HttpServletRequest request, HttpServletResponse response, boolean noAutoRefresh) { if(noAutoRefresh) diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index 56674dcba3..579bff42fd 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -118,6 +118,30 @@ public abstract class Computer implements ModelObject { return false; } + /** + * Returns true if this computer is needs to be launched via JNLP. That is if the Launch slave agent link should be + * visible. + * @return true if and only if the JNLP link should be shown. + */ + public boolean isJnlpAgentLaunchVisible() { + return isJnlpAgent() && isOffline() && !isTemporarilyOffline(); + } + + /** + * Returns true if the JNLP link should be restricted to authenticated in users. + * @return true if and only if the JNLP link should be restricted to authenticated users. + */ + public boolean isJnlpAgentLaunchAdminOnly() { + return true; + } + + /** + * Returns true if the JNLP link should be visible from the main page. + * @return true if and only if the JNLP link should be availible from the main page. + */ + public boolean isJnlpAgentLaunchPublic() { + return false; + } /** * Returns true if this node is marked temporarily offline by the user. * @@ -291,7 +315,7 @@ public abstract class Computer implements ModelObject { } private static final long serialVersionUID = 1L; } - + public static final ExecutorService threadPoolForRemoting = Executors.newCachedThreadPool(new DaemonThreadFactory()); @@ -309,7 +333,7 @@ public abstract class Computer implements ModelObject { private void rss(StaplerRequest req, StaplerResponse rsp, String suffix, RunList runs) throws IOException, ServletException { RSS.forwardToRss(getDisplayName()+ suffix, getUrl(), runs.newBuilds(), Run.FEED_ADAPTER, req, rsp ); - } + } public void doToggleOffline( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { if(!Hudson.adminCheck(req,rsp)) diff --git a/core/src/main/java/hudson/model/Node.java b/core/src/main/java/hudson/model/Node.java index f38da8a6f3..00554f5371 100644 --- a/core/src/main/java/hudson/model/Node.java +++ b/core/src/main/java/hudson/model/Node.java @@ -90,4 +90,51 @@ public interface Node { ConvertUtils.register(new EnumConverter(),Mode.class); } } + + enum JNLPSecurityMode { + NORMAL("Launch only from Computer detail. Require Login if security enabled.", true, false, false), + SECURE_PUBLIC("Launch from front page. Require Login if security enabled.", true, false, false), + BYPASS("Launch only from Computer detail. Login never required.", false, false, false), + PUBLIC("Launch from front page. Login never required.", false, true, false)/*, + + // stephenconnolly: holding off on these next changes until they are closer to ready + DYNAMIC("Dynamic secure slave (experimental)", true, true, true), + DYNAMIC("Dynamic public slave (experimental)", false, true, true)*/; + + private final String description; + private final boolean enforceSecurity; + private final boolean publicLaunch; + private final boolean dynammicPool; + + public String getDescription() { + return description; + } + + public String getName() { + return name(); + } + + public boolean isEnforceSecurity() { + return enforceSecurity; + } + + public boolean isPublicLaunch() { + return publicLaunch; + } + + public boolean isDynammicPool() { + return dynammicPool; + } + + JNLPSecurityMode(String description, boolean enforceSecurity, boolean publicLaunch, boolean dynammicPool) { + this.description = description; + this.enforceSecurity = enforceSecurity; + this.publicLaunch = publicLaunch; + this.dynammicPool = dynammicPool; + } + + static { + ConvertUtils.register(new EnumConverter(), JNLPSecurityMode.class); + } + } } diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 9a63fb3a4a..f11e5ffbdc 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -72,6 +72,11 @@ public final class Slave implements Node, Serializable { */ private Mode mode; + /** + * JNLP Security mode + */ + private JNLPSecurityMode jnlpSecurity; + /** * Command line to launch the agent, like * "ssh myslave java -jar /path/to/hudson-remoting.jar" @@ -91,13 +96,15 @@ public final class Slave implements Node, Serializable { /** * @stapler-constructor */ - public Slave(String name, String description, String command, String remoteFS, int numExecutors, Mode mode, String label) throws FormException { + public Slave(String name, String description, String command, String remoteFS, int numExecutors, Mode mode, + String label, JNLPSecurityMode jnlpSecurity) throws FormException { this.name = name; this.description = description; this.numExecutors = numExecutors; this.mode = mode; this.agentCommand = command; this.remoteFS = remoteFS; + this.jnlpSecurity = jnlpSecurity; this.label = Util.fixNull(label).trim(); getAssignedLabels(); // compute labels now @@ -130,7 +137,7 @@ public final class Slave implements Node, Serializable { } /** - * Gets the root directory of the Hudson workspace on this slave. + * Gets the root directory of the Hudson workspace on this slave. */ public FilePath getFilePath() { return new FilePath(getComputer().getChannel(),remoteFS); @@ -144,6 +151,10 @@ public final class Slave implements Node, Serializable { return mode; } + public JNLPSecurityMode getJnlpSecurity() { + return jnlpSecurity; + } + public String getLabelString() { return Util.fixNull(label).trim(); } @@ -259,6 +270,44 @@ public final class Slave implements Node, Serializable { return getNode().getCommand().length()==0; } + + /** + * Returns true if this computer is needs to be launched via JNLP. That is if the Launch slave agent link should be + * visible. + * + * @return true if and only if the JNLP link should be shown. + */ + @Override + public boolean isJnlpAgentLaunchVisible() { + if (getNode().getJnlpSecurity().isDynammicPool()) { + return isJnlpAgent(); + } + return super.isJnlpAgentLaunchVisible(); + } + + /** + * Returns true if the JNLP link should be restricted to authenticated in users. + * + * @return true if and only if the JNLP link should be restricted to authenticated users. + */ + @Override + public boolean isJnlpAgentLaunchAdminOnly() { + return getNode().getJnlpSecurity().isEnforceSecurity(); + } + + /** + * Returns true if the JNLP link should be visible from the main page. + * + * @return true if and only if the JNLP link should be availible from the main page. + */ + @Override + public boolean isJnlpAgentLaunchPublic() { + if (getNode().getJnlpSecurity().isPublicLaunch()) { + return isJnlpAgent(); + } + return super.isJnlpAgentLaunchPublic(); //To change body of overridden methods use File | Settings | File Templates. + } + /** * Launches a remote agent. */ diff --git a/core/src/main/resources/hudson/model/Computer/index.jelly b/core/src/main/resources/hudson/model/Computer/index.jelly index 0cb817fe91..70c15f23d4 100644 --- a/core/src/main/resources/hudson/model/Computer/index.jelly +++ b/core/src/main/resources/hudson/model/Computer/index.jelly @@ -22,8 +22,8 @@ - - + +

launch agent @@ -33,7 +33,7 @@

(Click the above link from this slave computer to launch the slave agent via JNLP)

-
+

diff --git a/core/src/main/resources/hudson/model/Hudson/configure.jelly b/core/src/main/resources/hudson/model/Hudson/configure.jelly index e92b8b650d..02276778e4 100644 --- a/core/src/main/resources/hudson/model/Hudson/configure.jelly +++ b/core/src/main/resources/hudson/model/Hudson/configure.jelly @@ -39,7 +39,7 @@ - + @@ -88,7 +88,15 @@ - + + + + +

diff --git a/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly b/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly index 4f137ff9b9..91931ce68b 100644 --- a/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly +++ b/core/src/main/resources/hudson/model/Slave/ComputerImpl/slave-agent.jnlp.jelly @@ -7,7 +7,7 @@ - + @@ -35,5 +35,5 @@ ${it.node.nodeName} - + diff --git a/core/src/main/resources/lib/hudson/executors.jelly b/core/src/main/resources/lib/hudson/executors.jelly index e1a44b2528..4404f91e59 100644 --- a/core/src/main/resources/lib/hudson/executors.jelly +++ b/core/src/main/resources/lib/hudson/executors.jelly @@ -26,8 +26,18 @@ ${c.displayName} - (offline) - + (offline) + + + + + Launch + + + + + + diff --git a/core/src/main/resources/lib/layout/isAdminOrTest.jelly b/core/src/main/resources/lib/layout/isAdminOrTest.jelly new file mode 100644 index 0000000000..90a29a9f81 --- /dev/null +++ b/core/src/main/resources/lib/layout/isAdminOrTest.jelly @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/war/resources/help/system-config/master-slave/jnlpSecurity.html b/war/resources/help/system-config/master-slave/jnlpSecurity.html new file mode 100644 index 0000000000..0768abf674 --- /dev/null +++ b/war/resources/help/system-config/master-slave/jnlpSecurity.html @@ -0,0 +1,41 @@ +
+ Controls how Hudson permits launching via JNLP. + +
+
+ Launch only from Computer detail. Require Login if security enabled. +
+
+ This is the default and normal setting. + In this mode, Hudson provides the JNLP launch link on the computer view. + If Security is enabled, then the link will only be available to authenticated users. +
+ +
+ Launch from front page. Require Login if security enabled. +
+
+ In this mode, Hudson provides the JNLP launch link on both the computer view and the Build Executor Status + sidepanel. + If Security is enabled, then the link will only be available to authenticated users. +
+ +
+ Launch only from Computer detail. Login never required. +
+
+ In this mode, Hudson provides the JNLP launch link on the computer view. + The link will always be available whenever the slave is offline. +
+ +
+ Launch from front page. Login never required. +
+
+ In this mode, Hudson provides the JNLP launch link on both the computer view and the Build Executor Status + sidepanel. + The link will always be available whenever the slave is offline. +
+ +
+
\ No newline at end of file