From 1635fadc38ff6bf15f42fec38b05e4ef6627a4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 12 Feb 2020 15:57:01 +0800 Subject: [PATCH] :arrow_up: Upgrading dependencies. spring cloud alibaba 2.2.0 --- pigx-common/pigx-common-bom/pom.xml | 7 ++ .../sentinel/SentinelAutoConfiguration.java | 21 +++-- .../sentinel/handle/PigxUrlBlockHandler.java | 9 +-- .../parser/PigxHeaderRequestOriginParser.java | 2 +- pigx-visual/pigx-sentinel-dashboard/pom.xml | 10 +-- .../sentinel/dashboard/auth/AuthAction.java | 47 +++++++++++ .../auth/AuthorizationInterceptor.java | 72 +++++++++++++++++ .../LoginAuthenticationFilter.java} | 45 ++++++----- .../auth/SimpleWebAuthServiceImpl.java | 8 +- .../dashboard/client/SentinelApiClient.java | 49 ++++++++--- .../sentinel/dashboard/config/WebConfig.java | 43 +++++++++- .../dashboard/controller/AuthController.java | 26 ++++-- .../controller/AuthorityRuleController.java | 31 +++---- .../controller/DegradeController.java | 33 +++----- .../controller/FlowControllerV1.java | 81 +++++++++---------- .../controller/ParamFlowRuleController.java | 77 +++++++----------- .../controller/SystemController.java | 32 +++----- .../controller/VersionController.java | 49 +++++++++++ .../gateway/GatewayApiController.java | 26 ++---- .../gateway/GatewayFlowRuleController.java | 28 +++---- .../controller/v2/FlowControllerV2.java | 30 +++---- .../entity/rule/AuthorityRuleEntity.java | 8 +- .../entity/rule/ParamFlowRuleEntity.java | 21 ++++- .../dashboard/domain/ResourceTreeNode.java | 2 +- .../src/main/resources/application.yml | 6 +- .../src/main/webapp/resources/README.md | 32 -------- .../src/main/webapp/resources/README_zh.md | 32 -------- .../app/scripts/controllers/flow_v1.js | 10 +-- .../app/scripts/controllers/identity.js | 14 ++-- .../app/scripts/controllers/login.js | 5 +- .../app/scripts/directives/header/header.html | 4 +- .../app/scripts/directives/header/header.js | 31 ++++++- .../app/scripts/services/auth_service.js | 7 ++ .../app/scripts/services/version_service.js | 10 +++ .../src/main/webapp/resources/dist/js/app.js | 2 +- .../src/main/webapp/resources/gulpfile.js | 1 + .../main/webapp/resources/package-lock.json | 81 +++++++------------ .../src/main/webapp/resources/package.json | 4 +- pom.xml | 4 +- 39 files changed, 573 insertions(+), 427 deletions(-) create mode 100755 pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthAction.java create mode 100755 pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthorizationInterceptor.java rename pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/{filter/AuthFilter.java => auth/LoginAuthenticationFilter.java} (74%) create mode 100755 pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/VersionController.java delete mode 100755 pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README.md delete mode 100755 pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README_zh.md create mode 100755 pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/services/version_service.js diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index 31738e563..a5b652d61 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -25,6 +25,7 @@ 1.5.22 3.6.0 1.2.0 + 1.2.62 3.0.52.ALL @@ -129,6 +130,12 @@ mysql-connector-java ${mysql.connector.version} + + + com.alibaba + fastjson + ${fastjson.version} + io.swagger diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java index 609f7076d..9679af060 100755 --- a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java +++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java @@ -17,25 +17,32 @@ package com.pig4cloud.pigx.common.sentinel; -import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager; +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; import com.pig4cloud.pigx.common.sentinel.handle.PigxUrlBlockHandler; import com.pig4cloud.pigx.common.sentinel.parser.PigxHeaderRequestOriginParser; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.annotation.PostConstruct; - /** * @author lengleng + * @date 2020-02-12 *

* sentinel 配置 */ @Configuration public class SentinelAutoConfiguration { - @PostConstruct - public void initWebCallbackManager() { - WebCallbackManager.setUrlBlockHandler(new PigxUrlBlockHandler()); - WebCallbackManager.setRequestOriginParser(new PigxHeaderRequestOriginParser()); + @Bean + @ConditionalOnMissingBean + public BlockExceptionHandler blockExceptionHandler() { + return new PigxUrlBlockHandler(); } + @Bean + @ConditionalOnMissingBean + public RequestOriginParser requestOriginParser(){ + return new PigxHeaderRequestOriginParser(); + } } diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java index 0cdd8115c..691e2c618 100644 --- a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java +++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java @@ -19,7 +19,7 @@ package com.pig4cloud.pigx.common.sentinel.handle; import cn.hutool.http.ContentType; import cn.hutool.json.JSONUtil; -import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler; +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.pig4cloud.pigx.common.core.util.R; import lombok.extern.slf4j.Slf4j; @@ -27,7 +27,6 @@ import org.springframework.http.HttpStatus; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; /** * @author lengleng @@ -36,10 +35,10 @@ import java.io.IOException; * 降级 限流策略 */ @Slf4j -public class PigxUrlBlockHandler implements UrlBlockHandler { - @Override - public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException { +public class PigxUrlBlockHandler implements BlockExceptionHandler { + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { log.error("sentinel 降级 资源名称{}", e.getRule().getResource(), e); response.setContentType(ContentType.JSON.toString()); diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java index efcc91c60..2b4308f56 100644 --- a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java +++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java @@ -17,7 +17,7 @@ package com.pig4cloud.pigx.common.sentinel.parser; -import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser; +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; import javax.servlet.http.HttpServletRequest; diff --git a/pigx-visual/pigx-sentinel-dashboard/pom.xml b/pigx-visual/pigx-sentinel-dashboard/pom.xml index bdcff7a92..6a7e16359 100755 --- a/pigx-visual/pigx-sentinel-dashboard/pom.xml +++ b/pigx-visual/pigx-sentinel-dashboard/pom.xml @@ -20,7 +20,6 @@ com.alibaba.csp sentinel-web-servlet - 1.6.3 com.alibaba.csp @@ -29,14 +28,11 @@ com.alibaba.csp sentinel-parameter-flow-control - 1.6.3 com.alibaba.csp sentinel-api-gateway-adapter-common - 1.6.3 - org.springframework.boot spring-boot-starter-web @@ -50,6 +46,7 @@ org.springframework.boot spring-boot-starter-logging + log4j log4j @@ -82,11 +79,6 @@ httpcore-nio 4.4.6 - - com.alibaba - fastjson - 1.2.58 - diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthAction.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthAction.java new file mode 100755 index 000000000..f521c04df --- /dev/null +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthAction.java @@ -0,0 +1,47 @@ +/* + * 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.auth; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author lkxiaolou + * @since 1.7.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Target({ElementType.METHOD}) +public @interface AuthAction { + + /** + * @return the privilege type + */ + AuthService.PrivilegeType value(); + + /** + * @return the target name to control + */ + String targetName() default "app"; + + /** + * @return the message when permission is denied + */ + String message() default "Permission denied"; +} diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthorizationInterceptor.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthorizationInterceptor.java new file mode 100755 index 000000000..19472521a --- /dev/null +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/AuthorizationInterceptor.java @@ -0,0 +1,72 @@ +/* + * 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.auth; + +import com.alibaba.csp.sentinel.dashboard.domain.Result; +import com.alibaba.fastjson.JSON; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Method; + +/** + * The web interceptor for privilege-based authorization. + * + * @author lkxiaolou + * @since 1.7.1 + */ +@Component +public class AuthorizationInterceptor implements HandlerInterceptor { + + @Autowired + private AuthService authService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + if (handler.getClass().isAssignableFrom(HandlerMethod.class)) { + Method method = ((HandlerMethod) handler).getMethod(); + + AuthAction authAction = method.getAnnotation(AuthAction.class); + if (authAction != null) { + AuthService.AuthUser authUser = authService.getAuthUser(request); + if (authUser == null) { + responseNoPrivilegeMsg(response, authAction.message()); + return false; + } + String target = request.getParameter(authAction.targetName()); + + if (!authUser.authTarget(target, authAction.value())) { + responseNoPrivilegeMsg(response, authAction.message()); + return false; + } + } + } + + return true; + } + + private void responseNoPrivilegeMsg(HttpServletResponse response, String message) throws IOException { + Result result = Result.ofFail(-1, message); + response.addHeader("Content-Type", "application/json;charset=UTF-8"); + response.getOutputStream().write(JSON.toJSONBytes(result)); + } +} diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/filter/AuthFilter.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/LoginAuthenticationFilter.java similarity index 74% rename from pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/filter/AuthFilter.java rename to pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/LoginAuthenticationFilter.java index 45972c4f1..f489b48e7 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/filter/AuthFilter.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/LoginAuthenticationFilter.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.csp.sentinel.dashboard.filter; +package com.alibaba.csp.sentinel.dashboard.auth; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -30,39 +29,46 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + import java.io.IOException; import java.util.List; /** - * Servlet Filter that authenticate requests. + *

The Servlet filter for authentication.

* - * Note: - * Some urls are excluded as they needn't auth, such as: + *

Note: some urls are excluded as they needn't auth, such as:

+ * * - * Index url: / - * Authentication request url: /login,logout - * Used for client: /registry/machine - * Static resources: htm,html,js and so on. - * - * The excluded urls and urlSuffixes are configured in application.properties + * The excluded urls and urlSuffixes could be configured in {@code application.properties} file. * * @author cdfive * @since 1.6.0 */ @Component -public class AuthFilter implements Filter { +public class LoginAuthenticationFilter implements Filter { private static final String URL_SUFFIX_DOT = "."; - /**Some urls which needn't auth, such as /auth/login,/registry/machine and so on*/ + /** + * Some urls which needn't auth, such as /auth/login, /registry/machine and so on. + */ @Value("#{'${auth.filter.exclude-urls}'.split(',')}") private List authFilterExcludeUrls; - /**Some urls with suffixes which needn't auth, such as htm,html,js and so on*/ + /** + * Some urls with suffixes which needn't auth, such as htm, html, js and so on. + */ @Value("#{'${auth.filter.exclude-url-suffixes}'.split(',')}") private List authFilterExcludeUrlSuffixes; - /**Authentication using AuthService interface*/ + /** + * Authentication using AuthService interface. + */ @Autowired private AuthService authService; @@ -72,13 +78,14 @@ public class AuthFilter implements Filter { } @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; - String requestURI = httpRequest.getRequestURI(); + String servletPath = httpRequest.getServletPath(); // Exclude the urls which needn't auth - if (authFilterExcludeUrls.contains(requestURI)) { + if (authFilterExcludeUrls.contains(servletPath)) { chain.doFilter(request, response); return; } @@ -94,7 +101,7 @@ public class AuthFilter implements Filter { authFilterExcludeUrlSuffix = URL_SUFFIX_DOT + authFilterExcludeUrlSuffix; } - if (requestURI.endsWith(authFilterExcludeUrlSuffix)) { + if (servletPath.endsWith(authFilterExcludeUrlSuffix)) { chain.doFilter(request, response); return; } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/SimpleWebAuthServiceImpl.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/SimpleWebAuthServiceImpl.java index 1cae8a60d..5d9599ee9 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/SimpleWebAuthServiceImpl.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/auth/SimpleWebAuthServiceImpl.java @@ -15,6 +15,7 @@ */ package com.alibaba.csp.sentinel.dashboard.auth; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -25,16 +26,17 @@ import javax.servlet.http.HttpSession; * @author cdfive * @since 1.6.0 */ -@Primary @Component +@Primary +@ConditionalOnProperty(name = "auth.enabled", matchIfMissing = true) public class SimpleWebAuthServiceImpl implements AuthService { - public static final String WEB_SESSTION_KEY = "session_sentinel_admin"; + public static final String WEB_SESSION_KEY = "session_sentinel_admin"; @Override public AuthUser getAuthUser(HttpServletRequest request) { HttpSession session = request.getSession(); - Object sentinelUserObj = session.getAttribute(SimpleWebAuthServiceImpl.WEB_SESSTION_KEY); + Object sentinelUserObj = session.getAttribute(SimpleWebAuthServiceImpl.WEB_SESSION_KEY); if (sentinelUserObj != null && sentinelUserObj instanceof AuthUser) { return (AuthUser) sentinelUserObj; } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java index 5db635101..008e67c1e 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java @@ -62,6 +62,7 @@ import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerFlowConfig import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerTransportConfig; import com.alibaba.csp.sentinel.dashboard.util.VersionUtils; +import org.apache.http.Consts; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; @@ -175,12 +176,7 @@ public class SentinelApiClient { for (Entry entry : params.entrySet()) { list.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } - try { - httpPost.setEntity(new UrlEncodedFormEntity(list)); - } catch (UnsupportedEncodingException e) { - logger.warn("httpPostContent encode entity error: {}", params, e); - return null; - } + httpPost.setEntity(new UrlEncodedFormEntity(list, Consts.UTF_8)); } return httpPost; } @@ -369,17 +365,44 @@ public class SentinelApiClient { params.put("type", type); params.put("data", data); String result = executeCommand(app, ip, port, SET_RULES_PATH, params, true).get(); - logger.info("setRules: {}", result); + logger.info("setRules result: {}, type={}", result, type); return true; - } catch (InterruptedException | ExecutionException e) { - logger.warn("setRules api failed: {}", type, e); + } catch (InterruptedException e) { + logger.warn("setRules API failed: {}", type, e); + return false; + } catch (ExecutionException e) { + logger.warn("setRules API failed: {}", type, e.getCause()); return false; } catch (Exception e) { - logger.warn("setRules failed", e); + logger.error("setRules API failed, type={}", type, e); return false; } } + private CompletableFuture setRulesAsync(String app, String ip, int port, String type, List entities) { + try { + AssertUtil.notNull(entities, "rules cannot be null"); + AssertUtil.notEmpty(app, "Bad app name"); + AssertUtil.notEmpty(ip, "Bad machine IP"); + AssertUtil.isTrue(port > 0, "Bad machine port"); + String data = JSON.toJSONString( + entities.stream().map(r -> r.toRule()).collect(Collectors.toList())); + Map params = new HashMap<>(2); + params.put("type", type); + params.put("data", data); + return executeCommand(app, ip, port, SET_RULES_PATH, params, true) + .thenCompose(r -> { + if ("success".equalsIgnoreCase(r.trim())) { + return CompletableFuture.completedFuture(null); + } + return AsyncUtils.newFailedFuture(new CommandFailedException(r)); + }); + } catch (Exception e) { + logger.error("setRulesAsync API failed, type={}", type, e); + return AsyncUtils.newFailedFuture(e); + } + } + public List fetchResourceOfMachine(String ip, int port, String type) { return fetchItems(ip, port, RESOURCE_URL_PATH, type, NodeVo.class); } @@ -393,7 +416,7 @@ public class SentinelApiClient { * @return */ public List fetchClusterNodeOfMachine(String ip, int port, boolean includeZero) { - String type = "noZero"; + String type = "notZero"; if (includeZero) { type = "zero"; } @@ -491,6 +514,10 @@ public class SentinelApiClient { return setRules(app, ip, port, FLOW_RULE_TYPE, rules); } + public CompletableFuture setFlowRuleOfMachineAsync(String app, String ip, int port, List rules) { + return setRulesAsync(app, ip, port, FLOW_RULE_TYPE, rules); + } + /** * set rules of the machine. rules == null will return immediately; * rules.isEmpty() means setting the rules to empty. diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/config/WebConfig.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/config/WebConfig.java index 3307fc0c0..92e51e54a 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/config/WebConfig.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/config/WebConfig.java @@ -15,18 +15,28 @@ */ package com.alibaba.csp.sentinel.dashboard.config; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter; -import com.alibaba.csp.sentinel.dashboard.filter.AuthFilter; +import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager; +import com.alibaba.csp.sentinel.dashboard.auth.AuthorizationInterceptor; +import com.alibaba.csp.sentinel.dashboard.auth.LoginAuthenticationFilter; +import com.alibaba.csp.sentinel.util.StringUtil; + 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; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import javax.annotation.PostConstruct; import javax.servlet.Filter; /** @@ -38,7 +48,15 @@ public class WebConfig implements WebMvcConfigurer { private final Logger logger = LoggerFactory.getLogger(WebConfig.class); @Autowired - private AuthFilter authFilter; + private LoginAuthenticationFilter loginAuthenticationFilter; + + @Autowired + private AuthorizationInterceptor authorizationInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(authorizationInterceptor).addPathPatterns("/**"); + } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { @@ -61,16 +79,35 @@ public class WebConfig implements WebMvcConfigurer { registration.addUrlPatterns("/*"); registration.setName("sentinelFilter"); registration.setOrder(1); + // If this is enabled, the entrance of all Web URL resources will be unified as a single context name. + // In most scenarios that's enough, and it could reduce the memory footprint. + registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "true"); logger.info("Sentinel servlet CommonFilter registered"); return registration; } + @PostConstruct + public void doInit() { + Set suffixSet = new HashSet<>(Arrays.asList(".js", ".css", ".html", ".ico", ".txt", + ".woff", ".woff2")); + // Example: register a UrlCleaner to exclude URLs of common static resources. + WebCallbackManager.setUrlCleaner(url -> { + if (StringUtil.isEmpty(url)) { + return url; + } + if (suffixSet.stream().anyMatch(url::endsWith)) { + return null; + } + return url; + }); + } + @Bean public FilterRegistrationBean authenticationFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean<>(); - registration.setFilter(authFilter); + registration.setFilter(loginAuthenticationFilter); registration.addUrlPatterns("/*"); registration.setName("authenticationFilter"); registration.setOrder(0); diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthController.java index 58be6f656..8b01aed23 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthController.java @@ -22,10 +22,10 @@ import com.alibaba.csp.sentinel.dashboard.domain.Result; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @@ -38,7 +38,7 @@ import javax.servlet.http.HttpServletRequest; @RequestMapping("/auth") public class AuthController { - private static Logger LOGGER = LoggerFactory.getLogger(AuthController.class); + private static final Logger LOGGER = LoggerFactory.getLogger(AuthController.class); @Value("${auth.username:sentinel}") private String authUsername; @@ -46,8 +46,11 @@ public class AuthController { @Value("${auth.password:sentinel}") private String authPassword; + @Autowired + private AuthService authService; + @PostMapping("/login") - public Result login(HttpServletRequest request, String username, String password) { + public Result login(HttpServletRequest request, String username, String password) { if (StringUtils.isNotBlank(DashboardConfig.getAuthUsername())) { authUsername = DashboardConfig.getAuthUsername(); } @@ -63,18 +66,27 @@ public class AuthController { */ if (StringUtils.isNotBlank(authUsername) && !authUsername.equals(username) || StringUtils.isNotBlank(authPassword) && !authPassword.equals(password)) { - LOGGER.error("Login failed: Invalid username or password, username=" + username + ", password=" + password); + LOGGER.error("Login failed: Invalid username or password, username=" + username); return Result.ofFail(-1, "Invalid username or password"); } AuthService.AuthUser authUser = new SimpleWebAuthServiceImpl.SimpleWebAuthUserImpl(username); - request.getSession().setAttribute(SimpleWebAuthServiceImpl.WEB_SESSTION_KEY, authUser); + request.getSession().setAttribute(SimpleWebAuthServiceImpl.WEB_SESSION_KEY, authUser); return Result.ofSuccess(authUser); } - @RequestMapping(value = "/logout", method = RequestMethod.POST) - public Result logout(HttpServletRequest request) { + @PostMapping(value = "/logout") + public Result logout(HttpServletRequest request) { request.getSession().invalidate(); return Result.ofSuccess(null); } + + @PostMapping(value = "/check") + public Result check(HttpServletRequest request) { + AuthService.AuthUser authUser = authService.getAuthUser(request); + if (authUser == null) { + return Result.ofFail(-1, "Not logged in"); + } + return Result.ofSuccess(authUser); + } } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java index 2b285eff8..294455f02 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java @@ -18,12 +18,9 @@ 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.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.util.StringUtil; @@ -60,16 +57,11 @@ public class AuthorityRuleController { @Autowired private RuleRepository repository; - @Autowired - private AuthService authService; - @GetMapping("/rules") - public Result> apiQueryAllRulesForMachine(HttpServletRequest request, - @RequestParam String app, + @AuthAction(PrivilegeType.READ_RULE) + public Result> apiQueryAllRulesForMachine(@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"); } @@ -119,10 +111,8 @@ public class AuthorityRuleController { } @PostMapping("/rule") - public Result apiAddAuthorityRule(HttpServletRequest request, - @RequestBody AuthorityRuleEntity entity) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE); + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiAddAuthorityRule(@RequestBody AuthorityRuleEntity entity) { Result checkResult = checkEntityInternal(entity); if (checkResult != null) { return checkResult; @@ -144,11 +134,9 @@ public class AuthorityRuleController { } @PutMapping("/rule/{id}") - public Result apiUpdateParamFlowRule(HttpServletRequest request, - @PathVariable("id") Long id, + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiUpdateParamFlowRule(@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"); } @@ -176,8 +164,8 @@ public class AuthorityRuleController { } @DeleteMapping("/rule/{id}") - public Result apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.DELETE_RULE) + public Result apiDeleteRule(@PathVariable("id") Long id) { if (id == null) { return Result.ofFail(-1, "id cannot be null"); } @@ -185,7 +173,6 @@ public class AuthorityRuleController { if (oldEntity == null) { return Result.ofSuccess(null); } - authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE); try { repository.delete(id); } catch (Exception e) { diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java index 7733129a0..61aaee68a 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java @@ -18,12 +18,9 @@ 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.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.util.StringUtil; @@ -54,14 +51,10 @@ public class DegradeController { @Autowired private SentinelApiClient sentinelApiClient; - @Autowired - private AuthService authService; - @ResponseBody @RequestMapping("/rules.json") - public Result> queryMachineRules(HttpServletRequest request, String app, String ip, Integer port) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(app, PrivilegeType.READ_RULE); + @AuthAction(PrivilegeType.READ_RULE) + public Result> queryMachineRules(String app, String ip, Integer port) { if (StringUtil.isEmpty(app)) { return Result.ofFail(-1, "app can't be null or empty"); @@ -84,12 +77,9 @@ public class DegradeController { @ResponseBody @RequestMapping("/new.json") - public Result add(HttpServletRequest request, - String app, String ip, Integer port, String limitApp, String resource, + @AuthAction(PrivilegeType.WRITE_RULE) + public Result add(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"); } @@ -143,10 +133,9 @@ public class DegradeController { @ResponseBody @RequestMapping("/save.json") - public Result updateIfNotNull(HttpServletRequest request, - Long id, String app, String limitApp, String resource, + @AuthAction(PrivilegeType.WRITE_RULE) + public Result updateIfNotNull(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"); } @@ -159,7 +148,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()); } @@ -195,8 +184,8 @@ public class DegradeController { @ResponseBody @RequestMapping("/delete.json") - public Result delete(HttpServletRequest request, Long id) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.DELETE_RULE) + public Result delete(Long id) { if (id == null) { return Result.ofFail(-1, "id can't be null"); } @@ -205,7 +194,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) { diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java index 71e5b7012..50c4e32f6 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java @@ -17,11 +17,11 @@ package com.alibaba.csp.sentinel.dashboard.controller; import java.util.Date; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; - -import com.alibaba.csp.sentinel.dashboard.auth.AuthService; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser; +import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.util.StringUtil; @@ -57,19 +57,15 @@ public class FlowControllerV1 { @Autowired private InMemoryRuleRepositoryAdapter repository; - @Autowired - private AuthService authService; @Autowired private SentinelApiClient sentinelApiClient; @GetMapping("/rules") - public Result> apiQueryMachineRules(HttpServletRequest request, - @RequestParam String app, + @AuthAction(PrivilegeType.READ_RULE) + public Result> apiQueryMachineRules(@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"); @@ -138,10 +134,8 @@ public class FlowControllerV1 { } @PostMapping("/rule") - public Result apiAddFlowRule(HttpServletRequest request, @RequestBody FlowRuleEntity entity) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE); - + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiAddFlowRule(@RequestBody FlowRuleEntity entity) { Result checkResult = checkEntityInternal(entity); if (checkResult != null) { return checkResult; @@ -154,25 +148,23 @@ public class FlowControllerV1 { entity.setResource(entity.getResource().trim()); try { entity = repository.save(entity); - } catch (Throwable throwable) { - logger.error("Failed to add flow rule", throwable); - return Result.ofThrowable(-1, throwable); + + publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get(5000, TimeUnit.MILLISECONDS); + return Result.ofSuccess(entity); + } catch (Throwable t) { + Throwable e = t instanceof ExecutionException ? t.getCause() : t; + logger.error("Failed to add new flow rule, app={}, ip={}", entity.getApp(), entity.getIp(), e); + return Result.ofFail(-1, e.getMessage()); } - if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) { - logger.error("Publish flow rules failed after rule add"); - } - return Result.ofSuccess(entity); } @PutMapping("/save.json") - public Result updateIfNotNull(HttpServletRequest request, Long id, String app, + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiUpdateFlowRule(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"); } @@ -233,21 +225,23 @@ public class FlowControllerV1 { try { entity = repository.save(entity); if (entity == null) { - return Result.ofFail(-1, "save entity fail"); + return Result.ofFail(-1, "save entity fail: null"); } - } catch (Throwable throwable) { - logger.error("save error:", throwable); - return Result.ofThrowable(-1, throwable); + + publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get(5000, TimeUnit.MILLISECONDS); + return Result.ofSuccess(entity); + } catch (Throwable t) { + Throwable e = t instanceof ExecutionException ? t.getCause() : t; + logger.error("Error when updating flow rules, app={}, ip={}, ruleId={}", entity.getApp(), + entity.getIp(), id, e); + return Result.ofFail(-1, e.getMessage()); } - if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) { - logger.info("publish flow rules fail after rule update"); - } - return Result.ofSuccess(entity); } @DeleteMapping("/delete.json") - public Result delete(HttpServletRequest request, Long id) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiDeleteFlowRule(Long id) { + if (id == null) { return Result.ofFail(-1, "id can't be null"); } @@ -255,20 +249,25 @@ public class FlowControllerV1 { if (oldEntity == null) { return Result.ofSuccess(null); } - authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE); + try { repository.delete(id); } catch (Exception e) { return Result.ofFail(-1, e.getMessage()); } - if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) { - logger.info("publish flow rules fail after rule delete"); + try { + publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort()).get(5000, TimeUnit.MILLISECONDS); + return Result.ofSuccess(id); + } catch (Throwable t) { + Throwable e = t instanceof ExecutionException ? t.getCause() : t; + logger.error("Error when deleting flow rules, app={}, ip={}, id={}", oldEntity.getApp(), + oldEntity.getIp(), id, e); + return Result.ofFail(-1, e.getMessage()); } - return Result.ofSuccess(id); } - private boolean publishRules(String app, String ip, Integer port) { + private CompletableFuture publishRules(String app, String ip, Integer port) { List rules = repository.findAllByMachine(MachineInfo.of(app, ip, port)); - return sentinelApiClient.setFlowRuleOfMachine(app, ip, port, rules); + return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules); } } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java index 1a456488c..f03925eee 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java @@ -15,43 +15,30 @@ */ package com.alibaba.csp.sentinel.dashboard.controller; +import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; +import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; +import com.alibaba.csp.sentinel.dashboard.client.CommandNotFoundException; +import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; +import com.alibaba.csp.sentinel.dashboard.datasource.entity.SentinelVersion; +import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; +import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement; +import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; +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 com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + import java.util.Date; import java.util.List; 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.auth.AuthService; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser; -import com.alibaba.csp.sentinel.dashboard.auth.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.SentinelVersion; -import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; -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; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - /** * @author Eric Zhao * @since 0.2.1 @@ -69,9 +56,6 @@ public class ParamFlowRuleController { @Autowired private RuleRepository repository; - @Autowired - private AuthService authService; - private boolean checkIfSupported(String app, String ip, int port) { try { return Optional.ofNullable(appManagement.getDetailApp(app)) @@ -86,12 +70,10 @@ public class ParamFlowRuleController { } @GetMapping("/rules") - public Result> apiQueryAllRulesForMachine(HttpServletRequest request, - @RequestParam String app, + @AuthAction(PrivilegeType.READ_RULE) + public Result> apiQueryAllRulesForMachine(@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"); } @@ -127,10 +109,8 @@ public class ParamFlowRuleController { } @PostMapping("/rule") - public Result apiAddParamFlowRule(HttpServletRequest request, - @RequestBody ParamFlowRuleEntity entity) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE); + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiAddParamFlowRule(@RequestBody ParamFlowRuleEntity entity) { Result checkResult = checkEntityInternal(entity); if (checkResult != null) { return checkResult; @@ -198,10 +178,9 @@ public class ParamFlowRuleController { } @PutMapping("/rule/{id}") - public Result apiUpdateParamFlowRule(HttpServletRequest request, - @PathVariable("id") Long id, + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiUpdateParamFlowRule(@PathVariable("id") Long id, @RequestBody ParamFlowRuleEntity entity) { - AuthUser authUser = authService.getAuthUser(request); if (id == null || id <= 0) { return Result.ofFail(-1, "Invalid id"); } @@ -209,7 +188,7 @@ public class ParamFlowRuleController { if (oldEntity == null) { return Result.ofFail(-1, "id " + id + " does not exist"); } - authUser.authTarget(oldEntity.getApp(), PrivilegeType.WRITE_RULE); + Result checkResult = checkEntityInternal(entity); if (checkResult != null) { return checkResult; @@ -239,8 +218,8 @@ public class ParamFlowRuleController { } @DeleteMapping("/rule/{id}") - public Result apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.DELETE_RULE) + public Result apiDeleteRule(@PathVariable("id") Long id) { if (id == null) { return Result.ofFail(-1, "id cannot be null"); } @@ -248,7 +227,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(); diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java index 66d29f580..daa0b98b5 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java @@ -18,10 +18,7 @@ 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.auth.AuthService; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser; +import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository; import com.alibaba.csp.sentinel.util.StringUtil; @@ -51,8 +48,6 @@ public class SystemController { private RuleRepository repository; @Autowired private SentinelApiClient sentinelApiClient; - @Autowired - private AuthService authService; private Result checkBasicParams(String app, String ip, Integer port) { if (StringUtil.isEmpty(app)) { @@ -71,11 +66,9 @@ public class SystemController { } @GetMapping("/rules.json") - public Result> apiQueryMachineRules(HttpServletRequest request, String app, String ip, + @AuthAction(PrivilegeType.READ_RULE) + public Result> apiQueryMachineRules(String app, String ip, Integer port) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(app, PrivilegeType.READ_RULE); - Result> checkResult = checkBasicParams(app, ip, port); if (checkResult != null) { return checkResult; @@ -101,11 +94,10 @@ public class SystemController { } @RequestMapping("/new.json") - public Result apiAdd(HttpServletRequest request, String app, String ip, Integer port, + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiAdd(String app, String ip, Integer port, Double highestSystemLoad, Double highestCpuUsage, Long avgRt, Long maxThread, Double qps) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(app, PrivilegeType.WRITE_RULE); Result checkResult = checkBasicParams(app, ip, port); if (checkResult != null) { @@ -168,10 +160,9 @@ public class SystemController { } @GetMapping("/save.json") - public Result apiUpdateIfNotNull(HttpServletRequest request, - Long id, String app, Double highestSystemLoad, Double highestCpuUsage, - Long avgRt, Long maxThread, Double qps) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.WRITE_RULE) + public Result apiUpdateIfNotNull(Long id, String app, Double highestSystemLoad, + Double highestCpuUsage, Long avgRt, Long maxThread, Double qps) { if (id == null) { return Result.ofFail(-1, "id can't be null"); } @@ -179,7 +170,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()); } @@ -231,8 +222,8 @@ public class SystemController { } @RequestMapping("/delete.json") - public Result delete(HttpServletRequest request, Long id) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.DELETE_RULE) + public Result delete(Long id) { if (id == null) { return Result.ofFail(-1, "id can't be null"); } @@ -240,7 +231,6 @@ public class SystemController { if (oldEntity == null) { return Result.ofSuccess(null); } - authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE); try { repository.delete(id); } catch (Throwable throwable) { diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/VersionController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/VersionController.java new file mode 100755 index 000000000..69d66ea13 --- /dev/null +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/VersionController.java @@ -0,0 +1,49 @@ +/* + * 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.controller; + +import com.alibaba.csp.sentinel.dashboard.domain.Result; +import com.alibaba.csp.sentinel.util.StringUtil; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author hisenyuan + * @since 1.7.0 + */ +@RestController +public class VersionController { + + private static final String VERSION_PATTERN = "-"; + + @Value("${sentinel.dashboard.version:}") + private String sentinelDashboardVersion; + + @GetMapping("/version") + public Result apiGetVersion() { + if (StringUtil.isNotBlank(sentinelDashboardVersion)) { + String res = sentinelDashboardVersion; + if (sentinelDashboardVersion.contains(VERSION_PATTERN)) { + res = sentinelDashboardVersion.substring(0, sentinelDashboardVersion.indexOf(VERSION_PATTERN)); + } + return Result.ofSuccess(res); + } else { + return Result.ofFail(1, "getVersion failed: empty version"); + } + } +} diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayApiController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayApiController.java index 378e3cc3c..c7a405d9c 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayApiController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayApiController.java @@ -15,6 +15,7 @@ */ package com.alibaba.csp.sentinel.dashboard.controller.gateway; +import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService; import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; @@ -55,13 +56,9 @@ public class GatewayApiController { @Autowired private SentinelApiClient sentinelApiClient; - @Autowired - private AuthService authService; - @GetMapping("/list.json") - public Result> queryApis(HttpServletRequest request, String app, String ip, Integer port) { - AuthService.AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(app, AuthService.PrivilegeType.READ_RULE); + @AuthAction(AuthService.PrivilegeType.READ_RULE) + public Result> queryApis(String app, String ip, Integer port) { if (StringUtil.isEmpty(app)) { return Result.ofFail(-1, "app can't be null or empty"); @@ -84,16 +81,14 @@ public class GatewayApiController { } @PostMapping("/new.json") + @AuthAction(AuthService.PrivilegeType.WRITE_RULE) public Result addApi(HttpServletRequest request, @RequestBody AddApiReqVo reqVo) { - AuthService.AuthUser authUser = authService.getAuthUser(request); String app = reqVo.getApp(); if (StringUtil.isBlank(app)) { return Result.ofFail(-1, "app can't be null or empty"); } - authUser.authTarget(app, AuthService.PrivilegeType.WRITE_RULE); - ApiDefinitionEntity entity = new ApiDefinitionEntity(); entity.setApp(app.trim()); @@ -169,16 +164,13 @@ public class GatewayApiController { } @PostMapping("/save.json") - public Result updateApi(HttpServletRequest request, @RequestBody UpdateApiReqVo reqVo) { - AuthService.AuthUser authUser = authService.getAuthUser(request); - + @AuthAction(AuthService.PrivilegeType.WRITE_RULE) + public Result updateApi(@RequestBody UpdateApiReqVo reqVo) { String app = reqVo.getApp(); if (StringUtil.isBlank(app)) { return Result.ofFail(-1, "app can't be null or empty"); } - authUser.authTarget(app, AuthService.PrivilegeType.WRITE_RULE); - Long id = reqVo.getId(); if (id == null) { return Result.ofFail(-1, "id can't be null"); @@ -235,9 +227,9 @@ public class GatewayApiController { } @PostMapping("/delete.json") - public Result deleteApi(HttpServletRequest request, Long id) { - AuthService.AuthUser authUser = authService.getAuthUser(request); + @AuthAction(AuthService.PrivilegeType.DELETE_RULE) + public Result deleteApi(Long id) { if (id == null) { return Result.ofFail(-1, "id can't be null"); } @@ -247,8 +239,6 @@ public class GatewayApiController { return Result.ofSuccess(null); } - authUser.authTarget(oldEntity.getApp(), AuthService.PrivilegeType.DELETE_RULE); - try { repository.delete(id); } catch (Throwable throwable) { diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayFlowRuleController.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayFlowRuleController.java index 7d84262fe..018916378 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayFlowRuleController.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/gateway/GatewayFlowRuleController.java @@ -16,6 +16,7 @@ package com.alibaba.csp.sentinel.dashboard.controller.gateway; +import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService; import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; @@ -32,7 +33,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Date; import java.util.List; @@ -59,13 +59,9 @@ public class GatewayFlowRuleController { @Autowired private SentinelApiClient sentinelApiClient; - @Autowired - private AuthService authService; - @GetMapping("/list.json") - public Result> queryFlowRules(HttpServletRequest request, String app, String ip, Integer port) { - AuthService.AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(app, AuthService.PrivilegeType.READ_RULE); + @AuthAction(AuthService.PrivilegeType.READ_RULE) + public Result> queryFlowRules(String app, String ip, Integer port) { if (StringUtil.isEmpty(app)) { return Result.ofFail(-1, "app can't be null or empty"); @@ -88,16 +84,14 @@ public class GatewayFlowRuleController { } @PostMapping("/new.json") - public Result addFlowRule(HttpServletRequest request, @RequestBody AddFlowRuleReqVo reqVo) { - AuthService.AuthUser authUser = authService.getAuthUser(request); + @AuthAction(AuthService.PrivilegeType.WRITE_RULE) + public Result addFlowRule(@RequestBody AddFlowRuleReqVo reqVo) { String app = reqVo.getApp(); if (StringUtil.isBlank(app)) { return Result.ofFail(-1, "app can't be null or empty"); } - authUser.authTarget(app, AuthService.PrivilegeType.WRITE_RULE); - GatewayFlowRuleEntity entity = new GatewayFlowRuleEntity(); entity.setApp(app.trim()); @@ -258,16 +252,14 @@ public class GatewayFlowRuleController { } @PostMapping("/save.json") - public Result updateFlowRule(HttpServletRequest request, @RequestBody UpdateFlowRuleReqVo reqVo) { - AuthService.AuthUser authUser = authService.getAuthUser(request); + @AuthAction(AuthService.PrivilegeType.WRITE_RULE) + public Result updateFlowRule(@RequestBody UpdateFlowRuleReqVo reqVo) { String app = reqVo.getApp(); if (StringUtil.isBlank(app)) { return Result.ofFail(-1, "app can't be null or empty"); } - authUser.authTarget(app, AuthService.PrivilegeType.WRITE_RULE); - Long id = reqVo.getId(); if (id == null) { return Result.ofFail(-1, "id can't be null"); @@ -408,8 +400,8 @@ public class GatewayFlowRuleController { @PostMapping("/delete.json") - public Result deleteFlowRule(HttpServletRequest request, Long id) { - AuthService.AuthUser authUser = authService.getAuthUser(request); + @AuthAction(AuthService.PrivilegeType.DELETE_RULE) + public Result deleteFlowRule(Long id) { if (id == null) { return Result.ofFail(-1, "id can't be null"); @@ -420,8 +412,6 @@ public class GatewayFlowRuleController { return Result.ofSuccess(null); } - authUser.authTarget(oldEntity.getApp(), AuthService.PrivilegeType.DELETE_RULE); - try { repository.delete(id); } catch (Throwable throwable) { diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java index 41aea755b..c79261cdf 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/v2/FlowControllerV2.java @@ -18,10 +18,8 @@ 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.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService; -import com.alibaba.csp.sentinel.dashboard.auth.AuthService.AuthUser; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.util.StringUtil; @@ -67,13 +65,9 @@ public class FlowControllerV2 { @Qualifier("flowRuleDefaultPublisher") private DynamicRulePublisher> rulePublisher; - @Autowired - private AuthService authService; - @GetMapping("/rules") - public Result> apiQueryMachineRules(HttpServletRequest request, @RequestParam String app) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(app, PrivilegeType.READ_RULE); + @AuthAction(PrivilegeType.READ_RULE) + public Result> apiQueryMachineRules(@RequestParam String app) { if (StringUtil.isEmpty(app)) { return Result.ofFail(-1, "app can't be null or empty"); @@ -141,9 +135,8 @@ public class FlowControllerV2 { } @PostMapping("/rule") - public Result apiAddFlowRule(HttpServletRequest request, @RequestBody FlowRuleEntity entity) { - AuthUser authUser = authService.getAuthUser(request); - authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE); + @AuthAction(value = PrivilegeType.WRITE_RULE) + public Result apiAddFlowRule(@RequestBody FlowRuleEntity entity) { Result checkResult = checkEntityInternal(entity); if (checkResult != null) { @@ -166,10 +159,10 @@ public class FlowControllerV2 { } @PutMapping("/rule/{id}") - public Result apiUpdateFlowRule(HttpServletRequest request, - @PathVariable("id") Long id, + @AuthAction(PrivilegeType.WRITE_RULE) + + public Result apiUpdateFlowRule(@PathVariable("id") Long id, @RequestBody FlowRuleEntity entity) { - AuthUser authUser = authService.getAuthUser(request); if (id == null || id <= 0) { return Result.ofFail(-1, "Invalid id"); } @@ -180,7 +173,6 @@ 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()); @@ -208,8 +200,8 @@ public class FlowControllerV2 { } @DeleteMapping("/rule/{id}") - public Result apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) { - AuthUser authUser = authService.getAuthUser(request); + @AuthAction(PrivilegeType.DELETE_RULE) + public Result apiDeleteRule(@PathVariable("id") Long id) { if (id == null || id <= 0) { return Result.ofFail(-1, "Invalid id"); } @@ -217,7 +209,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()); diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java index 924962010..a085d898b 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/AuthorityRuleEntity.java @@ -17,7 +17,7 @@ package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; import com.alibaba.csp.sentinel.util.AssertUtil; - +import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonIgnore; /** @@ -26,7 +26,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; */ public class AuthorityRuleEntity extends AbstractRuleEntity { - public AuthorityRuleEntity() {} + public AuthorityRuleEntity() { + } public AuthorityRuleEntity(AuthorityRule authorityRule) { AssertUtil.notNull(authorityRule, "Authority rule should not be null"); @@ -42,16 +43,19 @@ public class AuthorityRuleEntity extends AbstractRuleEntity { } @JsonIgnore + @JSONField(serialize = false) public String getLimitApp() { return rule.getLimitApp(); } @JsonIgnore + @JSONField(serialize = false) public String getResource() { return rule.getResource(); } @JsonIgnore + @JSONField(serialize = false) public int getStrategy() { return rule.getStrategy(); } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/ParamFlowRuleEntity.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/ParamFlowRuleEntity.java index 5ffb1fe10..56bd773c0 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/ParamFlowRuleEntity.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/rule/ParamFlowRuleEntity.java @@ -15,22 +15,23 @@ */ package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule; -import java.util.List; - import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowClusterConfig; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; import com.alibaba.csp.sentinel.util.AssertUtil; - +import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonIgnore; +import java.util.List; + /** * @author Eric Zhao * @since 0.2.1 */ public class ParamFlowRuleEntity extends AbstractRuleEntity { - public ParamFlowRuleEntity() {} + public ParamFlowRuleEntity() { + } public ParamFlowRuleEntity(ParamFlowRule rule) { AssertUtil.notNull(rule, "Authority rule should not be null"); @@ -46,61 +47,73 @@ public class ParamFlowRuleEntity extends AbstractRuleEntity { } @JsonIgnore + @JSONField(serialize = false) public String getLimitApp() { return rule.getLimitApp(); } @JsonIgnore + @JSONField(serialize = false) public String getResource() { return rule.getResource(); } @JsonIgnore + @JSONField(serialize = false) public int getGrade() { return rule.getGrade(); } @JsonIgnore + @JSONField(serialize = false) public Integer getParamIdx() { return rule.getParamIdx(); } @JsonIgnore + @JSONField(serialize = false) public double getCount() { return rule.getCount(); } @JsonIgnore + @JSONField(serialize = false) public List getParamFlowItemList() { return rule.getParamFlowItemList(); } @JsonIgnore + @JSONField(serialize = false) public int getControlBehavior() { return rule.getControlBehavior(); } @JsonIgnore + @JSONField(serialize = false) public int getMaxQueueingTimeMs() { return rule.getMaxQueueingTimeMs(); } @JsonIgnore + @JSONField(serialize = false) public int getBurstCount() { return rule.getBurstCount(); } @JsonIgnore + @JSONField(serialize = false) public long getDurationInSec() { return rule.getDurationInSec(); } @JsonIgnore + @JSONField(serialize = false) public boolean isClusterMode() { return rule.isClusterMode(); } @JsonIgnore + @JSONField(serialize = false) public ParamFlowClusterConfig getClusterConfig() { return rule.getClusterConfig(); } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/ResourceTreeNode.java b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/ResourceTreeNode.java index fa2e7ca9b..be576160c 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/ResourceTreeNode.java +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/ResourceTreeNode.java @@ -56,7 +56,7 @@ public class ResourceTreeNode { ResourceTreeNode node = fromNodeVo(vo); map.put(node.id, node); // real root - if (node.parentId == null) { + if (node.parentId == null || node.parentId.isEmpty()) { root = node; } else if (map.containsKey(node.parentId)) { map.get(node.parentId).children.add(node); diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/resources/application.yml b/pigx-visual/pigx-sentinel-dashboard/src/main/resources/application.yml index d87941658..bace37e18 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/resources/application.yml +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/resources/application.yml @@ -19,5 +19,9 @@ auth: username: sentinel password: sentinel filter: - exclude-urls: /,/auth/login,/auth/logout,/registry/machine + exclude-urls: /,/auth/login,/auth/logout,/registry/machine,/version exclude-url-suffixes: htm,html,js,css,map,ico,ttf,woff,png + +sentinel: + dashboard: + version: 1.7.1 \ No newline at end of file diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README.md b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README.md deleted file mode 100755 index c88ea68c6..000000000 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Sentinel Dashboard Frontend - -## Env Requirement - -- Node.js > 6.x - -## Code Guide - -- [Code Style Guide for HTML/CSS](https://codeguide.bootcss.com/) -- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) - -## Install Packages - -``` -npm install -``` - -## Start Development - -``` -npm start -``` - -## Build for production - -``` -npm run build -``` - -## Credit - -- [sb-admin-angular](https://github.com/start-angular/sb-admin-angular) \ No newline at end of file diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README_zh.md b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README_zh.md deleted file mode 100755 index 5daf33efb..000000000 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/README_zh.md +++ /dev/null @@ -1,32 +0,0 @@ -# Sentinel Dashboard Frontend - -## 环境要求 - -- Node.js > 6.x - -## 编码规范 - -- HTML/CSS 遵循 [Bootstrap 编码规范](https://codeguide.bootcss.com/) -- JavaScript 遵循 [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) 以及最新的 ES 6 标准 - -## 安装依赖 - -``` -npm i -``` - -## 开始本地开发 - -``` -npm start -``` - -## 构建前端资源 - -``` -npm run build -``` - -## Credit - -- [sb-admin-angular](https://github.com/start-angular/sb-admin-angular) \ No newline at end of file diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js index 8e4be2ab4..3c6449372 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js @@ -148,18 +148,18 @@ app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', ' getMachineRules(); confirmDialog.close(); } else { - alert('失败!'); + alert('失败:' + data.msg); } }); }; function addNewRule(rule) { FlowService.newRule(rule).success(function (data) { - if (data.code == 0) { + if (data.code === 0) { getMachineRules(); flowRuleDialog.close(); } else { - alert('失败!'); + alert('失败:' + data.msg); } }); }; @@ -173,7 +173,7 @@ app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', ' function saveRule(rule, edit) { FlowService.saveRule(rule).success(function (data) { - if (data.code == 0) { + if (data.code === 0) { getMachineRules(); if (edit) { flowRuleDialog.close(); @@ -181,7 +181,7 @@ app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', ' confirmDialog.close(); } } else { - alert('失败!'); + alert('失败:' + data.msg); } }); } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js index 1deecc832..f8116be78 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js @@ -98,7 +98,7 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService', let url = '/dashboard/flow/' + $scope.app; $location.path(url); } else { - alert('失败!'); + alert('失败:' + data.msg); } }).error((data, header, config, status) => { alert('未知错误'); @@ -110,10 +110,10 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService', return; } FlowService.newRule(flowRuleDialogScope.currentRule).success(function (data) { - if (data.code == 0) { + if (data.code === 0) { flowRuleDialog.close(); } else { - alert('失败!'); + alert('失败:' + data.msg); } }); } @@ -159,12 +159,12 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService', return; } DegradeService.newRule(degradeRuleDialogScope.currentRule).success(function (data) { - if (data.code == 0) { + if (data.code === 0) { degradeRuleDialog.close(); var url = '/dashboard/degrade/' + $scope.app; $location.path(url); } else { - alert('失败!'); + alert('失败:' + data.msg); } }); } @@ -174,10 +174,10 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService', return; } DegradeService.newRule(degradeRuleDialogScope.currentRule).success(function (data) { - if (data.code == 0) { + if (data.code === 0) { degradeRuleDialog.close(); } else { - alert('失败!'); + alert('失败:' + data.msg); } }); } diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/login.js b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/login.js index 1230129c8..3d49d3c16 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/login.js +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/login.js @@ -22,10 +22,7 @@ app.controller('LoginCtl', ['$scope', '$state', '$window', 'AuthService', AuthService.login(param).success(function (data) { if (data.code == 0) { - $window.localStorage.setItem('session_sentinel_admin', { - username: data.data - }); - + $window.localStorage.setItem('session_sentinel_admin', JSON.stringify(data.data)); $state.go('dashboard'); } else { alert(data.msg); diff --git a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/header/header.html b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/header/header.html index 744e73180..4584e89ba 100755 --- a/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/header/header.html +++ b/pigx-visual/pigx-sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/header/header.html @@ -1,10 +1,10 @@