mirror of https://github.com/jenkinsci/jenkins.git
Render /manage using ManageJenkinsAction, handle links using StaplerF… (#6126)
Co-authored-by: Daniel Beck <daniel-beck@users.noreply.github.com> Co-authored-by: Basil Crow <me@basilcrow.com> Co-authored-by: Tim Jacomb <timjacomb1+github@gmail.com> Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>
This commit is contained in:
parent
788aaadb2f
commit
a990ebcda4
|
@ -25,8 +25,18 @@
|
|||
package hudson.model;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.Util;
|
||||
import java.io.IOException;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.model.ModelObjectWithContextMenu;
|
||||
import org.apache.commons.jelly.JellyException;
|
||||
import org.jenkinsci.Symbol;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerFallback;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
|
||||
/**
|
||||
* Adds the "Manage Jenkins" link to the top page.
|
||||
|
@ -34,7 +44,7 @@ import org.jenkinsci.Symbol;
|
|||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@Extension(ordinal = 100) @Symbol("manageJenkins")
|
||||
public class ManageJenkinsAction implements RootAction {
|
||||
public class ManageJenkinsAction implements RootAction, StaplerFallback, ModelObjectWithContextMenu {
|
||||
@Override
|
||||
public String getIconFileName() {
|
||||
if (Jenkins.get().hasAnyPermission(Jenkins.MANAGE, Jenkins.SYSTEM_READ))
|
||||
|
@ -52,4 +62,29 @@ public class ManageJenkinsAction implements RootAction {
|
|||
public String getUrlName() {
|
||||
return "/manage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getStaplerFallback() {
|
||||
return Jenkins.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws JellyException, IOException {
|
||||
return new ContextMenu().from(this, request, response, "index");
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround to ensuring that links in context menus resolve correctly in the submenu of the top-level 'Dashboard'
|
||||
* menu.
|
||||
*/
|
||||
@Restricted(NoExternalUse.class)
|
||||
public void addContextMenuItem(ContextMenu menu, String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation) {
|
||||
if (Stapler.getCurrentRequest().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) {
|
||||
// Default behavior if the URL is absolute or scheme-relative, or the current object is an ancestor (i.e. would resolve correctly)
|
||||
menu.add(url, icon, iconXml, text, post, requiresConfirmation);
|
||||
return;
|
||||
}
|
||||
// If neither is the case, rewrite the relative URL to point to inside the /manage/ URL space
|
||||
menu.add("manage/" + url, icon, iconXml, text, post, requiresConfirmation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ import hudson.model.Label;
|
|||
import hudson.model.ListView;
|
||||
import hudson.model.LoadBalancer;
|
||||
import hudson.model.LoadStatistics;
|
||||
import hudson.model.ManageJenkinsAction;
|
||||
import hudson.model.ManagementLink;
|
||||
import hudson.model.Messages;
|
||||
import hudson.model.ModifiableViewGroup;
|
||||
|
@ -4415,7 +4416,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
|
|||
for (MenuItem i : menu.items) {
|
||||
if (i.url.equals(request.getContextPath() + "/manage")) {
|
||||
// add "Manage Jenkins" subitems
|
||||
i.subMenu = new ContextMenu().from(this, request, response, "manage");
|
||||
i.subMenu = new ContextMenu().from(ExtensionList.lookupSingleton(ManageJenkinsAction.class), request, response, "index");
|
||||
}
|
||||
}
|
||||
return menu;
|
||||
|
|
|
@ -30,7 +30,7 @@ l.side_panel {
|
|||
l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard"))
|
||||
l.task(icon:"symbol-settings", href:"${rootURL}/manage", title:_("Manage Jenkins"))
|
||||
if (!app.updateCenter.jobs.isEmpty()) {
|
||||
l.task(icon: "symbol-download", href:"${rootURL}/updateCenter/", title:_("Update Center"))
|
||||
l.task(icon: "symbol-download", href:"../updateCenter/", title:_("Update Center"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ THE SOFTWARE.
|
|||
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"/>
|
||||
<l:task href="${rootURL}/manage" icon="symbol-settings" permissions="${app.MANAGE_AND_SYSTEM_READ}" title="${%Manage Jenkins}"/>
|
||||
<l:task href="new" icon="symbol-add" permission="${createPermission}" title="${%New Node}"/>
|
||||
<l:task href="${rootURL}/configureClouds" icon="symbol-cloud" permission="${app.SYSTEM_READ}"
|
||||
<l:task href="../configureClouds" icon="symbol-cloud" permission="${app.SYSTEM_READ}"
|
||||
title="${app.hasPermission(app.ADMINISTER) ? '%Configure Clouds' : '%View Clouds'}"/>
|
||||
<l:task href="configure" icon="symbol-settings" permissions="${app.MANAGE_AND_SYSTEM_READ}" title="${%Node Monitoring}"/>
|
||||
</l:tasks>
|
||||
|
|
|
@ -31,7 +31,7 @@ THE SOFTWARE.
|
|||
<l:app-bar title="${%Manage Jenkins}" />
|
||||
|
||||
<j:if test="${taskTags==null}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
<st:include page="sidepanel.jelly" it="${app}" />
|
||||
</j:if>
|
||||
|
||||
<l:main-panel>
|
||||
|
@ -39,10 +39,10 @@ THE SOFTWARE.
|
|||
<j:forEach var="am" items="${app.activeAdministrativeMonitors}">
|
||||
<st:include page="message.jelly" it="${am}" />
|
||||
</j:forEach>
|
||||
<st:include page="downgrade.jelly" />
|
||||
<st:include page="downgrade.jelly" it="${app}" />
|
||||
</section>
|
||||
|
||||
<j:forEach var="category" items="${it.categorizedManagementLinks.entrySet()}">
|
||||
<j:forEach var="category" items="${app.categorizedManagementLinks.entrySet()}">
|
||||
<section class="jenkins-section jenkins-section--bottom-padding">
|
||||
<h2 class="jenkins-section__title">${category.key.label}</h2>
|
||||
${taskTags!=null and attrs.contextMenu!='false' ? taskTags.addHeader(category.key.label) : null}
|
||||
|
@ -55,7 +55,7 @@ THE SOFTWARE.
|
|||
<j:set var="iconXml">
|
||||
<l:icon src="${m.iconFileName}" />
|
||||
</j:set>
|
||||
${taskTags!=null and attrs.contextMenu!='false' ? taskTags.add(m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation) : null}
|
||||
${taskTags!=null and attrs.contextMenu!='false' ? it.addContextMenuItem(taskTags, m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation) : null}
|
||||
<j:choose>
|
||||
<j:when test="${m.requiresConfirmation}">
|
||||
<l:confirmationLink href="${m.urlName}" post="${m.requiresPOST}" message="${%are.you.sure(m.displayName)}">
|
|
@ -32,7 +32,7 @@ THE SOFTWARE.
|
|||
<l:tasks>
|
||||
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"/>
|
||||
<l:task href="${rootURL}/manage" icon="symbol-settings" title="${%Manage Jenkins}"/>
|
||||
<l:task href="${rootURL}/pluginManager/" icon="icon-plugin icon-lg" title="${%Manage Plugins}"/>
|
||||
<l:task href="../pluginManager/" icon="icon-plugin icon-lg" title="${%Manage Plugins}"/>
|
||||
</l:tasks>
|
||||
</l:side-panel>
|
||||
</j:jelly>
|
||||
|
|
|
@ -13,7 +13,7 @@ l.layout(norefresh:true, permission:app.SYSTEM_READ, title:my.displayName) {
|
|||
l.side_panel {
|
||||
l.tasks {
|
||||
l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard"))
|
||||
l.task(icon:"symbol-settings", href:"${rootURL}/computer/", title:_("Manage Nodes"))
|
||||
l.task(icon:"symbol-settings", href: "../computer/", title:_("Manage Nodes"))
|
||||
}
|
||||
}
|
||||
l.app_bar(title: my.displayName)
|
||||
|
|
|
@ -26,9 +26,10 @@ THE SOFTWARE.
|
|||
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
|
||||
<l:layout title="${it.displayName} ${%Load Statistics}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
<l:breadcrumb title="${%Load Statistics}"/>
|
||||
<l:main-panel>
|
||||
<j:set var="prefix" value="overallLoad" />
|
||||
<st:include page="main.jelly" from="${it.overallLoad}" />
|
||||
</l:main-panel>
|
||||
</l:layout>
|
||||
</j:jelly>
|
||||
</j:jelly>
|
||||
|
|
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
|||
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
|
||||
<l:layout permissions="${app.MANAGE_AND_SYSTEM_READ}" title="${%System Information}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
<l:breadcrumb title="${%System Information}"/>
|
||||
<l:main-panel>
|
||||
<l:hasPermission permission="${app.SYSTEM_READ}">
|
||||
<div class="jenkins-app-bar">
|
||||
|
|
|
@ -30,6 +30,7 @@ THE SOFTWARE.
|
|||
<l:layout permission="${h.ADMINISTER}" title="${%Script Console}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
|
||||
<l:breadcrumb title="${%Script Console}"/>
|
||||
<l:main-panel>
|
||||
<h1>${%Script Console}</h1>
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ public class Jenkins64991Test {
|
|||
|
||||
final Page redirectedPage = HtmlFormUtil.submit(loginPage.getFormByName("login"));
|
||||
assertTrue(redirectedPage.isHtmlPage());
|
||||
assertEquals(j.getURL() + "manage", redirectedPage.getUrl().toExternalForm());
|
||||
assertEquals(j.getURL() + "manage/", redirectedPage.getUrl().toExternalForm());
|
||||
assertThat(redirectedPage.getWebResponse().getContentAsString(), containsStringIgnoringCase(Messages.GlobalSecurityConfiguration_DisplayName()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue