From 6b597c6c5b142748e9f634ec2eabfd8e59ae47a0 Mon Sep 17 00:00:00 2001 From: Robin Shen Date: Mon, 29 Sep 2025 10:16:23 +0800 Subject: [PATCH] fix: Update Project Settings API endpoint does not have same validation as frontend, leading to NPE (OD-2568) --- .../administration/GlobalBuildSetting.java | 6 +++- .../administration/GlobalIssueSetting.java | 24 +++++++++++++- .../administration/GlobalProjectSetting.java | 2 ++ .../GlobalPullRequestSetting.java | 2 ++ .../administration/SecuritySetting.java | 28 ++++++++++------- .../administration/ServiceDeskSetting.java | 16 +++++++--- .../jobexecutor/ServiceLocator.java | 6 ++-- .../support/build/ProjectBuildSetting.java | 23 +++++++++++--- .../ChannelNotificationSetting.java | 6 ++-- .../support/issue/ProjectIssueSetting.java | 26 +++++++++++++--- .../support/pack/ProjectPackSetting.java | 9 ++++-- .../ProjectPullRequestSetting.java | 22 +++++++------ .../server/rest/resource/ProjectResource.java | 12 ++++++- .../server/rest/resource/SettingResource.java | 31 ++++++++++--------- .../kubernetes/KubernetesExecutor.java | 4 +++ .../serverdocker/ServerDockerExecutor.java | 4 ++- 16 files changed, 159 insertions(+), 62 deletions(-) diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalBuildSetting.java b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalBuildSetting.java index 8aa207c047..7b5853e4c3 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalBuildSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalBuildSetting.java @@ -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 getNamedQueries() { return namedQueries; } @@ -38,6 +41,7 @@ public class GlobalBuildSetting implements Serializable { this.namedQueries = namedQueries; } + @NotNull public List getListParams() { return listParams; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalIssueSetting.java b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalIssueSetting.java index e984514e08..5facaf1699 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalIssueSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalIssueSetting.java @@ -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 getStateSpecs() { return stateSpecs; } @@ -306,6 +310,8 @@ public class GlobalIssueSetting implements Serializable { this.stateSpecs = stateSpecs; } + @NotNull + @Valid public List getTransitionSpecs() { return transitionSpecs; } @@ -315,6 +321,8 @@ public class GlobalIssueSetting implements Serializable { } @Editable + @NotNull + @Valid public List 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 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 getListFields() { return listFields; } @@ -709,7 +722,8 @@ public class GlobalIssueSetting implements Serializable { public void setListFields(List listFields) { this.listFields = listFields; } - + + @NotNull public List getListLinks() { return listLinks; } @@ -718,6 +732,8 @@ public class GlobalIssueSetting implements Serializable { this.listLinks = listLinks; } + @NotNull + @Valid public List getNamedQueries() { return namedQueries; } @@ -726,6 +742,8 @@ public class GlobalIssueSetting implements Serializable { this.namedQueries = namedQueries; } + @NotNull + @Valid public List 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; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalProjectSetting.java b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalProjectSetting.java index fc9ebd4e39..842f5df2ee 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalProjectSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalProjectSetting.java @@ -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 getNamedQueries() { return namedQueries; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalPullRequestSetting.java b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalPullRequestSetting.java index 3d4ff075fa..6e2319b4d6 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalPullRequestSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/GlobalPullRequestSetting.java @@ -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 getNamedQueries() { return namedQueries; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/SecuritySetting.java b/server-core/src/main/java/io/onedev/server/model/support/administration/SecuritySetting.java index 151b656e2e..1e8150f29a 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/SecuritySetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/SecuritySetting.java @@ -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 CORS origins. " + "For a CORS simple or preflight request, if value of request header Origin is included here, " + "the response header Access-Control-Allow-Origin will be set to the same value") + @NotNull public List getCorsAllowedOrigins() { return corsAllowedOrigins; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/ServiceDeskSetting.java b/server-core/src/main/java/io/onedev/server/model/support/administration/ServiceDeskSetting.java index 876659ca0b..21d0a53ced 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/ServiceDeskSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/ServiceDeskSetting.java @@ -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 getIssueCreationSettings() { return issueCreationSettings; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/administration/jobexecutor/ServiceLocator.java b/server-core/src/main/java/io/onedev/server/model/support/administration/jobexecutor/ServiceLocator.java index 8b09bd3cb3..be7776617b 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/administration/jobexecutor/ServiceLocator.java +++ b/server-core/src/main/java/io/onedev/server/model/support/administration/jobexecutor/ServiceLocator.java @@ -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 getNodeSelector() { return nodeSelector; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/build/ProjectBuildSetting.java b/server-core/src/main/java/io/onedev/server/model/support/build/ProjectBuildSetting.java index 440a675a22..9bc8dbfb52 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/build/ProjectBuildSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/build/ProjectBuildSetting.java @@ -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 getJobProperties() { return jobProperties; } @@ -47,6 +56,7 @@ public class ProjectBuildSetting implements Serializable { this.jobProperties = jobProperties; } + @Valid public List getJobSecrets() { return jobSecrets; } @@ -55,6 +65,7 @@ public class ProjectBuildSetting implements Serializable { this.jobSecrets = jobSecrets; } + @Valid public List getBuildPreservations() { return buildPreservations; } @@ -63,6 +74,7 @@ public class ProjectBuildSetting implements Serializable { this.buildPreservations = buildPreservations; } + @Valid public List getDefaultFixedIssueFilters() { return defaultFixedIssueFilters; } @@ -97,6 +109,7 @@ public class ProjectBuildSetting implements Serializable { this.listParams = listParams; } + @Valid @Nullable public List getNamedQueries() { return namedQueries; diff --git a/server-core/src/main/java/io/onedev/server/model/support/channelnotification/ChannelNotificationSetting.java b/server-core/src/main/java/io/onedev/server/model/support/channelnotification/ChannelNotificationSetting.java index 4c50672edf..cae58e7c63 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/channelnotification/ChannelNotificationSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/channelnotification/ChannelNotificationSetting.java @@ -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 getNotifications() { return notifications; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java b/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java index efd47fa14e..c2f9d7782c 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java @@ -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 getBoardSpecs() { return boardSpecs; } @@ -65,6 +79,7 @@ public class ProjectIssueSetting implements Serializable { } @Nullable + @Valid public List getNamedQueries() { return namedQueries; } @@ -73,6 +88,7 @@ public class ProjectIssueSetting implements Serializable { this.namedQueries = namedQueries; } + @Valid public Map getTimesheetSettings() { return timesheetSettings; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/pack/ProjectPackSetting.java b/server-core/src/main/java/io/onedev/server/model/support/pack/ProjectPackSetting.java index 35907e5b5d..baaf4fc70a 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/pack/ProjectPackSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/pack/ProjectPackSetting.java @@ -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 namedQueries; @Nullable + @Valid public List getNamedQueries() { return namedQueries; } diff --git a/server-core/src/main/java/io/onedev/server/model/support/pullrequest/ProjectPullRequestSetting.java b/server-core/src/main/java/io/onedev/server/model/support/pullrequest/ProjectPullRequestSetting.java index 67498a1f27..e60106c1a9 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/pullrequest/ProjectPullRequestSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/pullrequest/ProjectPullRequestSetting.java @@ -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 getNamedQueries() { return namedQueries; } diff --git a/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java b/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java index 92cd9bb900..1adab85df1 100644 --- a/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java +++ b/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java @@ -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 contributedSettings = new ArrayList<>(); + @Valid public ArrayList getBranchProtections() { return branchProtections; } @@ -662,6 +663,7 @@ public class ProjectResource { this.branchProtections = branchProtections; } + @Valid public ArrayList 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 getNamedCommitQueries() { return namedCommitQueries; } @@ -710,6 +717,7 @@ public class ProjectResource { this.namedCommitQueries = namedCommitQueries; } + @Valid public ArrayList getNamedCodeCommentQueries() { return namedCodeCommentQueries; } @@ -718,6 +726,7 @@ public class ProjectResource { this.namedCodeCommentQueries = namedCodeCommentQueries; } + @Valid public ArrayList getWebHooks() { return webHooks; } @@ -726,6 +735,7 @@ public class ProjectResource { this.webHooks = webHooks; } + @Valid public ArrayList getContributedSettings() { return contributedSettings; } diff --git a/server-core/src/main/java/io/onedev/server/rest/resource/SettingResource.java b/server-core/src/main/java/io/onedev/server/rest/resource/SettingResource.java index 94c7218406..a440c5d400 100644 --- a/server-core/src/main/java/io/onedev/server/rest/resource/SettingResource.java +++ b/server-core/src/main/java/io/onedev/server/rest/resource/SettingResource.java @@ -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 groovyScripts) { + public Response setGroovyScripts(@NotNull @Valid List 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 jobExecutors) { + public Response setJobExecutors(@NotNull @Valid List 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 contributedSettings) { + public Response setContributedSettings(@NotNull @Valid List contributedSettings) { if (!SecurityUtils.isAdministrator()) throw new UnauthorizedException(); var oldAuditContent = getAuditContent(settingManager.getContributedSettings()); diff --git a/server-plugin/server-plugin-executor-kubernetes/src/main/java/io/onedev/server/plugin/executor/kubernetes/KubernetesExecutor.java b/server-plugin/server-plugin-executor-kubernetes/src/main/java/io/onedev/server/plugin/executor/kubernetes/KubernetesExecutor.java index 98552a1efb..dd08a2efb6 100644 --- a/server-plugin/server-plugin-executor-kubernetes/src/main/java/io/onedev/server/plugin/executor/kubernetes/KubernetesExecutor.java +++ b/server-plugin/server-plugin-executor-kubernetes/src/main/java/io/onedev/server/plugin/executor/kubernetes/KubernetesExecutor.java @@ -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 @server_url@ for registry url, @job_token@ for user name, and " + "access token for password") + @Valid public List 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 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 getServiceLocators() { return serviceLocators; } diff --git a/server-plugin/server-plugin-executor-serverdocker/src/main/java/io/onedev/server/plugin/executor/serverdocker/ServerDockerExecutor.java b/server-plugin/server-plugin-executor-serverdocker/src/main/java/io/onedev/server/plugin/executor/serverdocker/ServerDockerExecutor.java index 53130a3682..6d7d6fb83e 100644 --- a/server-plugin/server-plugin-executor-serverdocker/src/main/java/io/onedev/server/plugin/executor/serverdocker/ServerDockerExecutor.java +++ b/server-plugin/server-plugin-executor-serverdocker/src/main/java/io/onedev/server/plugin/executor/serverdocker/ServerDockerExecutor.java @@ -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 @server_url@ for registry url, @job_token@ for user name, and " + "access token for password") + @Valid public List getRegistryLogins() { return registryLogins; }