fix: Update Project Settings API endpoint does not have same validation as frontend, leading to NPE (OD-2568)

This commit is contained in:
Robin Shen 2025-09-29 10:16:23 +08:00
parent a32ff3f759
commit 6b597c6c5b
16 changed files with 159 additions and 62 deletions

View File

@ -5,9 +5,11 @@ import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import io.onedev.server.model.support.build.NamedBuildQuery;
import io.onedev.server.annotation.Editable;
import io.onedev.server.model.support.build.NamedBuildQuery;
@Editable
public class GlobalBuildSetting implements Serializable {
@ -30,6 +32,7 @@ public class GlobalBuildSetting implements Serializable {
namedQueries.add(new NamedBuildQuery("Build recently", "\"Submit Date\" is since \"last week\""));
}
@Valid
public List<NamedBuildQuery> getNamedQueries() {
return namedQueries;
}
@ -38,6 +41,7 @@ public class GlobalBuildSetting implements Serializable {
this.namedQueries = namedQueries;
}
@NotNull
public List<String> getListParams() {
return listParams;
}

View File

@ -12,6 +12,8 @@ import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import com.google.common.collect.Lists;
@ -298,6 +300,8 @@ public class GlobalIssueSetting implements Serializable {
return sorted;
}
@NotNull
@Valid
public List<StateSpec> getStateSpecs() {
return stateSpecs;
}
@ -306,6 +310,8 @@ public class GlobalIssueSetting implements Serializable {
this.stateSpecs = stateSpecs;
}
@NotNull
@Valid
public List<TransitionSpec> getTransitionSpecs() {
return transitionSpecs;
}
@ -315,6 +321,8 @@ public class GlobalIssueSetting implements Serializable {
}
@Editable
@NotNull
@Valid
public List<FieldSpec> getFieldSpecs() {
return fieldSpecs;
}
@ -686,6 +694,8 @@ public class GlobalIssueSetting implements Serializable {
throw new ExplicitException("No any issue state is defined");
}
@NotNull
@Valid
public List<BoardSpec> getBoardSpecs() {
return boardSpecs;
}
@ -694,6 +704,8 @@ public class GlobalIssueSetting implements Serializable {
this.boardSpecs = boardSpecs;
}
@NotNull
@Valid
public TimeTrackingSetting getTimeTrackingSetting() {
return timeTrackingSetting;
}
@ -702,6 +714,7 @@ public class GlobalIssueSetting implements Serializable {
this.timeTrackingSetting = timeTrackingSetting;
}
@NotNull
public List<String> getListFields() {
return listFields;
}
@ -709,7 +722,8 @@ public class GlobalIssueSetting implements Serializable {
public void setListFields(List<String> listFields) {
this.listFields = listFields;
}
@NotNull
public List<String> getListLinks() {
return listLinks;
}
@ -718,6 +732,8 @@ public class GlobalIssueSetting implements Serializable {
this.listLinks = listLinks;
}
@NotNull
@Valid
public List<NamedIssueQuery> getNamedQueries() {
return namedQueries;
}
@ -726,6 +742,8 @@ public class GlobalIssueSetting implements Serializable {
this.namedQueries = namedQueries;
}
@NotNull
@Valid
public List<IssueTemplate> getIssueTemplates() {
return issueTemplates;
}
@ -734,6 +752,8 @@ public class GlobalIssueSetting implements Serializable {
this.issueTemplates = issueTemplates;
}
@NotNull
@Valid
public CommitMessageFixPatterns getCommitMessageFixPatterns() {
return commitMessageFixPatterns;
}
@ -742,6 +762,8 @@ public class GlobalIssueSetting implements Serializable {
this.commitMessageFixPatterns = commitMessageFixPatterns;
}
@Valid
@NotNull
public ExternalIssueTransformers getExternalIssueTransformers() {
return externalIssueTransformers;
}

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.validation.Valid;
import io.onedev.server.model.support.NamedProjectQuery;
@ -19,6 +20,7 @@ public class GlobalProjectSetting implements Serializable {
namedQueries.add(new NamedProjectQuery("My projects", "owned by me"));
}
@Valid
public List<NamedProjectQuery> getNamedQueries() {
return namedQueries;
}

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.validation.Valid;
import io.onedev.server.model.support.pullrequest.NamedPullRequestQuery;
@ -33,6 +34,7 @@ public class GlobalPullRequestSetting implements Serializable {
namedQueries.add(new NamedPullRequestQuery("All", null));
}
@Valid
public List<NamedPullRequestQuery> getNamedQueries() {
return namedQueries;
}

View File

@ -1,21 +1,24 @@
package io.onedev.server.model.support.administration;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.GroupChoice;
import io.onedev.server.annotation.Patterns;
import io.onedev.server.annotation.DependsOn;
import io.onedev.server.entitymanager.GroupManager;
import io.onedev.server.model.Group;
import io.onedev.server.util.usage.Usage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.DependsOn;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.GroupChoice;
import io.onedev.server.annotation.Patterns;
import io.onedev.server.entitymanager.GroupManager;
import io.onedev.server.model.Group;
import io.onedev.server.util.usage.Usage;
@Editable
public class SecuritySetting implements Serializable {
@ -110,6 +113,7 @@ public class SecuritySetting implements Serializable {
"Optionally specify allowed <a href='https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS' target='_blank'>CORS</a> origins. " +
"For a CORS simple or preflight request, if value of request header <code>Origin</code> is included here, " +
"the response header <code>Access-Control-Allow-Origin</code> will be set to the same value")
@NotNull
public List<String> getCorsAllowedOrigins() {
return corsAllowedOrigins;
}

View File

@ -1,5 +1,16 @@
package io.onedev.server.model.support.administration;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.validation.Valid;
import edu.emory.mathcs.backport.java.util.Collections;
import io.onedev.commons.utils.ExplicitException;
import io.onedev.commons.utils.match.PathMatcher;
@ -13,10 +24,6 @@ import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldReso
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldValue;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldValuesResolution;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
@Editable
public class ServiceDeskSetting implements Serializable {
@ -35,6 +42,7 @@ public class ServiceDeskSetting implements Serializable {
@Editable(order=300, description="Specify issue creation settings. For a particular sender and project, " +
"the first matching entry will take effect. Issue creation will be disallowed if no matching " +
"entry found")
@Valid
public List<IssueCreationSetting> getIssueCreationSettings() {
return issueCreationSettings;
}

View File

@ -4,14 +4,15 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.Size;
import io.onedev.k8shelper.ServiceFacade;
import io.onedev.commons.utils.match.Matcher;
import io.onedev.commons.utils.match.PathMatcher;
import io.onedev.server.util.patternset.PatternSet;
import io.onedev.k8shelper.ServiceFacade;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.Patterns;
import io.onedev.server.util.patternset.PatternSet;
@Editable
public class ServiceLocator implements Serializable {
@ -52,6 +53,7 @@ public class ServiceLocator implements Serializable {
@Editable(order=300, description="Specify node selector of this locator")
@Size(min=1, message="At least one entry should be specified")
@Valid
public List<NodeSelectorEntry> getNodeSelector() {
return nodeSelector;
}

View File

@ -1,6 +1,19 @@
package io.onedev.server.model.support.build;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.validation.Valid;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.Editable;
import io.onedev.server.entitymanager.SettingManager;
import io.onedev.server.job.match.JobMatch;
import io.onedev.server.model.support.administration.GlobalBuildSetting;
@ -10,11 +23,6 @@ import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldReso
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldValue;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldValuesResolution;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedStateResolution;
import io.onedev.server.annotation.Editable;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.*;
@Editable
public class ProjectBuildSetting implements Serializable {
@ -39,6 +47,7 @@ public class ProjectBuildSetting implements Serializable {
private transient GlobalBuildSetting globalSetting;
@Valid
public List<JobProperty> getJobProperties() {
return jobProperties;
}
@ -47,6 +56,7 @@ public class ProjectBuildSetting implements Serializable {
this.jobProperties = jobProperties;
}
@Valid
public List<JobSecret> getJobSecrets() {
return jobSecrets;
}
@ -55,6 +65,7 @@ public class ProjectBuildSetting implements Serializable {
this.jobSecrets = jobSecrets;
}
@Valid
public List<BuildPreservation> getBuildPreservations() {
return buildPreservations;
}
@ -63,6 +74,7 @@ public class ProjectBuildSetting implements Serializable {
this.buildPreservations = buildPreservations;
}
@Valid
public List<DefaultFixedIssueFilter> getDefaultFixedIssueFilters() {
return defaultFixedIssueFilters;
}
@ -97,6 +109,7 @@ public class ProjectBuildSetting implements Serializable {
this.listParams = listParams;
}
@Valid
@Nullable
public List<NamedBuildQuery> getNamedQueries() {
return namedQueries;

View File

@ -6,13 +6,14 @@ import java.util.List;
import java.util.Set;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import io.onedev.server.annotation.Vertical;
import io.onedev.server.validation.Validatable;
import io.onedev.server.annotation.ClassValidating;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.OmitName;
import io.onedev.server.annotation.Vertical;
import io.onedev.server.validation.Validatable;
import io.onedev.server.web.page.project.setting.ContributedProjectSetting;
@ClassValidating
@ -26,6 +27,7 @@ public class ChannelNotificationSetting implements ContributedProjectSetting, Va
@Vertical
@OmitName
@NotNull
@Valid
public List<ChannelNotification> getNotifications() {
return notifications;
}

View File

@ -1,5 +1,18 @@
package io.onedev.server.model.support.issue;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.validation.Valid;
import io.onedev.server.OneDev;
import io.onedev.server.annotation.Editable;
import io.onedev.server.entitymanager.SettingManager;
@ -8,11 +21,11 @@ import io.onedev.server.model.IssueSchedule;
import io.onedev.server.model.support.administration.GlobalIssueSetting;
import io.onedev.server.search.entity.issue.IssueQueryUpdater;
import io.onedev.server.util.usage.Usage;
import io.onedev.server.web.component.issue.workflowreconcile.*;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.*;
import io.onedev.server.web.component.issue.workflowreconcile.ReconcileUtils;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldResolution;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldValue;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedFieldValuesResolution;
import io.onedev.server.web.component.issue.workflowreconcile.UndefinedStateResolution;
@Editable
public class ProjectIssueSetting implements Serializable {
@ -56,6 +69,7 @@ public class ProjectIssueSetting implements Serializable {
}
@Nullable
@Valid
public List<BoardSpec> getBoardSpecs() {
return boardSpecs;
}
@ -65,6 +79,7 @@ public class ProjectIssueSetting implements Serializable {
}
@Nullable
@Valid
public List<NamedIssueQuery> getNamedQueries() {
return namedQueries;
}
@ -73,6 +88,7 @@ public class ProjectIssueSetting implements Serializable {
this.namedQueries = namedQueries;
}
@Valid
public Map<String, TimesheetSetting> getTimesheetSettings() {
return timesheetSettings;
}

View File

@ -1,11 +1,13 @@
package io.onedev.server.model.support.pack;
import io.onedev.server.annotation.Editable;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;
import javax.validation.Valid;
import io.onedev.server.annotation.Editable;
@Editable
public class ProjectPackSetting implements Serializable {
@ -14,6 +16,7 @@ public class ProjectPackSetting implements Serializable {
private List<NamedPackQuery> namedQueries;
@Nullable
@Valid
public List<NamedPackQuery> getNamedQueries() {
return namedQueries;
}

View File

@ -1,5 +1,16 @@
package io.onedev.server.model.support.pullrequest;
import static io.onedev.server.web.translation.Translation._T;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.annotation.Nullable;
import javax.validation.Valid;
import io.onedev.commons.bootstrap.Bootstrap;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.UserChoice;
@ -9,16 +20,6 @@ import io.onedev.server.security.SecurityUtils;
import io.onedev.server.security.permission.WriteCode;
import io.onedev.server.util.usage.Usage;
import javax.annotation.Nullable;
import static io.onedev.server.web.translation.Translation._T;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@Editable
public class ProjectPullRequestSetting implements Serializable {
@ -33,6 +34,7 @@ public class ProjectPullRequestSetting implements Serializable {
private Boolean deleteSourceBranchAfterMerge;
@Nullable
@Valid
public List<NamedPullRequestQuery> getNamedQueries() {
return namedQueries;
}

View File

@ -355,7 +355,7 @@ public class ProjectResource {
@Api(order=900, description="Update project settings")
@Path("/{projectId}/setting")
@POST
public Response updateSetting(@PathParam("projectId") Long projectId, @NotNull ProjectSetting setting) {
public Response updateSetting(@PathParam("projectId") Long projectId, @NotNull @Valid ProjectSetting setting) {
Project project = projectManager.load(projectId);
if (!SecurityUtils.canManageProject(project))
throw new UnauthorizedException();
@ -654,6 +654,7 @@ public class ProjectResource {
private ArrayList<ContributedProjectSetting> contributedSettings = new ArrayList<>();
@Valid
public ArrayList<BranchProtection> getBranchProtections() {
return branchProtections;
}
@ -662,6 +663,7 @@ public class ProjectResource {
this.branchProtections = branchProtections;
}
@Valid
public ArrayList<TagProtection> getTagProtections() {
return tagProtections;
}
@ -670,6 +672,7 @@ public class ProjectResource {
this.tagProtections = tagProtections;
}
@Valid
public ProjectIssueSetting getIssueSetting() {
return issueSetting;
}
@ -678,6 +681,7 @@ public class ProjectResource {
this.issueSetting = issueSetting;
}
@Valid
public ProjectBuildSetting getBuildSetting() {
return buildSetting;
}
@ -686,6 +690,7 @@ public class ProjectResource {
this.buildSetting = buildSetting;
}
@Valid
public ProjectPackSetting getPackSetting() {
return packSetting;
}
@ -694,6 +699,7 @@ public class ProjectResource {
this.packSetting = packSetting;
}
@Valid
public ProjectPullRequestSetting getPullRequestSetting() {
return pullRequestSetting;
}
@ -702,6 +708,7 @@ public class ProjectResource {
this.pullRequestSetting = pullRequestSetting;
}
@Valid
public ArrayList<NamedCommitQuery> getNamedCommitQueries() {
return namedCommitQueries;
}
@ -710,6 +717,7 @@ public class ProjectResource {
this.namedCommitQueries = namedCommitQueries;
}
@Valid
public ArrayList<NamedCodeCommentQuery> getNamedCodeCommentQueries() {
return namedCodeCommentQueries;
}
@ -718,6 +726,7 @@ public class ProjectResource {
this.namedCodeCommentQueries = namedCodeCommentQueries;
}
@Valid
public ArrayList<WebHook> getWebHooks() {
return webHooks;
}
@ -726,6 +735,7 @@ public class ProjectResource {
this.webHooks = webHooks;
}
@Valid
public ArrayList<ContributedProjectSetting> getContributedSettings() {
return contributedSettings;
}

View File

@ -8,6 +8,7 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@ -196,7 +197,7 @@ public class SettingResource {
@Api(order=1500)
@Path("/system")
@POST
public Response setSystemSetting(@NotNull SystemSetting systemSetting) {
public Response setSystemSetting(@NotNull @Valid SystemSetting systemSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
String ingressUrl = OneDev.getInstance().getIngressUrl();
@ -212,7 +213,7 @@ public class SettingResource {
@Api(order=1600)
@Path("/authenticator")
@POST
public Response setAuthenticator(Authenticator authenticator) {
public Response setAuthenticator(@Valid Authenticator authenticator) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getAuthenticator()).toXML();
@ -225,7 +226,7 @@ public class SettingResource {
@Api(order=1700)
@Path("/backup")
@POST
public Response setBackupSetting(BackupSetting backupSetting) {
public Response setBackupSetting(@Valid BackupSetting backupSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getBackupSetting()).toXML();
@ -238,7 +239,7 @@ public class SettingResource {
@Api(order=1800)
@Path("/build")
@POST
public Response setBuildSetting(@NotNull GlobalBuildSetting buildSetting) {
public Response setBuildSetting(@NotNull @Valid GlobalBuildSetting buildSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getBuildSetting()).toXML();
@ -251,7 +252,7 @@ public class SettingResource {
@Api(order=1900)
@Path("/groovy-scripts")
@POST
public Response setGroovyScripts(@NotNull List<GroovyScript> groovyScripts) {
public Response setGroovyScripts(@NotNull @Valid List<GroovyScript> groovyScripts) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getGroovyScripts()).toXML();
@ -264,7 +265,7 @@ public class SettingResource {
@Api(order=2000)
@Path("/issue")
@POST
public Response setIssueSetting(@NotNull GlobalIssueSetting issueSetting) {
public Response setIssueSetting(@NotNull @Valid GlobalIssueSetting issueSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getIssueSetting()).toXML();
@ -278,7 +279,7 @@ public class SettingResource {
@Api(order=2100)
@Path("/job-executors")
@POST
public Response setJobExecutors(@NotNull List<JobExecutor> jobExecutors) {
public Response setJobExecutors(@NotNull @Valid List<JobExecutor> jobExecutors) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getJobExecutors()).toXML();
@ -291,7 +292,7 @@ public class SettingResource {
@Api(order=2200)
@Path("/mail-service")
@POST
public Response setMailService(MailService mailService) {
public Response setMailService(@Valid MailService mailService) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getMailService()).toXML();
@ -304,7 +305,7 @@ public class SettingResource {
@Api(order=2210)
@Path("/service-desk")
@POST
public Response setServiceDeskSetting(ServiceDeskSetting serviceDeskSetting) {
public Response setServiceDeskSetting(@Valid ServiceDeskSetting serviceDeskSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getServiceDeskSetting()).toXML();
@ -317,7 +318,7 @@ public class SettingResource {
@Api(order=2220)
@Path("/notification-template")
@POST
public Response setNotificationTemplateSetting(EmailTemplates emailTemplates) {
public Response setNotificationTemplateSetting(@Valid EmailTemplates emailTemplates) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getEmailTemplates()).toXML();
@ -330,7 +331,7 @@ public class SettingResource {
@Api(order=2300)
@Path("/project")
@POST
public Response setProjectSetting(@NotNull GlobalProjectSetting projectSetting) {
public Response setProjectSetting(@NotNull @Valid GlobalProjectSetting projectSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getProjectSetting()).toXML();
@ -343,7 +344,7 @@ public class SettingResource {
@Api(order=2400)
@Path("/pull-request")
@POST
public Response setPullRequestSetting(@NotNull GlobalPullRequestSetting pullRequestSetting) {
public Response setPullRequestSetting(@NotNull @Valid GlobalPullRequestSetting pullRequestSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getPullRequestSetting()).toXML();
@ -356,7 +357,7 @@ public class SettingResource {
@Api(order=2500)
@Path("/security")
@POST
public Response setSecuritySetting(@NotNull SecuritySetting securitySetting) {
public Response setSecuritySetting(@NotNull @Valid SecuritySetting securitySetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getSecuritySetting()).toXML();
@ -369,7 +370,7 @@ public class SettingResource {
@Api(order=2600)
@Path("/ssh")
@POST
public Response setSshSetting(@NotNull SshSetting sshSetting) {
public Response setSshSetting(@NotNull @Valid SshSetting sshSetting) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = VersionedXmlDoc.fromBean(settingManager.getSshSetting()).toXML();
@ -390,7 +391,7 @@ public class SettingResource {
@Api(order=2800)
@Path("/contributed-settings")
@POST
public Response setContributedSettings(@NotNull List<ContributedAdministrationSetting> contributedSettings) {
public Response setContributedSettings(@NotNull @Valid List<ContributedAdministrationSetting> contributedSettings) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
var oldAuditContent = getAuditContent(settingManager.getContributedSettings());

View File

@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import org.apache.commons.lang.SerializationUtils;
@ -146,6 +147,7 @@ public class KubernetesExecutor extends JobExecutor implements KubernetesAware,
@Editable(order=200, description="Specify registry logins if necessary. For built-in registry, " +
"use <code>@server_url@</code> for registry url, <code>@job_token@</code> for user name, and " +
"access token for password")
@Valid
public List<RegistryLogin> getRegistryLogins() {
return registryLogins;
}
@ -246,6 +248,7 @@ public class KubernetesExecutor extends JobExecutor implements KubernetesAware,
}
@Editable(order=500, group = "More Settings", description="Optionally specify node selector of the job pods")
@Valid
public List<NodeSelectorEntry> getNodeSelector() {
return nodeSelector;
}
@ -268,6 +271,7 @@ public class KubernetesExecutor extends JobExecutor implements KubernetesAware,
@Editable(order=25000, group="More Settings", description="Optionally specify where to run service pods "
+ "specified in job. The first matching locator will be used. If no any locators are found, "
+ "node selector of the executor will be used")
@Valid
public List<ServiceLocator> getServiceLocators() {
return serviceLocators;
}

View File

@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import org.apache.commons.lang3.SystemUtils;
@ -83,9 +84,9 @@ import io.onedev.server.job.JobManager;
import io.onedev.server.job.JobRunnable;
import io.onedev.server.job.ResourceAllocator;
import io.onedev.server.job.ServerCacheHelper;
import io.onedev.server.model.support.administration.jobexecutor.DockerAware;
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
import io.onedev.server.model.support.administration.jobexecutor.RegistryLogin;
import io.onedev.server.model.support.administration.jobexecutor.DockerAware;
import io.onedev.server.plugin.executor.serverdocker.ServerDockerExecutor.TestData;
import io.onedev.server.terminal.CommandlineShell;
import io.onedev.server.terminal.Shell;
@ -135,6 +136,7 @@ public class ServerDockerExecutor extends JobExecutor implements DockerAware, Te
@Editable(order=400, description="Specify registry logins if necessary. For built-in registry, " +
"use <code>@server_url@</code> for registry url, <code>@job_token@</code> for user name, and " +
"access token for password")
@Valid
public List<RegistryLogin> getRegistryLogins() {
return registryLogins;
}