mirror of https://github.com/jenkinsci/jenkins.git
`AdministrativeMonitorsDecorator` cleanup; `ManageJenkinsAction.getBadge` optimization (#10855)
This commit is contained in:
parent
3bf037ca07
commit
00c6707c45
|
@ -66,6 +66,11 @@ public class ReverseProxySetupMonitor extends AdministrativeMonitor {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActivationFake() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Restricted(DoNotUse.class) // WebOnly
|
||||
@RestrictedSince("2.235")
|
||||
public HttpResponse doTest(StaplerRequest2 request, @QueryParameter boolean testWithContext) {
|
||||
|
|
|
@ -160,6 +160,11 @@ public abstract class AdministrativeMonitor extends AbstractModelObject implemen
|
|||
*/
|
||||
public abstract boolean isActivated();
|
||||
|
||||
@Restricted(NoExternalUse.class)
|
||||
public boolean isActivationFake() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this monitor is security related.
|
||||
*
|
||||
|
@ -186,8 +191,7 @@ public abstract class AdministrativeMonitor extends AbstractModelObject implemen
|
|||
* By default {@link Jenkins#ADMINISTER}, but {@link Jenkins#SYSTEM_READ} or {@link Jenkins#MANAGE} are also supported.
|
||||
* <p>
|
||||
* Changing this permission check to return {@link Jenkins#SYSTEM_READ} will make the active
|
||||
* administrative monitor appear on {@code manage.jelly} and on the globally visible
|
||||
* {@link jenkins.management.AdministrativeMonitorsDecorator} to users without Administer permission.
|
||||
* administrative monitor appear on {@link ManageJenkinsAction} to users without Administer permission.
|
||||
* {@link #doDisable(StaplerRequest2, StaplerResponse2)} will still always require Administer permission.
|
||||
* </p>
|
||||
* <p>
|
||||
|
|
|
@ -26,11 +26,11 @@ package hudson.model;
|
|||
|
||||
import hudson.Extension;
|
||||
import hudson.Util;
|
||||
import hudson.util.HudsonIsLoading;
|
||||
import hudson.util.HudsonIsRestarting;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import jenkins.management.AdministrativeMonitorsDecorator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import jenkins.management.Badge;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.model.ModelObjectWithContextMenu;
|
||||
|
@ -50,6 +50,9 @@ import org.kohsuke.stapler.StaplerResponse2;
|
|||
*/
|
||||
@Extension(ordinal = 998) @Symbol("manageJenkins")
|
||||
public class ManageJenkinsAction implements RootAction, StaplerFallback, ModelObjectWithContextMenu {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ManageJenkinsAction.class.getName());
|
||||
|
||||
@Override
|
||||
public String getIconFileName() {
|
||||
if (Jenkins.get().hasAnyPermission(Jenkins.MANAGE, Jenkins.SYSTEM_READ))
|
||||
|
@ -98,28 +101,36 @@ public class ManageJenkinsAction implements RootAction, StaplerFallback, ModelOb
|
|||
menu.add("manage/" + url, icon, iconXml, text, post, requiresConfirmation, badge, message);
|
||||
}
|
||||
|
||||
/** Unlike {@link Jenkins#getActiveAdministrativeMonitors} this checks for activation lazily. */
|
||||
@Override
|
||||
public Badge getBadge() {
|
||||
Jenkins jenkins = Jenkins.get();
|
||||
AdministrativeMonitorsDecorator decorator = jenkins.getExtensionList(PageDecorator.class)
|
||||
.get(AdministrativeMonitorsDecorator.class);
|
||||
|
||||
if (decorator == null) {
|
||||
if (!(AdministrativeMonitor.hasPermissionToDisplay())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Collection<AdministrativeMonitor> activeAdministrativeMonitors = Optional.ofNullable(decorator.getMonitorsToDisplay()).orElse(Collections.emptyList());
|
||||
boolean anySecurity = activeAdministrativeMonitors.stream().anyMatch(AdministrativeMonitor::isSecurity);
|
||||
|
||||
if (activeAdministrativeMonitors.isEmpty()) {
|
||||
var app = Jenkins.get().getServletContext().getAttribute("app");
|
||||
if (app instanceof HudsonIsLoading || app instanceof HudsonIsRestarting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int size = activeAdministrativeMonitors.size();
|
||||
String tooltip = size > 1 ? Messages.ManageJenkinsAction_notifications(size) : Messages.ManageJenkinsAction_notification(size);
|
||||
if (Jenkins.get().administrativeMonitors.stream().anyMatch(m -> m.isSecurity() && isActive(m))) {
|
||||
return new Badge("1+", Messages.ManageJenkinsAction_notifications(),
|
||||
Badge.Severity.DANGER);
|
||||
} else if (Jenkins.get().administrativeMonitors.stream().anyMatch(m -> !m.isSecurity() && isActive(m))) {
|
||||
return new Badge("1+", Messages.ManageJenkinsAction_notifications(),
|
||||
Badge.Severity.WARNING);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new Badge(String.valueOf(size),
|
||||
tooltip,
|
||||
anySecurity ? Badge.Severity.DANGER : Badge.Severity.WARNING);
|
||||
private static boolean isActive(AdministrativeMonitor m) {
|
||||
try {
|
||||
return !m.isActivationFake() && m.hasRequiredPermission() && m.isEnabled() && m.isActivated();
|
||||
} catch (Throwable x) {
|
||||
LOGGER.log(Level.WARNING, null, x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ public class URICheckEncodingMonitor extends AdministrativeMonitor {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActivationFake() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return Messages.URICheckEncodingMonitor_DisplayName();
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package jenkins.management;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.model.PageDecorator;
|
||||
import hudson.model.RootAction;
|
||||
import jakarta.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.stapler.StaplerRequest2;
|
||||
import org.kohsuke.stapler.StaplerResponse2;
|
||||
import org.kohsuke.stapler.verb.GET;
|
||||
|
||||
@Extension
|
||||
@Restricted(NoExternalUse.class)
|
||||
public class AdministrativeMonitorsApi implements RootAction {
|
||||
@GET
|
||||
public void doNonSecurityPopupContent(StaplerRequest2 req, StaplerResponse2 resp) throws IOException, ServletException {
|
||||
AdministrativeMonitorsApiData viewData = new AdministrativeMonitorsApiData(getDecorator().getNonSecurityAdministrativeMonitors());
|
||||
req.getView(viewData, "monitorsList.jelly").forward(req, resp);
|
||||
}
|
||||
|
||||
@GET
|
||||
public void doSecurityPopupContent(StaplerRequest2 req, StaplerResponse2 resp) throws IOException, ServletException {
|
||||
AdministrativeMonitorsApiData viewData = new AdministrativeMonitorsApiData(getDecorator().getSecurityAdministrativeMonitors());
|
||||
req.getView(viewData, "monitorsList.jelly").forward(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIconFileName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrlName() {
|
||||
return "administrativeMonitorsApi";
|
||||
}
|
||||
|
||||
private AdministrativeMonitorsDecorator getDecorator() {
|
||||
return Jenkins.get()
|
||||
.getExtensionList(PageDecorator.class)
|
||||
.get(AdministrativeMonitorsDecorator.class);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package jenkins.management;
|
||||
|
||||
import hudson.model.AdministrativeMonitor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
@Restricted(NoExternalUse.class)
|
||||
public class AdministrativeMonitorsApiData {
|
||||
private final List<AdministrativeMonitor> monitorsList = new ArrayList<>();
|
||||
|
||||
AdministrativeMonitorsApiData(List<AdministrativeMonitor> monitors) {
|
||||
monitorsList.addAll(monitors);
|
||||
}
|
||||
|
||||
public List<AdministrativeMonitor> getMonitorsList() {
|
||||
return this.monitorsList;
|
||||
}
|
||||
|
||||
public boolean hasActiveMonitors() {
|
||||
return !this.monitorsList.isEmpty();
|
||||
}
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2016, Daniel Beck, CloudBees, 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package jenkins.management;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import hudson.Extension;
|
||||
import hudson.diagnosis.ReverseProxySetupMonitor;
|
||||
import hudson.model.AdministrativeMonitor;
|
||||
import hudson.model.PageDecorator;
|
||||
import hudson.util.HudsonIsLoading;
|
||||
import hudson.util.HudsonIsRestarting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import jenkins.diagnostics.URICheckEncodingMonitor;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.stapler.Ancestor;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerRequest2;
|
||||
|
||||
/**
|
||||
* Show notifications and popups for active administrative monitors on all pages.
|
||||
*/
|
||||
@Extension
|
||||
@Restricted(NoExternalUse.class)
|
||||
public class AdministrativeMonitorsDecorator extends PageDecorator {
|
||||
private final Collection<String> ignoredJenkinsRestOfUrls = new ArrayList<>();
|
||||
|
||||
public AdministrativeMonitorsDecorator() {
|
||||
// otherwise this would be added to every internal context menu building request
|
||||
ignoredJenkinsRestOfUrls.add("contextMenu");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return Messages.AdministrativeMonitorsDecorator_DisplayName();
|
||||
}
|
||||
|
||||
// Used by Jelly
|
||||
public Collection<AdministrativeMonitor> filterNonSecurityAdministrativeMonitors(Collection<AdministrativeMonitor> activeMonitors) {
|
||||
return this.filterActiveAdministrativeMonitors(activeMonitors, false);
|
||||
}
|
||||
|
||||
// Used by Jelly
|
||||
public Collection<AdministrativeMonitor> filterSecurityAdministrativeMonitors(Collection<AdministrativeMonitor> activeMonitors) {
|
||||
return this.filterActiveAdministrativeMonitors(activeMonitors, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent us to compute multiple times the {@link AdministrativeMonitor#isActivated()} by re-using the same list
|
||||
*/
|
||||
private Collection<AdministrativeMonitor> filterActiveAdministrativeMonitors(Collection<AdministrativeMonitor> activeMonitors, boolean isSecurity) {
|
||||
Collection<AdministrativeMonitor> active = new ArrayList<>();
|
||||
for (AdministrativeMonitor am : activeMonitors) {
|
||||
if (am.isSecurity() == isSecurity) {
|
||||
active.add(am);
|
||||
}
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
// Used by API
|
||||
public List<AdministrativeMonitor> getNonSecurityAdministrativeMonitors() {
|
||||
Collection<AdministrativeMonitor> allowedMonitors = getMonitorsToDisplay();
|
||||
|
||||
if (allowedMonitors == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return allowedMonitors.stream()
|
||||
.filter(administrativeMonitor -> !administrativeMonitor.isSecurity())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Used by API
|
||||
public List<AdministrativeMonitor> getSecurityAdministrativeMonitors() {
|
||||
Collection<AdministrativeMonitor> allowedMonitors = getMonitorsToDisplay();
|
||||
|
||||
if (allowedMonitors == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return allowedMonitors.stream()
|
||||
.filter(AdministrativeMonitor::isSecurity)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Collection<AdministrativeMonitor> getAllActiveAdministrativeMonitors() {
|
||||
Collection<AdministrativeMonitor> active = new ArrayList<>();
|
||||
for (AdministrativeMonitor am : Jenkins.get().getActiveAdministrativeMonitors()) {
|
||||
if (am instanceof ReverseProxySetupMonitor) {
|
||||
// TODO make reverse proxy monitor work when shown on any URL
|
||||
continue;
|
||||
}
|
||||
if (am instanceof URICheckEncodingMonitor) {
|
||||
// TODO make URI encoding monitor work when shown on any URL
|
||||
continue;
|
||||
}
|
||||
active.add(am);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the administrative monitors that are active and should be shown.
|
||||
* This is done only when the instance is currently running and the user has the permission to read them.
|
||||
*
|
||||
* @return the list of active monitors if we should display them, otherwise null.
|
||||
*/
|
||||
public Collection<AdministrativeMonitor> getMonitorsToDisplay() {
|
||||
if (!(AdministrativeMonitor.hasPermissionToDisplay())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StaplerRequest2 req = Stapler.getCurrentRequest2();
|
||||
|
||||
if (req == null) {
|
||||
return null;
|
||||
}
|
||||
List<Ancestor> ancestors = req.getAncestors();
|
||||
|
||||
if (ancestors == null || ancestors.isEmpty()) {
|
||||
// ???
|
||||
return null;
|
||||
}
|
||||
|
||||
Ancestor a = ancestors.get(ancestors.size() - 1);
|
||||
Object o = a.getObject();
|
||||
|
||||
// don't show while Jenkins is loading
|
||||
if (o instanceof HudsonIsLoading || o instanceof HudsonIsRestarting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// don't show for some URLs served directly by Jenkins
|
||||
if (o instanceof Jenkins) {
|
||||
String url = a.getRestOfUrl();
|
||||
|
||||
if (ignoredJenkinsRestOfUrls.contains(url)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return getAllActiveAdministrativeMonitors();
|
||||
}
|
||||
}
|
|
@ -66,7 +66,6 @@ public class Badge {
|
|||
*
|
||||
* @param text The text to be shown in the badge.
|
||||
* Keep it short, ideally just a number. More than 6 or 7 characters do not look good. Avoid spaces as they will lead to line breaks.
|
||||
* as this might lead to line breaks.
|
||||
* @param tooltip The tooltip to show for the badge.
|
||||
* Do not include html tags.
|
||||
* @param severity The severity of the badge (danger, warning, info)
|
||||
|
|
|
@ -199,8 +199,7 @@ LabelExpression.LabelLink=<a href="{0}{2}">Label {1}</a> matches {3,choice,0#no
|
|||
LabelExpression.NoMatch=No agent/cloud matches this label expression.
|
||||
LabelExpression.NoMatch_DidYouMean=No agent/cloud matches this label expression. Did you mean ‘{1}’ instead of ‘{0}’?
|
||||
ManageJenkinsAction.DisplayName=Manage Jenkins
|
||||
ManageJenkinsAction.notification={0} notification
|
||||
ManageJenkinsAction.notifications={0} notifications
|
||||
ManageJenkinsAction.notifications=One or more notifications
|
||||
MultiStageTimeSeries.EMPTY_STRING=
|
||||
ParametersDefinitionProperty.BuildButtonText=Build
|
||||
Queue.AllNodesOffline=All nodes of label ‘{0}’ are offline
|
||||
|
|
|
@ -66,5 +66,3 @@ ShutdownLink.Description=Stops executing new builds, so that the system can be e
|
|||
ShutdownLink.ShuttingDownInProgressDescription=Jenkins is currently shutting down. New builds are not executing.
|
||||
ShutdownLink.ShutDownReason_title=Reason
|
||||
ShutdownLink.ShutDownReason_update=Update reason
|
||||
|
||||
AdministrativeMonitorsDecorator.DisplayName=Administrative Monitors Notifier
|
||||
|
|
|
@ -74,6 +74,3 @@ ShutdownLink.Description=\
|
|||
# Configure tools, their locations and automatic installers.
|
||||
ConfigureTools.Description=\
|
||||
Настройване на инструментите, местоположенията и автоматичното инсталиране.
|
||||
# Administrative Monitors Notifier
|
||||
AdministrativeMonitorsDecorator.DisplayName=\
|
||||
Известия за предупреждения
|
||||
|
|
|
@ -49,5 +49,4 @@ NodesLink.Description=Knoten hinzufügen, entfernen, steuern und überwachen, au
|
|||
CliLink.Description=Jenkins aus der Kommandozeile oder skriptgesteuert nutzen und verwalten.
|
||||
CliLink.DisplayName=Jenkins CLI
|
||||
SystemLogLink.DisplayName=Systemlog
|
||||
AdministrativeMonitorsDecorator.DisplayName=Anzeige aktiver Administrator-Warnungen
|
||||
ConfigureTools.Description=Hilfsprogramme, ihre Installationsverzeichnisse und Installationsverfahren konfigurieren
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
AdministrativeMonitorsDecorator.DisplayName=Componente di notifica monitor \
|
||||
amministrativi
|
||||
CliLink.Description=Accedi/gestisci Jenkins dal terminale o da uno script.
|
||||
CliLink.DisplayName=Interfaccia a riga di comando di Jenkins
|
||||
ConfigureLink.Description=Configura le impostazioni e i percorsi globali.
|
||||
|
|
|
@ -45,7 +45,6 @@ NodesLink.Description=Adiciona, remove, controla e monitora o vários nós
|
|||
CliLink.DisplayName=Interface de Linha de Commando do Jenkins (CLI)
|
||||
ShutdownLink.DisplayName_update=Atualizar preparação de desligamento
|
||||
ShutdownLink.ShutDownReason_update=Atualizar razão
|
||||
AdministrativeMonitorsDecorator.DisplayName=Notificador de monitorações administrativas
|
||||
ConfigureTools.Description=Configurar ferramentas, suas localizações e instaladores automáticos.
|
||||
ShutdownLink.ShuttingDownInProgressDescription=O Jenkins está sendo desligado no momento. Novas construções não serão executadas.
|
||||
ShutdownLink.ShutDownReason_title=Razão
|
||||
|
|
|
@ -41,4 +41,3 @@ NodesLink.Description=Позволяет добавлять, удалять, к
|
|||
PluginsLink.Description=Добавить, удалить, отключить или включить плагины, расширяющие функционональные возможности Jenkins.
|
||||
ConfigureTools.Description=Конфигурация инструментов, их расположение и автоматическая инсталяция.
|
||||
SystemLogLink.DisplayName=Системный журнал
|
||||
AdministrativeMonitorsDecorator.DisplayName=Системные уведомления
|
||||
|
|
|
@ -66,5 +66,3 @@ ShutdownLink.Description=Slutar köra nya byggen så att systemet eventuellt kan
|
|||
ShutdownLink.ShuttingDownInProgressDescription=Jenkins stängs ned för tillfället. Nya byggen körs inte.
|
||||
ShutdownLink.ShutDownReason_title=Anledning
|
||||
ShutdownLink.ShutDownReason_update=Uppdatera anledning
|
||||
|
||||
AdministrativeMonitorsDecorator.DisplayName=Avisering om administrativ övervakning
|
||||
|
|
|
@ -58,5 +58,3 @@ ShutdownLink.Description=不再執行新的建置作業,讓系統可以安全
|
|||
ShutdownLink.ShuttingDownInProgressDescription=Jenkins 正在停機,不會執行新的建置作業。
|
||||
ShutdownLink.ShutDownReason_title=原因
|
||||
ShutdownLink.ShutDownReason_update=更新原因
|
||||
|
||||
AdministrativeMonitorsDecorator.DisplayName=管理監視器通知
|
||||
|
|
|
@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
|
||||
import hudson.ExtensionList;
|
||||
import hudson.model.AdministrativeMonitor;
|
||||
import hudson.model.ManageJenkinsAction;
|
||||
import hudson.model.User;
|
||||
import hudson.security.ACL;
|
||||
import hudson.security.Permission;
|
||||
|
@ -40,6 +41,7 @@ import org.jenkinsci.Symbol;
|
|||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.jvnet.hudson.test.For;
|
||||
import org.jvnet.hudson.test.Issue;
|
||||
import org.jvnet.hudson.test.JenkinsRule;
|
||||
import org.jvnet.hudson.test.MockAuthorizationStrategy;
|
||||
|
@ -47,6 +49,7 @@ import org.jvnet.hudson.test.TestExtension;
|
|||
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
|
||||
|
||||
@WithJenkins
|
||||
@For(ManageJenkinsAction.class) // the name is historical
|
||||
class AdministrativeMonitorsDecoratorTest {
|
||||
|
||||
private String managePermission;
|
||||
|
@ -68,8 +71,15 @@ class AdministrativeMonitorsDecoratorTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void deleteOtherImpls(ExtensionList<AdministrativeMonitor> extensionList) {
|
||||
extensionList.removeAll(extensionList.stream().filter(m -> m.getClass().getEnclosingClass() != AdministrativeMonitorsDecoratorTest.class).toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void ensureAdminMonitorsAreNotRunPerNonAdminPage() throws Exception {
|
||||
ExtensionList<AdministrativeMonitor> extensionList = j.jenkins.getExtensionList(AdministrativeMonitor.class);
|
||||
deleteOtherImpls(extensionList);
|
||||
|
||||
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
|
||||
String nonAdminLogin = "nonAdmin";
|
||||
User.getById(nonAdminLogin, true);
|
||||
|
@ -81,7 +91,6 @@ class AdministrativeMonitorsDecoratorTest {
|
|||
JenkinsRule.WebClient wc = j.createWebClient();
|
||||
wc.login(nonAdminLogin);
|
||||
|
||||
ExtensionList<AdministrativeMonitor> extensionList = j.jenkins.getExtensionList(AdministrativeMonitor.class);
|
||||
ExecutionCounterNonSecAdministrativeMonitor nonSecCounter = extensionList.get(ExecutionCounterNonSecAdministrativeMonitor.class);
|
||||
ExecutionCounterSecAdministrativeMonitor secCounter = extensionList.get(ExecutionCounterSecAdministrativeMonitor.class);
|
||||
|
||||
|
@ -92,6 +101,9 @@ class AdministrativeMonitorsDecoratorTest {
|
|||
@Test
|
||||
@Issue("JENKINS-63977")
|
||||
void ensureAdminMonitorsAreRunOnlyOncePerAdminPage() throws Exception {
|
||||
ExtensionList<AdministrativeMonitor> extensionList = j.jenkins.getExtensionList(AdministrativeMonitor.class);
|
||||
deleteOtherImpls(extensionList);
|
||||
|
||||
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
|
||||
String adminLogin = "admin";
|
||||
User.getById(adminLogin, true);
|
||||
|
@ -103,15 +115,40 @@ class AdministrativeMonitorsDecoratorTest {
|
|||
JenkinsRule.WebClient wc = j.createWebClient();
|
||||
wc.login(adminLogin);
|
||||
|
||||
ExtensionList<AdministrativeMonitor> extensionList = j.jenkins.getExtensionList(AdministrativeMonitor.class);
|
||||
ExecutionCounterNonSecAdministrativeMonitor nonSecCounter = extensionList.get(ExecutionCounterNonSecAdministrativeMonitor.class);
|
||||
ExecutionCounterSecAdministrativeMonitor secCounter = extensionList.get(ExecutionCounterSecAdministrativeMonitor.class);
|
||||
|
||||
assertEquals(1, nonSecCounter.count);
|
||||
assertEquals(0, nonSecCounter.count);
|
||||
assertEquals(1, secCounter.count);
|
||||
}
|
||||
|
||||
@TestExtension({"ensureAdminMonitorsAreNotRunPerNonAdminPage", "ensureAdminMonitorsAreRunOnlyOncePerAdminPage"})
|
||||
@Test
|
||||
void ensureOnlyOneAdminMonitorPerTypeIsRunPerAdminPage() throws Exception {
|
||||
ExtensionList<AdministrativeMonitor> extensionList = j.jenkins.getExtensionList(AdministrativeMonitor.class);
|
||||
deleteOtherImpls(extensionList);
|
||||
|
||||
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
|
||||
String adminLogin = "admin";
|
||||
User.getById(adminLogin, true);
|
||||
|
||||
j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()
|
||||
.grant(Jenkins.ADMINISTER).everywhere().to(adminLogin)
|
||||
);
|
||||
|
||||
JenkinsRule.WebClient wc = j.createWebClient();
|
||||
wc.login(adminLogin);
|
||||
|
||||
ExecutionCounterNonSecAdministrativeMonitor nonSecCounter = extensionList.get(ExecutionCounterNonSecAdministrativeMonitor.class);
|
||||
ExecutionCounterNonSecAdministrativeMonitor2 nonSecCounter2 = extensionList.get(ExecutionCounterNonSecAdministrativeMonitor2.class);
|
||||
ExecutionCounterSecAdministrativeMonitor secCounter = extensionList.get(ExecutionCounterSecAdministrativeMonitor.class);
|
||||
|
||||
assertEquals(0, nonSecCounter.count);
|
||||
assertEquals(0, nonSecCounter2.count);
|
||||
assertEquals(1, secCounter.count);
|
||||
}
|
||||
|
||||
|
||||
@TestExtension({"ensureAdminMonitorsAreNotRunPerNonAdminPage", "ensureAdminMonitorsAreRunOnlyOncePerAdminPage", "ensureOnlyOneAdminMonitorPerTypeIsRunPerAdminPage"})
|
||||
@Symbol("non_sec_counting")
|
||||
public static class ExecutionCounterNonSecAdministrativeMonitor extends AdministrativeMonitor {
|
||||
|
||||
|
@ -134,7 +171,30 @@ class AdministrativeMonitorsDecoratorTest {
|
|||
}
|
||||
}
|
||||
|
||||
@TestExtension({"ensureAdminMonitorsAreNotRunPerNonAdminPage", "ensureAdminMonitorsAreRunOnlyOncePerAdminPage"})
|
||||
@TestExtension("ensureOnlyOneAdminMonitorPerTypeIsRunPerAdminPage")
|
||||
@Symbol("non_sec_counting_2")
|
||||
public static class ExecutionCounterNonSecAdministrativeMonitor2 extends AdministrativeMonitor {
|
||||
|
||||
public int count = 0;
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "NonSecCounter2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActivated() {
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecurity() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@TestExtension({"ensureAdminMonitorsAreNotRunPerNonAdminPage", "ensureAdminMonitorsAreRunOnlyOncePerAdminPage", "ensureOnlyOneAdminMonitorPerTypeIsRunPerAdminPage"})
|
||||
@Symbol("sec_counting")
|
||||
public static class ExecutionCounterSecAdministrativeMonitor extends AdministrativeMonitor {
|
||||
|
||||
|
|
Loading…
Reference in New Issue