Signed-off-by: Carpenter Lee <hooleeucas@163.com>master
@@ -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"; | |||
} | |||
} | |||
} |