dashboard: Improve IP validation in SentinelApiClient and rule controllers
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
84df19b2c5
commit
e13d20ce55
|
|
@ -71,6 +71,7 @@ import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
import org.apache.http.concurrent.FutureCallback;
|
import org.apache.http.concurrent.FutureCallback;
|
||||||
|
import org.apache.http.conn.util.InetAddressUtils;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.http.impl.client.DefaultRedirectStrategy;
|
import org.apache.http.impl.client.DefaultRedirectStrategy;
|
||||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||||
|
|
@ -282,6 +283,14 @@ public class SentinelApiClient {
|
||||||
future.completeExceptionally(new IllegalArgumentException("Bad URL or command name"));
|
future.completeExceptionally(new IllegalArgumentException("Bad URL or command name"));
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
if (!InetAddressUtils.isIPv4Address(ip) && !InetAddressUtils.isIPv6Address(ip)) {
|
||||||
|
future.completeExceptionally(new IllegalArgumentException("Bad IP"));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
if (!StringUtil.isEmpty(app) && !appManagement.isValidMachineOfApp(app, ip)) {
|
||||||
|
future.completeExceptionally(new IllegalArgumentException("Given ip does not belong to given app"));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
StringBuilder urlBuilder = new StringBuilder();
|
StringBuilder urlBuilder = new StringBuilder();
|
||||||
urlBuilder.append("http://");
|
urlBuilder.append("http://");
|
||||||
urlBuilder.append(ip).append(':').append(port).append('/').append(api);
|
urlBuilder.append(ip).append(':').append(port).append('/').append(api);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
||||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
|
||||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||||
|
|
@ -56,6 +57,8 @@ public class AuthorityRuleController {
|
||||||
private SentinelApiClient sentinelApiClient;
|
private SentinelApiClient sentinelApiClient;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RuleRepository<AuthorityRuleEntity, Long> repository;
|
private RuleRepository<AuthorityRuleEntity, Long> repository;
|
||||||
|
@Autowired
|
||||||
|
private AppManagement appManagement;
|
||||||
|
|
||||||
@GetMapping("/rules")
|
@GetMapping("/rules")
|
||||||
@AuthAction(PrivilegeType.READ_RULE)
|
@AuthAction(PrivilegeType.READ_RULE)
|
||||||
|
|
@ -71,6 +74,9 @@ public class AuthorityRuleController {
|
||||||
if (port == null || port <= 0) {
|
if (port == null || port <= 0) {
|
||||||
return Result.ofFail(-1, "Invalid parameter: port");
|
return Result.ofFail(-1, "Invalid parameter: port");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(app, ip)) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);
|
List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);
|
||||||
rules = repository.saveAll(rules);
|
rules = repository.saveAll(rules);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
||||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
|
||||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
||||||
|
|
@ -58,6 +59,8 @@ public class DegradeController {
|
||||||
private RuleRepository<DegradeRuleEntity, Long> repository;
|
private RuleRepository<DegradeRuleEntity, Long> repository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SentinelApiClient sentinelApiClient;
|
private SentinelApiClient sentinelApiClient;
|
||||||
|
@Autowired
|
||||||
|
private AppManagement appManagement;
|
||||||
|
|
||||||
@GetMapping("/rules.json")
|
@GetMapping("/rules.json")
|
||||||
@AuthAction(PrivilegeType.READ_RULE)
|
@AuthAction(PrivilegeType.READ_RULE)
|
||||||
|
|
@ -71,6 +74,9 @@ public class DegradeController {
|
||||||
if (port == null) {
|
if (port == null) {
|
||||||
return Result.ofFail(-1, "port can't be null");
|
return Result.ofFail(-1, "port can't be null");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(app, ip)) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
List<DegradeRuleEntity> rules = sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);
|
List<DegradeRuleEntity> rules = sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);
|
||||||
rules = repository.saveAll(rules);
|
rules = repository.saveAll(rules);
|
||||||
|
|
@ -173,6 +179,9 @@ public class DegradeController {
|
||||||
if (StringUtil.isBlank(entity.getIp())) {
|
if (StringUtil.isBlank(entity.getIp())) {
|
||||||
return Result.ofFail(-1, "ip can't be null or empty");
|
return Result.ofFail(-1, "ip can't be null or empty");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(entity.getApp(), entity.getIp())) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
if (entity.getPort() == null || entity.getPort() <= 0) {
|
if (entity.getPort() == null || entity.getPort() <= 0) {
|
||||||
return Result.ofFail(-1, "invalid port: " + entity.getPort());
|
return Result.ofFail(-1, "invalid port: " + entity.getPort());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||||
|
|
@ -57,6 +58,8 @@ public class FlowControllerV1 {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
|
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
|
||||||
|
@Autowired
|
||||||
|
private AppManagement appManagement;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SentinelApiClient sentinelApiClient;
|
private SentinelApiClient sentinelApiClient;
|
||||||
|
|
@ -66,7 +69,6 @@ public class FlowControllerV1 {
|
||||||
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app,
|
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app,
|
||||||
@RequestParam String ip,
|
@RequestParam String ip,
|
||||||
@RequestParam Integer port) {
|
@RequestParam Integer port) {
|
||||||
|
|
||||||
if (StringUtil.isEmpty(app)) {
|
if (StringUtil.isEmpty(app)) {
|
||||||
return Result.ofFail(-1, "app can't be null or empty");
|
return Result.ofFail(-1, "app can't be null or empty");
|
||||||
}
|
}
|
||||||
|
|
@ -76,6 +78,9 @@ public class FlowControllerV1 {
|
||||||
if (port == null) {
|
if (port == null) {
|
||||||
return Result.ofFail(-1, "port can't be null");
|
return Result.ofFail(-1, "port can't be null");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(app, ip)) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
List<FlowRuleEntity> rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);
|
List<FlowRuleEntity> rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);
|
||||||
rules = repository.saveAll(rules);
|
rules = repository.saveAll(rules);
|
||||||
|
|
@ -96,6 +101,9 @@ public class FlowControllerV1 {
|
||||||
if (entity.getPort() == null) {
|
if (entity.getPort() == null) {
|
||||||
return Result.ofFail(-1, "port can't be null");
|
return Result.ofFail(-1, "port can't be null");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(entity.getApp(), entity.getIp())) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
if (StringUtil.isBlank(entity.getLimitApp())) {
|
if (StringUtil.isBlank(entity.getLimitApp())) {
|
||||||
return Result.ofFail(-1, "limitApp can't be null or empty");
|
return Result.ofFail(-1, "limitApp can't be null or empty");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,9 @@ public class ParamFlowRuleController {
|
||||||
if (port == null || port <= 0) {
|
if (port == null || port <= 0) {
|
||||||
return Result.ofFail(-1, "Invalid parameter: port");
|
return Result.ofFail(-1, "Invalid parameter: port");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(app, ip)) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
if (!checkIfSupported(app, ip, port)) {
|
if (!checkIfSupported(app, ip, port)) {
|
||||||
return unsupportedVersion();
|
return unsupportedVersion();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
||||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
|
||||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
|
|
@ -48,6 +49,8 @@ public class SystemController {
|
||||||
private RuleRepository<SystemRuleEntity, Long> repository;
|
private RuleRepository<SystemRuleEntity, Long> repository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SentinelApiClient sentinelApiClient;
|
private SentinelApiClient sentinelApiClient;
|
||||||
|
@Autowired
|
||||||
|
private AppManagement appManagement;
|
||||||
|
|
||||||
private <R> Result<R> checkBasicParams(String app, String ip, Integer port) {
|
private <R> Result<R> checkBasicParams(String app, String ip, Integer port) {
|
||||||
if (StringUtil.isEmpty(app)) {
|
if (StringUtil.isEmpty(app)) {
|
||||||
|
|
@ -59,6 +62,9 @@ public class SystemController {
|
||||||
if (port == null) {
|
if (port == null) {
|
||||||
return Result.ofFail(-1, "port can't be null");
|
return Result.ofFail(-1, "port can't be null");
|
||||||
}
|
}
|
||||||
|
if (!appManagement.isValidMachineOfApp(app, ip)) {
|
||||||
|
return Result.ofFail(-1, "given ip does not belong to given app");
|
||||||
|
}
|
||||||
if (port <= 0 || port > 65535) {
|
if (port <= 0 || port > 65535) {
|
||||||
return Result.ofFail(-1, "port should be in (0, 65535)");
|
return Result.ofFail(-1, "port should be in (0, 65535)");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,12 @@ public class AppInfo {
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<MachineInfo> getMachine(String ip) {
|
||||||
|
return machines.stream()
|
||||||
|
.filter(e -> e.getIp().equals(ip))
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean heartbeatJudge(final int threshold) {
|
private boolean heartbeatJudge(final int threshold) {
|
||||||
if (machines.size() == 0) {
|
if (machines.size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,13 @@
|
||||||
package com.alibaba.csp.sentinel.dashboard.discovery;
|
package com.alibaba.csp.sentinel.dashboard.discovery;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@ -67,4 +70,13 @@ public class AppManagement implements MachineDiscovery {
|
||||||
machineDiscovery.removeApp(app);
|
machineDiscovery.removeApp(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isValidMachineOfApp(String app, String ip) {
|
||||||
|
if (StringUtil.isEmpty(app)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(getDetailApp(app))
|
||||||
|
.flatMap(a -> a.getMachine(ip))
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue