dashboard: Add interface of authentication/authorization and provide a default stub implementation (#503)
Signed-off-by: Carpenter Lee <hooleeucas@163.com>
This commit is contained in:
parent
4b1ccd93e2
commit
3c52bbc3c8
|
|
@ -15,12 +15,24 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
|
@ -35,6 +47,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(WebConfig.class);
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
|
|
@ -62,4 +76,36 @@ public class WebConfig implements WebMvcConfigurer {
|
|||
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean authenticationFilterRegistration() {
|
||||
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new Filter() {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException { }
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
|
||||
FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest)servletRequest;
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
// authentication fail
|
||||
if (authUser == null) {
|
||||
PrintWriter writer = servletResponse.getWriter();
|
||||
writer.append("login needed");
|
||||
writer.flush();
|
||||
} else {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() { }
|
||||
});
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("authenticationFilter");
|
||||
registration.setOrder(0);
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,20 @@ package com.alibaba.csp.sentinel.dashboard.controller;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -54,10 +60,16 @@ public class AuthorityRuleController {
|
|||
@Autowired
|
||||
private RuleRepository<AuthorityRuleEntity, Long> repository;
|
||||
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@GetMapping("/rules")
|
||||
public Result<List<AuthorityRuleEntity>> apiQueryAllRulesForMachine(@RequestParam String app,
|
||||
public Result<List<AuthorityRuleEntity>> apiQueryAllRulesForMachine(HttpServletRequest request,
|
||||
@RequestParam String app,
|
||||
@RequestParam String ip,
|
||||
@RequestParam Integer port) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.READ_RULE);
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app cannot be null or empty");
|
||||
}
|
||||
|
|
@ -107,7 +119,10 @@ public class AuthorityRuleController {
|
|||
}
|
||||
|
||||
@PostMapping("/rule")
|
||||
public Result<AuthorityRuleEntity> apiAddAuthorityRule(@RequestBody AuthorityRuleEntity entity) {
|
||||
public Result<AuthorityRuleEntity> apiAddAuthorityRule(HttpServletRequest request,
|
||||
@RequestBody AuthorityRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
Result<AuthorityRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
|
|
@ -129,8 +144,11 @@ public class AuthorityRuleController {
|
|||
}
|
||||
|
||||
@PutMapping("/rule/{id}")
|
||||
public Result<AuthorityRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,
|
||||
public Result<AuthorityRuleEntity> apiUpdateParamFlowRule(HttpServletRequest request,
|
||||
@PathVariable("id") Long id,
|
||||
@RequestBody AuthorityRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
if (id == null || id <= 0) {
|
||||
return Result.ofFail(-1, "Invalid id");
|
||||
}
|
||||
|
|
@ -158,7 +176,8 @@ public class AuthorityRuleController {
|
|||
}
|
||||
|
||||
@DeleteMapping("/rule/{id}")
|
||||
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
|
||||
public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id cannot be null");
|
||||
}
|
||||
|
|
@ -166,6 +185,7 @@ public class AuthorityRuleController {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofSuccess(null);
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
|
||||
try {
|
||||
repository.delete(id);
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -18,14 +18,20 @@ package com.alibaba.csp.sentinel.dashboard.controller;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemDegradeRuleStore;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -48,9 +54,15 @@ public class DegradeController {
|
|||
@Autowired
|
||||
private SentinelApiClient sentinelApiClient;
|
||||
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/rules.json")
|
||||
public Result<List<DegradeRuleEntity>> queryMachineRules(String app, String ip, Integer port) {
|
||||
public Result<List<DegradeRuleEntity>> queryMachineRules(HttpServletRequest request, String app, String ip, Integer port) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.READ_RULE);
|
||||
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -72,8 +84,12 @@ public class DegradeController {
|
|||
|
||||
@ResponseBody
|
||||
@RequestMapping("/new.json")
|
||||
public Result<DegradeRuleEntity> add(String app, String ip, Integer port, String limitApp, String resource,
|
||||
Double count, Integer timeWindow, Integer grade) {
|
||||
public Result<DegradeRuleEntity> add(HttpServletRequest request,
|
||||
String app, String ip, Integer port, String limitApp, String resource,
|
||||
Double count, Integer timeWindow, Integer grade) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.WRITE_RULE);
|
||||
|
||||
if (StringUtil.isBlank(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -127,8 +143,10 @@ public class DegradeController {
|
|||
|
||||
@ResponseBody
|
||||
@RequestMapping("/save.json")
|
||||
public Result<DegradeRuleEntity> updateIfNotNull(Long id, String app, String limitApp, String resource,
|
||||
Double count, Integer timeWindow, Integer grade) {
|
||||
public Result<DegradeRuleEntity> updateIfNotNull(HttpServletRequest request,
|
||||
Long id, String app, String limitApp, String resource,
|
||||
Double count, Integer timeWindow, Integer grade) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -141,6 +159,7 @@ public class DegradeController {
|
|||
if (entity == null) {
|
||||
return Result.ofFail(-1, "id " + id + " dose not exist");
|
||||
}
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
if (StringUtil.isNotBlank(app)) {
|
||||
entity.setApp(app.trim());
|
||||
}
|
||||
|
|
@ -176,7 +195,8 @@ public class DegradeController {
|
|||
|
||||
@ResponseBody
|
||||
@RequestMapping("/delete.json")
|
||||
public Result<Long> delete(Long id) {
|
||||
public Result<Long> delete(HttpServletRequest request, Long id) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -185,6 +205,7 @@ public class DegradeController {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofSuccess(null);
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
|
||||
try {
|
||||
repository.delete(id);
|
||||
} catch (Throwable throwable) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ package com.alibaba.csp.sentinel.dashboard.controller;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||
|
|
@ -25,6 +30,7 @@ import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
|||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -51,14 +57,20 @@ public class FlowControllerV1 {
|
|||
|
||||
@Autowired
|
||||
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@Autowired
|
||||
private SentinelApiClient sentinelApiClient;
|
||||
|
||||
@GetMapping("/rules")
|
||||
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app,
|
||||
public Result<List<FlowRuleEntity>> apiQueryMachineRules(HttpServletRequest request,
|
||||
@RequestParam String app,
|
||||
@RequestParam String ip,
|
||||
@RequestParam Integer port) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.READ_RULE);
|
||||
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -126,7 +138,10 @@ public class FlowControllerV1 {
|
|||
}
|
||||
|
||||
@PostMapping("/rule")
|
||||
public Result<FlowRuleEntity> apiAddFlowRule(@RequestBody FlowRuleEntity entity) {
|
||||
public Result<FlowRuleEntity> apiAddFlowRule(HttpServletRequest request, @RequestBody FlowRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
|
||||
Result<FlowRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
|
|
@ -150,10 +165,14 @@ public class FlowControllerV1 {
|
|||
}
|
||||
|
||||
@PutMapping("/save.json")
|
||||
public Result<FlowRuleEntity> updateIfNotNull(Long id, String app,
|
||||
String limitApp, String resource, Integer grade,
|
||||
Double count, Integer strategy, String refResource,
|
||||
Integer controlBehavior, Integer warmUpPeriodSec, Integer maxQueueingTimeMs) {
|
||||
public Result<FlowRuleEntity> updateIfNotNull(HttpServletRequest request, Long id, String app,
|
||||
String limitApp, String resource, Integer grade,
|
||||
Double count, Integer strategy, String refResource,
|
||||
Integer controlBehavior, Integer warmUpPeriodSec,
|
||||
Integer maxQueueingTimeMs) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.WRITE_RULE);
|
||||
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -227,7 +246,8 @@ public class FlowControllerV1 {
|
|||
}
|
||||
|
||||
@DeleteMapping("/delete.json")
|
||||
public Result<Long> delete(Long id) {
|
||||
public Result<Long> delete(HttpServletRequest request, Long id) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -235,6 +255,7 @@ public class FlowControllerV1 {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofSuccess(null);
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
|
||||
try {
|
||||
repository.delete(id);
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,15 @@ import java.util.Optional;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.client.CommandNotFoundException;
|
||||
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.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
|
|
@ -33,6 +38,7 @@ import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEn
|
|||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
||||
import com.alibaba.csp.sentinel.dashboard.util.VersionUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -63,6 +69,9 @@ public class ParamFlowRuleController {
|
|||
@Autowired
|
||||
private RuleRepository<ParamFlowRuleEntity, Long> repository;
|
||||
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
private boolean checkIfSupported(String app, String ip, int port) {
|
||||
try {
|
||||
return Optional.ofNullable(appManagement.getDetailApp(app))
|
||||
|
|
@ -77,9 +86,12 @@ public class ParamFlowRuleController {
|
|||
}
|
||||
|
||||
@GetMapping("/rules")
|
||||
public Result<List<ParamFlowRuleEntity>> apiQueryAllRulesForMachine(@RequestParam String app,
|
||||
public Result<List<ParamFlowRuleEntity>> apiQueryAllRulesForMachine(HttpServletRequest request,
|
||||
@RequestParam String app,
|
||||
@RequestParam String ip,
|
||||
@RequestParam Integer port) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.READ_RULE);
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app cannot be null or empty");
|
||||
}
|
||||
|
|
@ -115,7 +127,10 @@ public class ParamFlowRuleController {
|
|||
}
|
||||
|
||||
@PostMapping("/rule")
|
||||
public Result<ParamFlowRuleEntity> apiAddParamFlowRule(@RequestBody ParamFlowRuleEntity entity) {
|
||||
public Result<ParamFlowRuleEntity> apiAddParamFlowRule(HttpServletRequest request,
|
||||
@RequestBody ParamFlowRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
|
|
@ -177,7 +192,10 @@ public class ParamFlowRuleController {
|
|||
}
|
||||
|
||||
@PutMapping("/rule/{id}")
|
||||
public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id, @RequestBody ParamFlowRuleEntity entity) {
|
||||
public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(HttpServletRequest request,
|
||||
@PathVariable("id") Long id,
|
||||
@RequestBody ParamFlowRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null || id <= 0) {
|
||||
return Result.ofFail(-1, "Invalid id");
|
||||
}
|
||||
|
|
@ -185,6 +203,7 @@ public class ParamFlowRuleController {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofFail(-1, "id " + id + " does not exist");
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
|
|
@ -214,7 +233,8 @@ public class ParamFlowRuleController {
|
|||
}
|
||||
|
||||
@DeleteMapping("/rule/{id}")
|
||||
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
|
||||
public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id cannot be null");
|
||||
}
|
||||
|
|
@ -222,6 +242,7 @@ public class ParamFlowRuleController {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofSuccess(null);
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
|
||||
try {
|
||||
repository.delete(id);
|
||||
publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort()).get();
|
||||
|
|
@ -245,7 +266,8 @@ public class ParamFlowRuleController {
|
|||
}
|
||||
|
||||
private <R> Result<R> unsupportedVersion() {
|
||||
return Result.ofFail(4041, "Sentinel client not supported for parameter flow control (unsupported version or dependency absent)");
|
||||
return Result.ofFail(4041,
|
||||
"Sentinel client not supported for parameter flow control (unsupported version or dependency absent)");
|
||||
}
|
||||
|
||||
private final SentinelVersion version020 = new SentinelVersion().setMinorVersion(2);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ package com.alibaba.csp.sentinel.dashboard.controller;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
|
||||
|
|
@ -25,6 +30,7 @@ import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
|||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemSystemRuleStore;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -45,10 +51,14 @@ public class SystemController {
|
|||
private InMemSystemRuleStore repository;
|
||||
@Autowired
|
||||
private SentinelApiClient sentinelApiClient;
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/rules.json")
|
||||
Result<List<SystemRuleEntity>> queryMachineRules(String app, String ip, Integer port) {
|
||||
Result<List<SystemRuleEntity>> queryMachineRules(HttpServletRequest request, String app, String ip, Integer port) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.READ_RULE);
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -80,7 +90,10 @@ public class SystemController {
|
|||
|
||||
@ResponseBody
|
||||
@RequestMapping("/new.json")
|
||||
Result<?> add(String app, String ip, Integer port, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
|
||||
Result<?> add(HttpServletRequest request,
|
||||
String app, String ip, Integer port, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.WRITE_RULE);
|
||||
if (StringUtil.isBlank(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -137,7 +150,9 @@ public class SystemController {
|
|||
|
||||
@ResponseBody
|
||||
@RequestMapping("/save.json")
|
||||
Result<?> updateIfNotNull(Long id, String app, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
|
||||
Result<?> updateIfNotNull(HttpServletRequest request,
|
||||
Long id, String app, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -145,6 +160,7 @@ public class SystemController {
|
|||
if (entity == null) {
|
||||
return Result.ofFail(-1, "id " + id + " dose not exist");
|
||||
}
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
if (StringUtil.isNotBlank(app)) {
|
||||
entity.setApp(app.trim());
|
||||
}
|
||||
|
|
@ -188,7 +204,8 @@ public class SystemController {
|
|||
|
||||
@ResponseBody
|
||||
@RequestMapping("/delete.json")
|
||||
Result<?> delete(Long id) {
|
||||
Result<?> delete(HttpServletRequest request, Long id) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -196,6 +213,7 @@ public class SystemController {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofSuccess(null);
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
|
||||
try {
|
||||
repository.delete(id);
|
||||
} catch (Throwable throwable) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ package com.alibaba.csp.sentinel.dashboard.controller.v2;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
|
||||
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
||||
|
|
@ -25,6 +30,7 @@ import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepository
|
|||
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
|
||||
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -61,8 +67,14 @@ public class FlowControllerV2 {
|
|||
@Qualifier("flowRuleDefaultPublisher")
|
||||
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
|
||||
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@GetMapping("/rules")
|
||||
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app) {
|
||||
public Result<List<FlowRuleEntity>> apiQueryMachineRules(HttpServletRequest request, @RequestParam String app) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(app, PrivilegeType.READ_RULE);
|
||||
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -129,7 +141,10 @@ public class FlowControllerV2 {
|
|||
}
|
||||
|
||||
@PostMapping("/rule")
|
||||
public Result<FlowRuleEntity> apiAddFlowRule(@RequestBody FlowRuleEntity entity) {
|
||||
public Result<FlowRuleEntity> apiAddFlowRule(HttpServletRequest request, @RequestBody FlowRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
|
||||
Result<FlowRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
|
|
@ -151,7 +166,10 @@ public class FlowControllerV2 {
|
|||
}
|
||||
|
||||
@PutMapping("/rule/{id}")
|
||||
public Result<FlowRuleEntity> apiUpdateFlowRule(@PathVariable("id") Long id, @RequestBody FlowRuleEntity entity) {
|
||||
public Result<FlowRuleEntity> apiUpdateFlowRule(HttpServletRequest request,
|
||||
@PathVariable("id") Long id,
|
||||
@RequestBody FlowRuleEntity entity) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null || id <= 0) {
|
||||
return Result.ofFail(-1, "Invalid id");
|
||||
}
|
||||
|
|
@ -162,6 +180,8 @@ public class FlowControllerV2 {
|
|||
if (entity == null) {
|
||||
return Result.ofFail(-1, "invalid body");
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.WRITE_RULE);
|
||||
|
||||
entity.setApp(oldEntity.getApp());
|
||||
entity.setIp(oldEntity.getIp());
|
||||
entity.setPort(oldEntity.getPort());
|
||||
|
|
@ -188,7 +208,8 @@ public class FlowControllerV2 {
|
|||
}
|
||||
|
||||
@DeleteMapping("/rule/{id}")
|
||||
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
|
||||
public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) {
|
||||
AuthUser authUser = authService.getAuthUser(request);
|
||||
if (id == null || id <= 0) {
|
||||
return Result.ofFail(-1, "Invalid id");
|
||||
}
|
||||
|
|
@ -196,6 +217,7 @@ public class FlowControllerV2 {
|
|||
if (oldEntity == null) {
|
||||
return Result.ofSuccess(null);
|
||||
}
|
||||
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
|
||||
try {
|
||||
repository.delete(id);
|
||||
publishRules(oldEntity.getApp());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.service;
|
||||
|
||||
/**
|
||||
* Interface about authentication and authorization
|
||||
*
|
||||
* @author Carpenter Lee
|
||||
*/
|
||||
public interface AuthService<R> {
|
||||
/**
|
||||
* Get the authentication user.
|
||||
*
|
||||
* @param request the request contains the user information
|
||||
* @return the auth user represent the current user, when the user is illegal, a null value will return.
|
||||
*/
|
||||
AuthUser getAuthUser(R request);
|
||||
|
||||
/**
|
||||
* privilege type.
|
||||
*/
|
||||
enum PrivilegeType {
|
||||
/**
|
||||
* read rule
|
||||
*/
|
||||
READ_RULE,
|
||||
/**
|
||||
* create or modify rule
|
||||
*/
|
||||
WRITE_RULE,
|
||||
/**
|
||||
* delete rule
|
||||
*/
|
||||
DELETE_RULE,
|
||||
/**
|
||||
* read metrics
|
||||
*/
|
||||
READ_METRIC,
|
||||
/**
|
||||
* add machine
|
||||
*/
|
||||
ADD_MACHINE,
|
||||
/**
|
||||
* equals all privileges above
|
||||
*/
|
||||
ALL
|
||||
}
|
||||
|
||||
/**
|
||||
* entity represents the current user
|
||||
*/
|
||||
interface AuthUser {
|
||||
/**
|
||||
* query whether current user has the specific privilege to the target, the target
|
||||
* may be an app name or an ip address, or other destination.
|
||||
* <p>
|
||||
* This method will use return value to represent whether user has the specific
|
||||
* privileges to the target, but to throw a RuntimeException to represent no auth
|
||||
* is also a good way.
|
||||
* </p>
|
||||
*
|
||||
* @param target the target to check
|
||||
* @param privilegeType the privilege type to check
|
||||
* @return if current user has the specific privileges to the target, return true,
|
||||
* otherwise return false.
|
||||
*/
|
||||
boolean authTarget(String target, PrivilegeType privilegeType);
|
||||
|
||||
/**
|
||||
* check whether current user is super user
|
||||
*
|
||||
* @return if current user is super user return true, else return false.
|
||||
*/
|
||||
boolean isSuperUser();
|
||||
|
||||
/**
|
||||
* get current user's nick name.
|
||||
*
|
||||
* @return current user's nick name.
|
||||
*/
|
||||
String getNickName();
|
||||
|
||||
/**
|
||||
* get current user's login name.
|
||||
*
|
||||
* @return current user's login name.
|
||||
*/
|
||||
String getLoginName();
|
||||
|
||||
/**
|
||||
* get current user's employ id.
|
||||
*
|
||||
* @return current user's employ id.
|
||||
*/
|
||||
String getEmpId();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* A fake AuthService implementation, which will pass all user auth checking.
|
||||
*
|
||||
* @author Carpenter Lee
|
||||
*/
|
||||
@Component
|
||||
public class FakeAuthServiceImpl implements AuthService<HttpServletRequest> {
|
||||
@Override
|
||||
public AuthUser getAuthUser(HttpServletRequest request) {
|
||||
|
||||
return new AuthUserImpl();
|
||||
}
|
||||
|
||||
static final class AuthUserImpl implements AuthUser {
|
||||
|
||||
@Override
|
||||
public boolean authTarget(String target, PrivilegeType privilegeType) {
|
||||
// fake implementation, always return true
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuperUser() {
|
||||
// fake implementation, always return true
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNickName() {
|
||||
return "FAKE_NICK_NAME";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoginName() {
|
||||
return "FAKE_LOGIN_NAME";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmpId() {
|
||||
return "FAKE_EMP_ID";
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue