diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/DomainsController.java b/backend/src/main/java/com/alibaba/higress/console/controller/DomainsController.java index abb9748b..a7c30620 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/DomainsController.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/DomainsController.java @@ -15,6 +15,18 @@ import javax.annotation.Resource; import javax.validation.constraints.NotBlank; +import com.alibaba.higress.console.controller.dto.CommonPageQuery; +import com.alibaba.higress.console.controller.dto.Domain; +import com.alibaba.higress.console.controller.dto.PaginatedResponse; +import com.alibaba.higress.console.controller.dto.RoutePageQuery; +import com.alibaba.higress.console.controller.dto.Route; +import com.alibaba.higress.console.controller.dto.Response; +import com.alibaba.higress.console.controller.dto.TlsCertificate; +import com.alibaba.higress.console.service.TlsCertificateService; +import com.alibaba.higress.console.controller.exception.ValidationException; +import com.alibaba.higress.console.controller.util.ControllerUtil; +import com.alibaba.higress.console.service.DomainService; +import com.alibaba.higress.console.service.RouteService; import org.apache.commons.lang3.StringUtils; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; @@ -27,16 +39,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.alibaba.higress.console.controller.dto.CommonPageQuery; -import com.alibaba.higress.console.controller.dto.Domain; -import com.alibaba.higress.console.controller.dto.PaginatedResponse; -import com.alibaba.higress.console.controller.dto.Response; -import com.alibaba.higress.console.controller.dto.Route; -import com.alibaba.higress.console.controller.dto.RoutePageQuery; -import com.alibaba.higress.console.controller.exception.ValidationException; -import com.alibaba.higress.console.controller.util.ControllerUtil; -import com.alibaba.higress.console.service.DomainService; -import com.alibaba.higress.console.service.RouteService; +import java.util.Objects; @RestController("DomainsController") @RequestMapping("/v1/domains") @@ -49,6 +52,9 @@ public class DomainsController { @Resource private RouteService routeService; + @Resource + private TlsCertificateService tlsCertificateService; + @GetMapping public ResponseEntity> list(CommonPageQuery query) { return ControllerUtil.buildResponseEntity(domainService.list(query)); @@ -56,6 +62,7 @@ public ResponseEntity> list(CommonPageQuery query) { @PostMapping public ResponseEntity> add(@RequestBody Domain domain) { + checkDomainValid(domain); return ControllerUtil.buildResponseEntity(domainService.add(domain)); } @@ -66,15 +73,28 @@ public ResponseEntity> query(@PathVariable("name") @NotBlank St @PutMapping("/{name}") public ResponseEntity> put(@PathVariable("name") @NotBlank String domainName, - @RequestBody Domain domain) { + @RequestBody Domain domain) { if (StringUtils.isEmpty(domain.getName())) { domain.setName(domainName); } else if (!StringUtils.equals(domainName, domain.getName())) { throw new ValidationException("Domain name in the URL doesn't match the one in the body."); } + checkDomainValid(domain); return ControllerUtil.buildResponseEntity(domainService.put(domain)); } + private void checkDomainValid(Domain domain) { + if (!domain.valid()) { + throw new ValidationException("Domain is invalid."); + } + if (domain.getEnableHttps().equals(Domain.EnableHttps.ON.getValue())) { + TlsCertificate certificate = tlsCertificateService.query(domain.getCertIdentifier()); + if (Objects.isNull(certificate)) { + throw new ValidationException("domain certificate is not exits."); + } + } + } + @DeleteMapping("/{name}") public void delete(@PathVariable("name") @NotBlank String name) { domainService.delete(name); @@ -82,7 +102,7 @@ public void delete(@PathVariable("name") @NotBlank String name) { @GetMapping(value = "/{name}/routes") public ResponseEntity> queryRoutes(@PathVariable("name") @NotBlank String name, - CommonPageQuery commonPageQuery) { + CommonPageQuery commonPageQuery) { RoutePageQuery routePageQuery = new RoutePageQuery(); routePageQuery.setDomainName(name); if (commonPageQuery != null) { diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/RoutesController.java b/backend/src/main/java/com/alibaba/higress/console/controller/RoutesController.java index 0abafa22..4b8a2cef 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/RoutesController.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/RoutesController.java @@ -50,17 +50,23 @@ public ResponseEntity> list(RoutePageQuery query) { @PostMapping public ResponseEntity> add(@RequestBody Route route) { + if (!route.valid()) { + throw new ValidationException("Route is invalid"); + } return ControllerUtil.buildResponseEntity(routeService.add(route)); } @PutMapping("/{name}") public ResponseEntity> update(@PathVariable("name") @NotBlank String routeName, - @RequestBody Route route) { + @RequestBody Route route) { if (StringUtils.isEmpty(route.getName())) { route.setName(routeName); } else if (!StringUtils.equals(routeName, route.getName())) { throw new ValidationException("Route name in the URL doesn't match the one in the body."); } + if (!route.valid()) { + throw new ValidationException("Route is invalid"); + } return ControllerUtil.buildResponseEntity(routeService.update(route)); } diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/TlsCertificatesController.java b/backend/src/main/java/com/alibaba/higress/console/controller/TlsCertificatesController.java index 527bb4d6..2619ea58 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/TlsCertificatesController.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/TlsCertificatesController.java @@ -60,6 +60,9 @@ public ResponseEntity> list(CommonPageQuery qu @PostMapping public ResponseEntity> add(@RequestBody TlsCertificate certificate) { + if (!certificate.valid()) { + throw new ValidationException("certificate is not valid."); + } TlsCertificate newCertificate = tlsCertificateService.add(certificate); stripSensitiveInfo(newCertificate); return ControllerUtil.buildResponseEntity(newCertificate); @@ -74,12 +77,15 @@ public ResponseEntity> query(@PathVariable("name") @Not @PutMapping("/{name}") public ResponseEntity> put(@PathVariable("name") @NotBlank String certificateName, - @RequestBody TlsCertificate certificate) { + @RequestBody TlsCertificate certificate) { if (StringUtils.isNotEmpty(certificate.getName())) { certificate.setName(certificateName); } else if (!StringUtils.equals(certificateName, certificate.getName())) { throw new ValidationException("TlsCertificate name in the URL doesn't match the one in the body."); } + if (!certificate.valid()) { + throw new ValidationException("certificate is not valid."); + } TlsCertificate updatedCertificate = tlsCertificateService.update(certificate); stripSensitiveInfo(updatedCertificate); return ControllerUtil.buildResponseEntity(updatedCertificate); diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/dto/Domain.java b/backend/src/main/java/com/alibaba/higress/console/controller/dto/Domain.java index 2f7ecb42..5862faad 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/dto/Domain.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/dto/Domain.java @@ -16,7 +16,11 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; @Data @Builder @@ -25,10 +29,34 @@ @ApiModel("Gateway Domain") public class Domain { - public static class EnableHttps { - public static final String OFF = "off"; - public static final String ON = "on"; - public static final String FORCE = "force"; + @Getter + @AllArgsConstructor + public enum EnableHttps { + /** + * OFF + */ + OFF("off"), + /** + * ON + */ + ON("on"), + /** + * FORCE + */ + FORCE("force"); + /** + * value is enable http value + */ + private final String value; + + public static EnableHttps getEnum(String value) { + for (EnableHttps enableHttps : values()) { + if (Objects.equals(enableHttps.value, value)) { + return enableHttps; + } + } + return null; + } } private String name; @@ -38,4 +66,14 @@ public static class EnableHttps { private String enableHttps; private String certIdentifier; + + public boolean valid() { + if (StringUtils.isAnyBlank(name, version)) { + return false; + } + if (StringUtils.isNotEmpty(enableHttps)) { + return !Objects.isNull(EnableHttps.getEnum(enableHttps)); + } + return true; + } } diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/dto/Route.java b/backend/src/main/java/com/alibaba/higress/console/controller/dto/Route.java index 4f532c03..28383b07 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/dto/Route.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/dto/Route.java @@ -13,6 +13,7 @@ package com.alibaba.higress.console.controller.dto; import java.util.List; +import java.util.Objects; import com.alibaba.higress.console.controller.dto.route.CorsConfig; import com.alibaba.higress.console.controller.dto.route.HeaderControlConfig; @@ -29,6 +30,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; @Data @Builder @@ -36,7 +39,6 @@ @AllArgsConstructor @ApiModel("Gateway Route") public class Route { - private String name; private String version; @@ -80,4 +82,20 @@ public class Route { private HeaderControlConfig requestHeaderControl; private HeaderControlConfig responseHeaderControl; + + public boolean valid() { + if (StringUtils.isAnyBlank(name, version)) { + return false; + } + if (CollectionUtils.isEmpty(domains)) { + return false; + } + if (Objects.isNull(path)) { + return false; + } + if (StringUtils.isAnyEmpty(path.getMatchType(), path.getMatchValue())) { + return false; + } + return true; + } } diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/dto/ServiceSource.java b/backend/src/main/java/com/alibaba/higress/console/controller/dto/ServiceSource.java index 2501a01c..edafc735 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/dto/ServiceSource.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/dto/ServiceSource.java @@ -12,8 +12,10 @@ */ package com.alibaba.higress.console.controller.dto; +import java.util.List; import java.util.Map; +import com.alibaba.higress.console.util.TypeUtil; import org.apache.commons.lang3.StringUtils; import com.alibaba.higress.console.controller.util.ValidateUtil; @@ -53,17 +55,26 @@ public boolean valid() { if (null == this.getPort() || null == this.getProperties() || !ValidateUtil.checkPort(this.getPort())) { return false; } + if (!ValidateUtil.checkIp(domain) || !ValidateUtil.checkDomain(domain)) { + return false; + } if ((V1McpBridge.REGISTRY_TYPE_NACOS.equals(this.getType()) - || V1McpBridge.REGISTRY_TYPE_NACOS2.equals(this.getType())) - && (null == this.getProperties().get(V1McpBridge.REGISTRY_TYPE_NACOS_NACOSNAMESPACEID) || StringUtils - .isBlank((String)this.getProperties().get(V1McpBridge.REGISTRY_TYPE_NACOS_NACOSNAMESPACEID)))) { + || V1McpBridge.REGISTRY_TYPE_NACOS2.equals(this.getType())) + && (null == this.getProperties().get(V1McpBridge.REGISTRY_TYPE_NACOS_NACOSNAMESPACEID) || StringUtils + .isBlank((String) this.getProperties().get(V1McpBridge.REGISTRY_TYPE_NACOS_NACOSNAMESPACEID)))) { return false; } - + Object zkServicePathObject = this.getProperties().get(V1McpBridge.REGISTRY_TYPE_ZK_ZKSERVICESPATH); if (V1McpBridge.REGISTRY_TYPE_ZK.equals(this.getType()) - && null == this.getProperties().get(V1McpBridge.REGISTRY_TYPE_ZK_ZKSERVICESPATH)) { + && null == zkServicePathObject) { return false; } + List zkServicePathList = TypeUtil.object2List(zkServicePathObject, String.class); + for (String path : zkServicePathList) { + if (!ValidateUtil.checkZkPath(path)) { + return false; + } + } return true; } } diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/dto/TlsCertificate.java b/backend/src/main/java/com/alibaba/higress/console/controller/dto/TlsCertificate.java index d3d3a001..369e3d59 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/dto/TlsCertificate.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/dto/TlsCertificate.java @@ -14,13 +14,17 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Objects; +import com.alibaba.higress.console.controller.util.ValidateUtil; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; @Data @Builder @@ -44,4 +48,22 @@ public class TlsCertificate { @JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss") private LocalDateTime validityEnd; + + public boolean valid() { + if (StringUtils.isAnyBlank(name, version, cert, key)) { + return false; + } + if (CollectionUtils.isEmpty(domains)) { + return false; + } + for (String domain : domains) { + if (!ValidateUtil.checkDomain(domain)) { + return false; + } + } + if (Objects.isNull(validityStart) || Objects.isNull(validityEnd)) { + return false; + } + return validityEnd.isAfter(validityStart); + } } diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/dto/route/RoutePredicate.java b/backend/src/main/java/com/alibaba/higress/console/controller/dto/route/RoutePredicate.java index 9a0b4161..15a2d35e 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/dto/route/RoutePredicate.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/dto/route/RoutePredicate.java @@ -22,7 +22,6 @@ @NoArgsConstructor @AllArgsConstructor public class RoutePredicate { - /** * @see RoutePredicateTypeEnum */ diff --git a/backend/src/main/java/com/alibaba/higress/console/controller/util/ValidateUtil.java b/backend/src/main/java/com/alibaba/higress/console/controller/util/ValidateUtil.java index 4bd778f9..493c5a46 100644 --- a/backend/src/main/java/com/alibaba/higress/console/controller/util/ValidateUtil.java +++ b/backend/src/main/java/com/alibaba/higress/console/controller/util/ValidateUtil.java @@ -12,11 +12,19 @@ */ package com.alibaba.higress.console.controller.util; +import com.google.common.net.InetAddresses; +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class ValidateUtil { + private static final String DOMAIN_PATTERN_REGEX = "^(?!-)[A-Za-z0-9-]{1,63}(? 1 && port < 65535; } + + public static boolean checkIp(String ip) { + return InetAddresses.isInetAddress(ip); + } + + public static boolean checkDomain(String domain) { + Matcher matcher = DOMAIN_PATTERN.matcher(domain); + return matcher.matches(); + } + + public static boolean checkZkPath(String zkPath) { + if (StringUtils.isEmpty(zkPath)) { + return false; + } + return zkPath.startsWith("/"); + } } diff --git a/backend/src/main/java/com/alibaba/higress/console/service/kubernetes/KubernetesModelConverter.java b/backend/src/main/java/com/alibaba/higress/console/service/kubernetes/KubernetesModelConverter.java index fc740d3b..b3a769c8 100644 --- a/backend/src/main/java/com/alibaba/higress/console/service/kubernetes/KubernetesModelConverter.java +++ b/backend/src/main/java/com/alibaba/higress/console/service/kubernetes/KubernetesModelConverter.java @@ -622,7 +622,7 @@ private void fillIngressTls(V1ObjectMeta metadata, V1IngressSpec spec, Route rou Domain domain = configMap2Domain(configMap); - if (Domain.EnableHttps.OFF.equals(domain.getEnableHttps())) { + if (Domain.EnableHttps.OFF.getValue().equals(domain.getEnableHttps())) { continue; } @@ -639,7 +639,7 @@ private void fillIngressTls(V1ObjectMeta metadata, V1IngressSpec spec, Route rou } tlses.add(tls); - if (Domain.EnableHttps.FORCE.equals(domain.getEnableHttps())) { + if (Domain.EnableHttps.FORCE.getValue().equals(domain.getEnableHttps())) { KubernetesUtil.setAnnotation(metadata, KubernetesConstants.Annotation.SSL_REDIRECT_KEY, KubernetesConstants.Annotation.TRUE_VALUE); } diff --git a/backend/src/main/java/com/alibaba/higress/console/util/TypeUtil.java b/backend/src/main/java/com/alibaba/higress/console/util/TypeUtil.java index 15e53b0b..9d37ad7f 100644 --- a/backend/src/main/java/com/alibaba/higress/console/util/TypeUtil.java +++ b/backend/src/main/java/com/alibaba/higress/console/util/TypeUtil.java @@ -16,7 +16,10 @@ import java.time.LocalDateTime; import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Collections; import java.util.Date; +import java.util.List; /** * @author CH3CHO @@ -45,4 +48,16 @@ public static Integer string2Integer(String str) { return null; } } + + public static List object2List(Object obj, Class clazz) { + if (obj instanceof List) { + List result = new ArrayList<>(); + for (Object o : (List) obj) { + result.add(clazz.cast(o)); + } + return result; + } + return Collections.emptyList(); + } + }