From 0a65aa897686636406a3a8fce39be818d985aa68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E7=BF=8A=20SionYang?= <37170243+KomachiSion@users.noreply.github.com> Date: Mon, 29 Jun 2020 13:55:42 +0800 Subject: [PATCH] Use new code style for nacos-console module. (#3195) --- console/pom.xml | 16 +-- .../main/java/com/alibaba/nacos/Nacos.java | 6 +- .../nacos/console/config/ConsoleConfig.java | 15 ++- .../console/controller/HealthController.java | 36 ++++--- .../controller/NamespaceController.java | 85 ++++++++-------- .../controller/PermissionController.java | 39 ++++---- .../console/controller/RoleController.java | 41 ++++---- .../controller/ServerStateController.java | 26 +++-- .../console/controller/UserController.java | 98 +++++++++++-------- .../exception/ConsoleExceptionHandler.java | 15 +-- .../filter/JwtAuthenticationTokenFilter.java | 23 ++--- .../nacos/console/model/Namespace.java | 42 ++++---- .../nacos/console/model/NamespaceAllInfo.java | 17 ++-- .../nacos/CustomAuthenticationProvider.java | 15 +-- .../nacos/JwtAuthenticationEntryPoint.java | 16 +-- .../security/nacos/JwtTokenManager.java | 58 ++++++----- .../security/nacos/NacosAuthConfig.java | 95 ++++++++---------- .../security/nacos/NacosAuthManager.java | 40 ++++---- .../nacos/roles/NacosRoleServiceImpl.java | 96 ++++++++++-------- .../security/nacos/users/NacosUser.java | 21 ++-- .../nacos/users/NacosUserDetails.java | 23 ++--- .../users/NacosUserDetailsServiceImpl.java | 33 +++---- .../nacos/console/utils/JwtTokenUtils.java | 95 +++++++++--------- .../console/utils/PasswordEncoderUtil.java | 9 +- .../controller/HealthControllerTest.java | 43 ++++---- .../controller/UserControllerTest.java | 25 ++--- 26 files changed, 537 insertions(+), 491 deletions(-) diff --git a/console/pom.xml b/console/pom.xml index ff0475538..b5bc3fa3e 100644 --- a/console/pom.xml +++ b/console/pom.xml @@ -15,8 +15,8 @@ ~ limitations under the License. --> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.alibaba.nacos @@ -30,7 +30,7 @@ UTF-8 - + ${project.groupId} @@ -44,12 +44,12 @@ ${project.groupId} nacos-naming - + ${project.groupId} nacos-istio - + @@ -91,7 +91,7 @@ runtime - + @@ -102,7 +102,7 @@ - + @@ -111,7 +111,7 @@ - + release-nacos diff --git a/console/src/main/java/com/alibaba/nacos/Nacos.java b/console/src/main/java/com/alibaba/nacos/Nacos.java index 7377d5b21..ba2283db8 100644 --- a/console/src/main/java/com/alibaba/nacos/Nacos.java +++ b/console/src/main/java/com/alibaba/nacos/Nacos.java @@ -21,16 +21,16 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; -import java.util.concurrent.*; - /** + * Nacos starter. + * * @author nacos */ @SpringBootApplication(scanBasePackages = "com.alibaba.nacos") @ServletComponentScan @EnableScheduling public class Nacos { - + public static void main(String[] args) { SpringApplication.run(Nacos.class, args); } diff --git a/console/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java b/console/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java index 0a47b45b6..15f20851f 100644 --- a/console/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java +++ b/console/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.config; +package com.alibaba.nacos.console.config; import com.alibaba.nacos.core.code.ControllerMethodsCache; import org.springframework.beans.factory.annotation.Autowired; @@ -29,6 +29,8 @@ import org.springframework.web.filter.CorsFilter; import javax.annotation.PostConstruct; /** + * Console config. + * * @author yshen * @author nkorange * @since 1.2.0 @@ -37,26 +39,29 @@ import javax.annotation.PostConstruct; @EnableScheduling @PropertySource("/application.properties") public class ConsoleConfig { - + @Autowired private ControllerMethodsCache methodsCache; - + + /** + * Init. + */ @PostConstruct public void init() { methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers"); methodsCache.initClassMethod("com.alibaba.nacos.console.controller"); methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller"); } - + @Bean public CorsFilter corsFilter() { - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.setMaxAge(18000L); config.addAllowedMethod("*"); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/HealthController.java b/console/src/main/java/com/alibaba/nacos/console/controller/HealthController.java index 3c60cdb81..10d879657 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/HealthController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/HealthController.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.controller; import com.alibaba.nacos.config.server.service.repository.PersistService; @@ -28,25 +29,28 @@ import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; /** + * Health Controller. + * * @author hxy1991 */ @RestController("consoleHealth") @RequestMapping("/v1/console/health") public class HealthController { - - private static final Logger logger = LoggerFactory.getLogger(HealthController.class); - + + private static final Logger LOGGER = LoggerFactory.getLogger(HealthController.class); + private final PersistService persistService; + private final OperatorController apiCommands; - + @Autowired public HealthController(PersistService persistService, OperatorController apiCommands) { this.persistService = persistService; this.apiCommands = apiCommands; } - + /** - * Whether the Nacos is in broken states or not, and cannot recover except by being restarted + * Whether the Nacos is in broken states or not, and cannot recover except by being restarted. * * @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that * Nacos is in broken states. @@ -55,9 +59,9 @@ public class HealthController { public ResponseEntity liveness() { return ResponseEntity.ok().body("OK"); } - + /** - * Ready to receive the request or not + * Ready to receive the request or not. * * @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not * ready. @@ -66,39 +70,39 @@ public class HealthController { public ResponseEntity readiness(HttpServletRequest request) { boolean isConfigReadiness = isConfigReadiness(); boolean isNamingReadiness = isNamingReadiness(request); - + if (isConfigReadiness && isNamingReadiness) { return ResponseEntity.ok().body("OK"); } - + if (!isConfigReadiness && !isNamingReadiness) { return ResponseEntity.status(500).body("Config and Naming are not in readiness"); } - + if (!isConfigReadiness) { return ResponseEntity.status(500).body("Config is not in readiness"); } - + return ResponseEntity.status(500).body("Naming is not in readiness"); } - + private boolean isConfigReadiness() { // check db try { persistService.configInfoCount(""); return true; } catch (Exception e) { - logger.error("Config health check fail.", e); + LOGGER.error("Config health check fail.", e); } return false; } - + private boolean isNamingReadiness(HttpServletRequest request) { try { apiCommands.metrics(request); return true; } catch (Exception e) { - logger.error("Naming health check fail.", e); + LOGGER.error("Naming health check fail.", e); } return false; } diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java b/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java index a6164d734..efd441cab 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.controller; import com.alibaba.nacos.common.model.RestResult; @@ -25,7 +26,13 @@ import com.alibaba.nacos.core.auth.ActionTypes; import com.alibaba.nacos.core.auth.Secured; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -35,23 +42,23 @@ import java.util.UUID; import java.util.regex.Pattern; /** - * namespace service + * namespace service. * * @author Nacos */ @RestController @RequestMapping("/v1/console/namespaces") public class NamespaceController { - + @Autowired private PersistService persistService; - - private Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+"); - + + private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+"); + private static final int NAMESPACE_ID_MAX_LENGTH = 128; - + /** - * Get namespace list + * Get namespace list. * * @param request request * @param response response @@ -69,15 +76,15 @@ public class NamespaceController { for (TenantInfo tenantInfo : tenantInfos) { int configCount = persistService.configInfoCount(tenantInfo.getTenantId()); Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), 200, - configCount, 2); + configCount, 2); namespaces.add(namespaceTmp); } rr.setData(namespaces); return rr; } - + /** - * get namespace all info by namespace id + * get namespace all info by namespace id. * * @param request request * @param response response @@ -86,21 +93,21 @@ public class NamespaceController { */ @GetMapping(params = "show=all") public NamespaceAllInfo getNamespace(HttpServletRequest request, HttpServletResponse response, - @RequestParam("namespaceId") String namespaceId) { + @RequestParam("namespaceId") String namespaceId) { // TODO 获取用kp if (StringUtils.isBlank(namespaceId)) { - return new NamespaceAllInfo(namespaceId, "Public", 200, - persistService.configInfoCount(""), 0, "Public Namespace"); + return new NamespaceAllInfo(namespaceId, "Public", 200, persistService.configInfoCount(""), 0, + "Public Namespace"); } else { TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId); int configCount = persistService.configInfoCount(namespaceId); - return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200, - configCount, 2, tenantInfo.getTenantDesc()); + return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200, configCount, 2, + tenantInfo.getTenantDesc()); } } - + /** - * create namespace + * create namespace. * * @param request request * @param response response @@ -111,11 +118,10 @@ public class NamespaceController { @PostMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response, - @RequestParam("customNamespaceId") String namespaceId, - @RequestParam("namespaceName") String namespaceName, - @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { + @RequestParam("customNamespaceId") String namespaceId, @RequestParam("namespaceName") String namespaceName, + @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { // TODO 获取用kp - if(StringUtils.isBlank(namespaceId)){ + if (StringUtils.isBlank(namespaceId)) { namespaceId = UUID.randomUUID().toString(); } else { namespaceId = namespaceId.trim(); @@ -125,32 +131,31 @@ public class NamespaceController { if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) { return false; } - if(persistService.tenantInfoCountByTenantId(namespaceId) > 0){ + if (persistService.tenantInfoCountByTenantId(namespaceId) > 0) { return false; } } persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos", - System.currentTimeMillis()); + System.currentTimeMillis()); return true; } - + /** - * @author klw(213539@qq.com) - * @Description: check namespaceId exist - * @Date 2019/12/10 21:41 - * @param: namespaceId - * @return java.lang.Boolean + * check namespaceId exist. + * + * @param namespaceId namespace id + * @return true if exist, otherwise false */ @GetMapping(params = "checkNamespaceIdExist=true") - public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId){ - if(StringUtils.isBlank(namespaceId)){ + public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId) { + if (StringUtils.isBlank(namespaceId)) { return false; } return (persistService.tenantInfoCountByTenantId(namespaceId) > 0); } - + /** - * edit namespace + * edit namespace. * * @param namespace namespace * @param namespaceShowName namespace ShowName @@ -160,15 +165,15 @@ public class NamespaceController { @PutMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) public Boolean editNamespace(@RequestParam("namespace") String namespace, - @RequestParam("namespaceShowName") String namespaceShowName, - @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { + @RequestParam("namespaceShowName") String namespaceShowName, + @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { // TODO 获取用kp persistService.updateTenantNameAtomic("1", namespace, namespaceShowName, namespaceDesc); return true; } - + /** - * del namespace by id + * del namespace by id. * * @param request request * @param response response @@ -178,9 +183,9 @@ public class NamespaceController { @DeleteMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response, - @RequestParam("namespaceId") String namespaceId) { + @RequestParam("namespaceId") String namespaceId) { persistService.removeTenantInfoAtomic("1", namespaceId); return true; } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java b/console/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java index 34451ac56..4730fa1be 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.controller; +package com.alibaba.nacos.console.controller; import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.console.security.nacos.NacosAuthConfig; @@ -23,11 +23,15 @@ import com.alibaba.nacos.core.auth.ActionTypes; import com.alibaba.nacos.core.auth.Secured; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; /** - * Permission operation controller + * Permission operation controller. * * @author nkorange * @since 1.2.0 @@ -35,12 +39,12 @@ import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/v1/auth/permissions") public class PermissionController { - + @Autowired private NacosRoleServiceImpl nacosRoleService; - + /** - * Query permissions of a role + * Query permissions of a role. * * @param role the role * @param pageNo page index @@ -50,16 +54,16 @@ public class PermissionController { @GetMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.READ) public Object getPermissions(@RequestParam int pageNo, @RequestParam int pageSize, - @RequestParam(name = "role", defaultValue = StringUtils.EMPTY) String role) { + @RequestParam(name = "role", defaultValue = StringUtils.EMPTY) String role) { return nacosRoleService.getPermissionsFromDatabase(role, pageNo, pageSize); } - + /** - * Add a permission to a role + * Add a permission to a role. * - * @param role the role + * @param role the role * @param resource the related resource - * @param action the related action + * @param action the related action * @return ok if succeed */ @PostMapping @@ -68,18 +72,19 @@ public class PermissionController { nacosRoleService.addPermission(role, resource, action); return new RestResult<>(200, "add permission ok!"); } - + /** - * Delete a permission from a role + * Delete a permission from a role. * - * @param role the role + * @param role the role * @param resource the related resource - * @param action the related action + * @param action the related action * @return ok if succeed */ @DeleteMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE) - public Object deletePermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) { + public Object deletePermission(@RequestParam String role, @RequestParam String resource, + @RequestParam String action) { nacosRoleService.deletePermission(role, resource, action); return new RestResult<>(200, "delete permission ok!"); } diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/RoleController.java b/console/src/main/java/com/alibaba/nacos/console/controller/RoleController.java index 6ec008841..bcf19e157 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/RoleController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/RoleController.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.controller; +package com.alibaba.nacos.console.controller; import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.console.security.nacos.NacosAuthConfig; @@ -23,10 +23,15 @@ import com.alibaba.nacos.core.auth.ActionTypes; import com.alibaba.nacos.core.auth.Secured; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; /** - * Role operation controller + * Role operation controller. * * @author nkorange * @since 1.2.0 @@ -34,12 +39,12 @@ import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/v1/auth/roles") public class RoleController { - + @Autowired private NacosRoleServiceImpl roleService; - + /** - * Get roles list + * Get roles list. * * @param pageNo number index of page * @param pageSize page size @@ -49,20 +54,18 @@ public class RoleController { @GetMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.READ) public Object getRoles(@RequestParam int pageNo, @RequestParam int pageSize, - @RequestParam(name = "username", defaultValue = "") String username) { + @RequestParam(name = "username", defaultValue = "") String username) { return roleService.getRolesFromDatabase(username, pageNo, pageSize); } - + /** * Add a role to a user - *

- * This method is used for 2 functions: - * 1. create a role and bind it to GLOBAL_ADMIN. - * 2. bind a role to an user. * - * @param role - * @param username - * @return + *

This method is used for 2 functions: 1. create a role and bind it to GLOBAL_ADMIN. 2. bind a role to an user. + * + * @param role role name + * @param username username + * @return Code 200 and message 'add role ok!' */ @PostMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE) @@ -70,9 +73,9 @@ public class RoleController { roleService.addRole(role, username); return new RestResult<>(200, "add role ok!"); } - + /** - * Delete a role. If no username is specified, all users under this role are deleted + * Delete a role. If no username is specified, all users under this role are deleted. * * @param role role * @param username username @@ -81,7 +84,7 @@ public class RoleController { @DeleteMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE) public Object deleteRole(@RequestParam String role, - @RequestParam(name = "username", defaultValue = StringUtils.EMPTY) String username) { + @RequestParam(name = "username", defaultValue = StringUtils.EMPTY) String username) { if (StringUtils.isBlank(username)) { roleService.deleteRole(role); } else { @@ -89,5 +92,5 @@ public class RoleController { } return new RestResult<>(200, "delete role of user " + username + " ok!"); } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java b/console/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java index e5c70bfc2..c1fc820c2 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.controller; +package com.alibaba.nacos.console.controller; import com.alibaba.nacos.common.utils.VersionUtils; import com.alibaba.nacos.core.utils.ApplicationUtils; @@ -27,23 +27,29 @@ import java.util.HashMap; import java.util.Map; /** - * @author xingxuechao - * on:2019/2/27 11:17 AM + * Server state controller. + * + * @author xingxuechao on:2019/2/27 11:17 AM */ @RestController @RequestMapping("/v1/console/server") public class ServerStateController { - + + /** + * Get server state of current server. + * + * @return state json. + */ @GetMapping("/state") public ResponseEntity serverState() { - Map serverState = new HashMap<>(3); - serverState.put("standalone_mode", ApplicationUtils.getStandaloneMode() ? - ApplicationUtils.STANDALONE_MODE_ALONE : ApplicationUtils.STANDALONE_MODE_CLUSTER); - + Map serverState = new HashMap<>(3); + serverState.put("standalone_mode", ApplicationUtils.getStandaloneMode() ? ApplicationUtils.STANDALONE_MODE_ALONE + : ApplicationUtils.STANDALONE_MODE_CLUSTER); + serverState.put("function_mode", ApplicationUtils.getFunctionMode()); serverState.put("version", VersionUtils.version); - + return ResponseEntity.ok().body(serverState); } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/UserController.java b/console/src/main/java/com/alibaba/nacos/console/controller/UserController.java index c75456c21..340291e9f 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/UserController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/UserController.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.controller; import com.alibaba.nacos.api.common.Constants; @@ -27,9 +28,12 @@ import com.alibaba.nacos.console.security.nacos.users.NacosUser; import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.console.utils.JwtTokenUtils; import com.alibaba.nacos.console.utils.PasswordEncoderUtil; -import com.alibaba.nacos.core.auth.*; +import com.alibaba.nacos.core.auth.AccessException; +import com.alibaba.nacos.core.auth.ActionTypes; +import com.alibaba.nacos.core.auth.AuthConfigs; +import com.alibaba.nacos.core.auth.AuthSystemTypes; +import com.alibaba.nacos.core.auth.Secured; import com.fasterxml.jackson.databind.node.ObjectNode; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -37,14 +41,20 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; /** - * User related methods entry + * User related methods entry. * * @author wfnuser * @author nkorange @@ -52,27 +62,27 @@ import java.util.List; @RestController("user") @RequestMapping({"/v1/auth", "/v1/auth/users"}) public class UserController { - + @Autowired private JwtTokenUtils jwtTokenUtils; - + @Autowired private AuthenticationManager authenticationManager; - + @Autowired private NacosUserDetailsServiceImpl userDetailsService; - + @Autowired private NacosRoleServiceImpl roleService; - + @Autowired private AuthConfigs authConfigs; - + @Autowired private NacosAuthManager authManager; - + /** - * Create a new user + * Create a new user. * * @param username username * @param password password @@ -83,7 +93,7 @@ public class UserController { @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE) @PostMapping public Object createUser(@RequestParam String username, @RequestParam String password) { - + User user = userDetailsService.getUserFromDatabase(username); if (user != null) { throw new IllegalArgumentException("user '" + username + "' already exist!"); @@ -91,9 +101,9 @@ public class UserController { userDetailsService.createUser(username, PasswordEncoderUtil.encode(password)); return new RestResult<>(200, "create user ok!"); } - + /** - * Delete an existed user + * Delete an existed user. * * @param username username of user * @return ok if deleted succeed, keep silent if user not exist @@ -113,9 +123,9 @@ public class UserController { userDetailsService.deleteUser(username); return new RestResult<>(200, "delete user ok!"); } - + /** - * Update an user + * Update an user. * * @param username username of user * @param newPassword new password of user @@ -126,19 +136,19 @@ public class UserController { @PutMapping @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE) public Object updateUser(@RequestParam String username, @RequestParam String newPassword) { - + User user = userDetailsService.getUserFromDatabase(username); if (user == null) { throw new IllegalArgumentException("user " + username + " not exist!"); } - + userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword)); - + return new RestResult<>(200, "update user ok!"); } - + /** - * Get paged users + * Get paged users. * * @param pageNo number index of page * @param pageSize size of page @@ -150,11 +160,11 @@ public class UserController { public Object getUsers(@RequestParam int pageNo, @RequestParam int pageSize) { return userDetailsService.getUsersFromDatabase(pageNo, pageSize); } - + /** * Login to Nacos - *

- * This methods uses username and password to require a new token. + * + *

This methods uses username and password to require a new token. * * @param username username of user * @param password password @@ -164,27 +174,26 @@ public class UserController { * @throws AccessException if user info is incorrect */ @PostMapping("/login") - public Object login(@RequestParam String username, @RequestParam String password, - HttpServletResponse response, HttpServletRequest request) throws AccessException { - - + public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response, + HttpServletRequest request) throws AccessException { + if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { NacosUser user = (NacosUser) authManager.login(request); - - response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, - NacosAuthConfig.TOKEN_PREFIX + user.getToken()); - + + response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken()); + ObjectNode result = JacksonUtils.createEmptyJsonNode(); -// JSONObject result = new JSONObject(); + // JSONObject result = new JSONObject(); result.put(Constants.ACCESS_TOKEN, user.getToken()); result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds()); result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin()); return result; } - + // 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); - + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, + password); + RestResult rr = new RestResult(); try { //通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证 Authentication 对象 @@ -204,18 +213,25 @@ public class UserController { return rr; } } - + + /** + * Update password. + * + * @param oldPassword old password + * @param newPassword new password + * @return Code 200 if update successfully, Code 401 if old password invalid, otherwise 500 + */ @PutMapping("/password") @Deprecated public RestResult updatePassword(@RequestParam(value = "oldPassword") String oldPassword, - @RequestParam(value = "newPassword") String newPassword) { - + @RequestParam(value = "newPassword") String newPassword) { + RestResult rr = new RestResult(); Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); String username = ((UserDetails) principal).getUsername(); User user = userDetailsService.getUserFromDatabase(username); String password = user.getPassword(); - + // TODO: throw out more fine grained exceptions try { if (PasswordEncoderUtil.matches(oldPassword, password)) { diff --git a/console/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java b/console/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java index 4a8b86abc..7853593a7 100644 --- a/console/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java +++ b/console/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.exception; import com.alibaba.nacos.common.utils.ExceptionUtil; @@ -25,29 +26,29 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; /** - * Exception handler for console module + * Exception handler for console module. * * @author nkorange * @since 1.2.0 */ @ControllerAdvice public class ConsoleExceptionHandler { - - private static final Logger logger = LoggerFactory.getLogger(ConsoleExceptionHandler.class); - + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleExceptionHandler.class); + @ExceptionHandler(AccessException.class) private ResponseEntity handleAccessException(AccessException e) { return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg()); } - + @ExceptionHandler(IllegalArgumentException.class) private ResponseEntity handleIllegalArgumentException(IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionUtil.getAllExceptionMsg(e)); } - + @ExceptionHandler(Exception.class) private ResponseEntity handleException(Exception e) { - logger.error("CONSOLE", e); + LOGGER.error("CONSOLE", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ExceptionUtil.getAllExceptionMsg(e)); } } diff --git a/console/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java b/console/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java index e4ba2c547..4e8be4910 100644 --- a/console/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java +++ b/console/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.filter; import com.alibaba.nacos.api.common.Constants; @@ -30,26 +31,26 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** - * jwt auth token filter + * jwt auth token filter. * * @author wfnuser */ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { - + private static final String TOKEN_PREFIX = "Bearer "; - - private JwtTokenManager tokenManager; - + + private final JwtTokenManager tokenManager; + public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) { this.tokenManager = tokenManager; } - + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws IOException, ServletException { - + throws IOException, ServletException { + String jwt = resolveToken(request); - + if (StringUtils.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) { this.tokenManager.validateToken(jwt); Authentication authentication = this.tokenManager.getAuthentication(jwt); @@ -57,9 +58,9 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { } chain.doFilter(request, response); } - + /** - * Get token from header + * Get token from header. */ private String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER); diff --git a/console/src/main/java/com/alibaba/nacos/console/model/Namespace.java b/console/src/main/java/com/alibaba/nacos/console/model/Namespace.java index c617f10c0..326b3f513 100644 --- a/console/src/main/java/com/alibaba/nacos/console/model/Namespace.java +++ b/console/src/main/java/com/alibaba/nacos/console/model/Namespace.java @@ -13,51 +13,53 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.model; /** - * Namespace + * Namespace. * * @author diamond */ public class Namespace { - + private String namespace; - + private String namespaceShowName; - + private int quota; - + private int configCount; + /** - * 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace + * 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace. */ private int type; - + public String getNamespaceShowName() { return namespaceShowName; } - + public void setNamespaceShowName(String namespaceShowName) { this.namespaceShowName = namespaceShowName; } - + public String getNamespace() { return namespace; } - + public void setNamespace(String namespace) { this.namespace = namespace; } - + public Namespace() { } - + public Namespace(String namespace, String namespaceShowName) { this.namespace = namespace; this.namespaceShowName = namespaceShowName; } - + public Namespace(String namespace, String namespaceShowName, int quota, int configCount, int type) { this.namespace = namespace; this.namespaceShowName = namespaceShowName; @@ -65,29 +67,29 @@ public class Namespace { this.configCount = configCount; this.type = type; } - + public int getQuota() { return quota; } - + public void setQuota(int quota) { this.quota = quota; } - + public int getConfigCount() { return configCount; } - + public void setConfigCount(int configCount) { this.configCount = configCount; } - + public int getType() { return type; } - + public void setType(int type) { this.type = type; } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java b/console/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java index bbd63ce38..737326223 100644 --- a/console/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java +++ b/console/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java @@ -13,32 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.model; /** - * all namespace info + * all namespace info. * * @author Nacos */ public class NamespaceAllInfo extends Namespace { - + private String namespaceDesc; - + public String getNamespaceDesc() { return namespaceDesc; } - + public void setNamespaceDesc(String namespaceDesc) { this.namespaceDesc = namespaceDesc; } - + public NamespaceAllInfo() { } - + public NamespaceAllInfo(String namespace, String namespaceShowName, int quota, int configCount, int type, - String namespaceDesc) { + String namespaceDesc) { super(namespace, namespaceShowName, quota, configCount, type); this.namespaceDesc = namespaceDesc; } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java index c54db33f7..350561418 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.security.nacos; import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl; @@ -25,32 +26,32 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; /** - * auth provider + * auth provider. * * @author wfnuser */ @Component public class CustomAuthenticationProvider implements AuthenticationProvider { - + @Autowired private NacosUserDetailsServiceImpl userDetailsService; - + @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { - + String username = (String) authentication.getPrincipal(); String password = (String) authentication.getCredentials(); UserDetails userDetails = userDetailsService.loadUserByUsername(username); - + if (!password.equals(userDetails.getPassword())) { return new UsernamePasswordAuthenticationToken(username, null, null); } return null; } - + @Override public boolean supports(Class aClass) { return aClass.equals(UsernamePasswordAuthenticationToken.class); } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java index dad99758c..3866fb26e 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.security.nacos; import org.slf4j.Logger; @@ -27,20 +28,19 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** - * jwt auth fail point + * jwt auth fail point. * * @author wfnuser */ @Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { - - private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class); - + + private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class); + @Override - public void commence(HttpServletRequest request, - HttpServletResponse response, - AuthenticationException e) throws IOException, ServletException { - logger.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI()); + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) + throws IOException, ServletException { + LOGGER.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI()); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); } } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java index a07738f44..9d42a2a4c 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.security.nacos; import com.alibaba.nacos.core.auth.AuthConfigs; @@ -27,26 +28,25 @@ import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Component; -import java.util.Collection; import java.util.Date; import java.util.List; /** - * JWT token manager + * JWT token manager. * * @author wfnuser * @author nkorange */ @Component public class JwtTokenManager { - + private static final String AUTHORITIES_KEY = "auth"; - + @Autowired private AuthConfigs authConfigs; - + /** - * Create token + * Create token. * * @param authentication auth info * @return token @@ -54,49 +54,47 @@ public class JwtTokenManager { public String createToken(Authentication authentication) { return createToken(authentication.getName()); } - + + /** + * Create token. + * + * @param userName auth info + * @return token + */ public String createToken(String userName) { - + long now = System.currentTimeMillis(); - + Date validity; validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L); - + Claims claims = Jwts.claims().setSubject(userName); - - return Jwts.builder() - .setClaims(claims) - .setExpiration(validity) - .signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey()) - .compact(); + + return Jwts.builder().setClaims(claims).setExpiration(validity) + .signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey()).compact(); } - + /** - * Get auth Info + * Get auth Info. * * @param token token * @return auth info */ public Authentication getAuthentication(String token) { - /** - * parse the payload of token - */ - Claims claims = Jwts.parser() - .setSigningKey(authConfigs.getSecretKey()) - .parseClaimsJws(token) - .getBody(); - - List authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); + Claims claims = Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token).getBody(); + + List authorities = AuthorityUtils + .commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); + User principal = new User(claims.getSubject(), "", authorities); return new UsernamePasswordAuthenticationToken(principal, "", authorities); } - + /** - * validate token + * validate token. * * @param token token - * @return whether valid */ public void validateToken(String token) { Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token); diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java index 7e726f477..7956420b9 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.security.nacos; +package com.alibaba.nacos.console.security.nacos; import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter; import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl; @@ -23,7 +23,6 @@ import com.alibaba.nacos.core.auth.AuthSystemTypes; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.BeanIds; @@ -39,105 +38,93 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic import org.springframework.web.cors.CorsUtils; /** - * Spring security config + * Spring security config. * * @author Nacos */ @EnableGlobalMethodSecurity(prePostEnabled = true) public class NacosAuthConfig extends WebSecurityConfigurerAdapter { - + public static final String AUTHORIZATION_HEADER = "Authorization"; - + public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ","; - + public static final String LOGIN_ENTRY_POINT = "/v1/auth/login"; - + public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/v1/auth/**"; - + public static final String TOKEN_PREFIX = "Bearer "; - + public static final String CONSOLE_RESOURCE_NAME_PREFIX = "console/"; - + @Autowired private Environment env; - + @Autowired private JwtTokenManager tokenProvider; - + @Autowired private AuthConfigs authConfigs; - + @Autowired private NacosUserDetailsServiceImpl userDetailsService; - + @Bean(name = BeanIds.AUTHENTICATION_MANAGER) @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } - + @Override public void configure(WebSecurity web) { - - String ignoreURLs = null; -// + + String ignoreUrls = null; if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - ignoreURLs = "/**"; + ignoreUrls = "/**"; } -// if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { - ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**"); + ignoreUrls = env.getProperty("nacos.security.ignore.urls", "/**"); } - - if (StringUtils.isNotBlank(ignoreURLs)) { - for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) { - web.ignoring().antMatchers(ignoreURL.trim()); + if (StringUtils.isNotBlank(ignoreUrls)) { + for (String each : ignoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) { + web.ignoring().antMatchers(each.trim()); } } - } - + @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } - + @Override protected void configure(HttpSecurity http) throws Exception { - + if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { http - - .csrf().disable() - .cors() // We don't need CSRF for JWT based authentication - - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - - .and() - .authorizeRequests() - .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() - .antMatchers(LOGIN_ENTRY_POINT).permitAll() - - .and() - .authorizeRequests() - .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() - - .and() - .exceptionHandling() - .authenticationEntryPoint(new JwtAuthenticationEntryPoint()); - + + .csrf().disable().cors() // We don't need CSRF for JWT based authentication + + .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + + .and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll() + .antMatchers(LOGIN_ENTRY_POINT).permitAll() + + .and().authorizeRequests().antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() + + .and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint()); + // disable cache http.headers().cacheControl(); - - http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class); + + http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), + UsernamePasswordAuthenticationFilter.class); } } - + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } - + } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java index bd6d12293..d53ecb789 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.security.nacos; import com.alibaba.nacos.api.common.Constants; @@ -38,25 +39,25 @@ import javax.servlet.http.HttpServletRequest; import java.util.List; /** - * Builtin access control entry of Nacos + * Builtin access control entry of Nacos. * * @author nkorange * @since 1.2.0 */ @Component public class NacosAuthManager implements AuthManager { - + private static final String TOKEN_PREFIX = "Bearer "; - + @Autowired private JwtTokenManager tokenManager; - + @Autowired private AuthenticationManager authenticationManager; - + @Autowired private NacosRoleServiceImpl roleService; - + @Override public User login(Object request) throws AccessException { HttpServletRequest req = (HttpServletRequest) request; @@ -64,7 +65,7 @@ public class NacosAuthManager implements AuthManager { if (StringUtils.isBlank(token)) { throw new AccessException("user not found!"); } - + try { tokenManager.validateToken(token); } catch (ExpiredJwtException e) { @@ -72,10 +73,10 @@ public class NacosAuthManager implements AuthManager { } catch (Exception e) { throw new AccessException("token invalid!"); } - + Authentication authentication = tokenManager.getAuthentication(token); SecurityContextHolder.getContext().setAuthentication(authentication); - + String username = authentication.getName(); NacosUser user = new NacosUser(); user.setUserName(username); @@ -89,23 +90,23 @@ public class NacosAuthManager implements AuthManager { } } } - + return user; } - + @Override public void auth(Permission permission, User user) throws AccessException { if (Loggers.AUTH.isDebugEnabled()) { Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user); } - + if (!roleService.hasPermission(user.getUserName(), permission)) { throw new AccessException("authorization failed!"); } } - + /** - * Get token from header + * Get token from header. */ private String resolveToken(HttpServletRequest request) throws AccessException { String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER); @@ -118,19 +119,20 @@ public class NacosAuthManager implements AuthManager { String password = request.getParameter("password"); bearerToken = resolveTokenFromUser(userName, password); } - + return bearerToken; } - + private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException { - + try { - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, rawPassword); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, + rawPassword); authenticationManager.authenticate(authenticationToken); } catch (AuthenticationException e) { throw new AccessException("unknown user!"); } - + return tokenManager.createToken(userName); } } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java index 2ed542092..2d9b66aab 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.security.nacos.roles; +package com.alibaba.nacos.console.security.nacos.roles; import com.alibaba.nacos.config.server.auth.PermissionInfo; import com.alibaba.nacos.config.server.auth.PermissionPersistService; @@ -33,8 +33,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; @@ -46,31 +49,32 @@ import java.util.regex.Pattern; */ @Service public class NacosRoleServiceImpl { - + public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; - + @Autowired private AuthConfigs authConfigs; - + @Autowired private RolePersistService rolePersistService; - + @Autowired private NacosUserDetailsServiceImpl userDetailsService; - + @Autowired private PermissionPersistService permissionPersistService; - - private Set roleSet = new ConcurrentHashSet<>(); - - private Map> roleInfoMap = new ConcurrentHashMap<>(); - - private Map> permissionInfoMap = new ConcurrentHashMap<>(); - + + private final Set roleSet = new ConcurrentHashSet<>(); + + private final Map> roleInfoMap = new ConcurrentHashMap<>(); + + private final Map> permissionInfoMap = new ConcurrentHashMap<>(); + @Scheduled(initialDelay = 5000, fixedDelay = 15000) private void reload() { try { - Page roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, 1, Integer.MAX_VALUE); + Page roleInfoPage = rolePersistService + .getRolesByUserName(StringUtils.EMPTY, 1, Integer.MAX_VALUE); if (roleInfoPage == null) { return; } @@ -83,13 +87,14 @@ public class NacosRoleServiceImpl { tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo); tmpRoleSet.add(roleInfo.getRole()); } - + Map> tmpPermissionInfoMap = new ConcurrentHashMap<>(16); for (String role : tmpRoleSet) { - Page permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE); + Page permissionInfoPage = permissionPersistService + .getPermissions(role, 1, Integer.MAX_VALUE); tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems()); } - + roleSet.addAll(tmpRoleSet); roleInfoMap.putAll(tmpRoleInfoMap); permissionInfoMap.putAll(tmpPermissionInfoMap); @@ -97,36 +102,36 @@ public class NacosRoleServiceImpl { Loggers.AUTH.warn("[LOAD-ROLES] load failed", e); } } - + /** * Determine if the user has permission of the resource. - *

- * Note if the user has many roles, this method returns true if any one role of the user has the - * desired permission. + * + *

Note if the user has many roles, this method returns true if any one role of the user has the desired + * permission. * * @param username user info * @param permission permission to auth * @return true if granted, false otherwise */ public boolean hasPermission(String username, Permission permission) { - + List roleInfoList = getRoles(username); if (Collections.isEmpty(roleInfoList)) { return false; } - + // Global admin pass: for (RoleInfo roleInfo : roleInfoList) { if (GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) { return true; } } - + // Old global admin can pass resource 'console/': if (permission.getResource().startsWith(NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX)) { return false; } - + // For other roles, use a pattern match to decide if pass or not. for (RoleInfo roleInfo : roleInfoList) { List permissionInfoList = getPermissions(roleInfo.getRole()); @@ -136,15 +141,15 @@ public class NacosRoleServiceImpl { for (PermissionInfo permissionInfo : permissionInfoList) { String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*"); String permissionAction = permissionInfo.getAction(); - if (permissionAction.contains(permission.getAction()) && - Pattern.matches(permissionResource, permission.getResource())) { + if (permissionAction.contains(permission.getAction()) && Pattern + .matches(permissionResource, permission.getResource())) { return true; } } } return false; } - + public List getRoles(String username) { List roleInfoList = roleInfoMap.get(username); if (!authConfigs.isCachingEnabled()) { @@ -155,7 +160,7 @@ public class NacosRoleServiceImpl { } return roleInfoList; } - + public Page getRolesFromDatabase(String userName, int pageNo, int pageSize) { Page roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize); if (roles == null) { @@ -163,7 +168,7 @@ public class NacosRoleServiceImpl { } return roles; } - + public List getPermissions(String role) { List permissionInfoList = permissionInfoMap.get(role); if (!authConfigs.isCachingEnabled()) { @@ -174,11 +179,17 @@ public class NacosRoleServiceImpl { } return permissionInfoList; } - + public Page getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) { return permissionPersistService.getPermissions(role, pageNo, pageSize); } - + + /** + * Add role. + * + * @param role role name + * @param username user name + */ public void addRole(String role, String username) { if (userDetailsService.getUserFromDatabase(username) == null) { throw new IllegalArgumentException("user '" + username + "' not found!"); @@ -189,16 +200,16 @@ public class NacosRoleServiceImpl { rolePersistService.addRole(role, username); roleSet.add(role); } - + public void deleteRole(String role, String userName) { rolePersistService.deleteRole(role, userName); } - + public void deleteRole(String role) { rolePersistService.deleteRole(role); roleSet.remove(role); } - + public Page getPermissionsFromDatabase(String role, int pageNo, int pageSize) { Page pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize); if (pageInfo == null) { @@ -206,14 +217,21 @@ public class NacosRoleServiceImpl { } return pageInfo; } - + + /** + * Add permission. + * + * @param role role name + * @param resource resource + * @param action action + */ public void addPermission(String role, String resource, String action) { if (!roleSet.contains(role)) { throw new IllegalArgumentException("role " + role + " not found!"); } permissionPersistService.addPermission(role, resource, action); } - + public void deletePermission(String role, String resource, String action) { permissionPersistService.deletePermission(role, resource, action); } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java index f3dfa0f73..d0aaf196b 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java @@ -19,36 +19,35 @@ package com.alibaba.nacos.console.security.nacos.users; import com.alibaba.nacos.core.auth.User; /** + * Nacos User. + * * @author nkorange * @since 1.2.0 */ public class NacosUser extends User { - + private String token; - + private boolean globalAdmin = false; - + public String getToken() { return token; } - + public void setToken(String token) { this.token = token; } - + public boolean isGlobalAdmin() { return globalAdmin; } - + public void setGlobalAdmin(boolean globalAdmin) { this.globalAdmin = globalAdmin; } - + @Override public String toString() { - return "NacosUser{" + - "token='" + token + '\'' + - ", globalAdmin=" + globalAdmin + - '}'; + return "NacosUser{" + "token='" + token + '\'' + ", globalAdmin=" + globalAdmin + '}'; } } diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java index 3390a2ce2..553dbf1e3 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.security.nacos.users; import com.alibaba.nacos.config.server.model.User; @@ -23,49 +24,49 @@ import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; /** - * custem user + * custom user. * * @author wfnuser */ public class NacosUserDetails implements UserDetails { - - private User user; - + + private final User user; + public NacosUserDetails(User user) { this.user = user; } - + @Override public Collection getAuthorities() { // TODO: get authorities return AuthorityUtils.commaSeparatedStringToAuthorityList(""); } - + @Override public String getPassword() { return user.getPassword(); } - + @Override public String getUsername() { return user.getUsername(); } - + @Override public boolean isAccountNonExpired() { return true; } - + @Override public boolean isAccountNonLocked() { return true; } - + @Override public boolean isCredentialsNonExpired() { return true; } - + @Override public boolean isEnabled() { return true; diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java index 02bafdb90..a87f7cb59 100644 --- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java +++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.console.security.nacos.users; +package com.alibaba.nacos.console.security.nacos.users; import com.alibaba.nacos.config.server.auth.UserPersistService; import com.alibaba.nacos.config.server.model.Page; @@ -28,27 +28,26 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** - * Custem user service + * Custem user service. * * @author wfnuser * @author nkorange */ @Service public class NacosUserDetailsServiceImpl implements UserDetailsService { - + private Map userMap = new ConcurrentHashMap<>(); - + @Autowired private UserPersistService userPersistService; - + @Autowired private AuthConfigs authConfigs; - + @Scheduled(initialDelay = 5000, fixedDelay = 15000) private void reload() { try { @@ -56,7 +55,7 @@ public class NacosUserDetailsServiceImpl implements UserDetailsService { if (users == null) { return; } - + Map map = new ConcurrentHashMap<>(16); for (User user : users.getPageItems()) { map.put(user.getUsername(), user); @@ -66,29 +65,29 @@ public class NacosUserDetailsServiceImpl implements UserDetailsService { Loggers.AUTH.warn("[LOAD-USERS] load failed", e); } } - + @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - + User user = userMap.get(username); if (!authConfigs.isCachingEnabled()) { user = userPersistService.findUserByUsername(username); } - + if (user == null) { throw new UsernameNotFoundException(username); } return new NacosUserDetails(user); } - + public void updateUserPassword(String username, String password) { userPersistService.updateUserPassword(username, password); } - + public Page getUsersFromDatabase(int pageNo, int pageSize) { return userPersistService.getUsers(pageNo, pageSize); } - + public User getUser(String username) { User user = userMap.get(username); if (!authConfigs.isCachingEnabled()) { @@ -96,15 +95,15 @@ public class NacosUserDetailsServiceImpl implements UserDetailsService { } return user; } - + public User getUserFromDatabase(String username) { return userPersistService.findUserByUsername(username); } - + public void createUser(String username, String password) { userPersistService.createUser(username, password); } - + public void deleteUser(String username) { userPersistService.deleteUser(username); } diff --git a/console/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java b/console/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java index 967a45fd9..6096f135d 100644 --- a/console/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java +++ b/console/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java @@ -13,9 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.utils; -import io.jsonwebtoken.*; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.SignatureException; +import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,43 +41,46 @@ import java.util.List; /** - * Jwt token tool + * Jwt token tool. * * @author wfnuser */ @Component public class JwtTokenUtils { - + private final Logger log = LoggerFactory.getLogger(JwtTokenUtils.class); - + private static final String AUTHORITIES_KEY = "auth"; - + /** - * minimum SHA_256 secretKey string length + * minimum SHA_256 secretKey string length. */ private static final int SHA_256_SECRET_CHAR_SIZE = 256 / 8; - + /** - * default SHA_256 secretKey flag + * default SHA_256 secretKey flag. */ private static final String DEFAULT_SECRET_FLAG = "default"; - + /** - * custom SHA_256 secretKey from config property + * custom SHA_256 secretKey from config property. */ @Value("${nacos.security.token.secret-key:default}") private String customSecretKeyStr; - + /** - * secret key + * secret key. */ private SecretKey secretKey; - + /** - * Token validity time(ms) + * Token validity time(ms). */ private long tokenValidityInMilliseconds; - + + /** + * Init. + */ @PostConstruct public void init() { //use default secretKey for SHA-256 @@ -83,69 +93,52 @@ public class JwtTokenUtils { if (left > 0) { //character for padding StringBuilder stringBuilder = new StringBuilder(customSecretKeyStr); - for (int i = 0 ;i < left ; i ++){ - stringBuilder.append(i%10); + for (int i = 0; i < left; i++) { + stringBuilder.append(i % 10); } this.secretKey = Keys.hmacShaKeyFor(stringBuilder.toString().getBytes()); - }else { + } else { this.secretKey = Keys.hmacShaKeyFor(customSecretKeyStr.getBytes()); } } this.tokenValidityInMilliseconds = 1000 * 60 * 30L; } - + /** - * Create token + * Create token. * * @param authentication auth info * @return token */ public String createToken(Authentication authentication) { - /** - * Current time - */ + long now = System.currentTimeMillis(); - /** - * Validity date - */ - Date validity; - validity = new Date(now + this.tokenValidityInMilliseconds); - /** - * create token - */ - return Jwts.builder() - .setSubject(authentication.getName()) - .claim(AUTHORITIES_KEY, "") - .setExpiration(validity) - .signWith(secretKey, SignatureAlgorithm.HS256) - .compact(); + Date validity = new Date(now + this.tokenValidityInMilliseconds); + + return Jwts.builder().setSubject(authentication.getName()).claim(AUTHORITIES_KEY, "").setExpiration(validity) + .signWith(secretKey, SignatureAlgorithm.HS256).compact(); } - + /** - * Get auth Info + * Get auth Info. * * @param token token * @return auth info */ public Authentication getAuthentication(String token) { - /** - * parse the payload of token - */ - Claims claims = Jwts.parser() - .setSigningKey(secretKey) - .parseClaimsJws(token) - .getBody(); - - List authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); - + Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody(); + + List authorities = AuthorityUtils + .commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); + User principal = new User(claims.getSubject(), "", authorities); return new UsernamePasswordAuthenticationToken(principal, "", authorities); } - + /** - * validate token + * validate token. * * @param token token * @return whether valid diff --git a/console/src/main/java/com/alibaba/nacos/console/utils/PasswordEncoderUtil.java b/console/src/main/java/com/alibaba/nacos/console/utils/PasswordEncoderUtil.java index 67585d024..a55a27027 100644 --- a/console/src/main/java/com/alibaba/nacos/console/utils/PasswordEncoderUtil.java +++ b/console/src/main/java/com/alibaba/nacos/console/utils/PasswordEncoderUtil.java @@ -13,25 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.utils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** - * Password encoder tool + * Password encoder tool. * * @author nacos */ public class PasswordEncoderUtil { - + public static void main(String[] args) { System.out.println(new BCryptPasswordEncoder().encode("nacos")); } - + public static Boolean matches(String raw, String encoded) { return new BCryptPasswordEncoder().matches(raw, encoded); } - + public static String encode(String raw) { return new BCryptPasswordEncoder().encode(raw); } diff --git a/console/src/test/java/com/alibaba/nacos/console/controller/HealthControllerTest.java b/console/src/test/java/com/alibaba/nacos/console/controller/HealthControllerTest.java index 82cf7e4fe..c9dfbbba1 100644 --- a/console/src/test/java/com/alibaba/nacos/console/controller/HealthControllerTest.java +++ b/console/src/test/java/com/alibaba/nacos/console/controller/HealthControllerTest.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.console.controller; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.naming.controllers.OperatorController; - import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -40,68 +40,65 @@ import javax.servlet.http.HttpServletRequest; import static org.mockito.ArgumentMatchers.any; -/** - * @author hxy1991 - */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class HealthControllerTest { - + @InjectMocks private HealthController healthController; - + @Mock private PersistService persistService; - + @Mock private OperatorController apiCommands; - + private MockMvc mockmvc; - + @Before public void setUp() { mockmvc = MockMvcBuilders.standaloneSetup(healthController).build(); } - + @Test public void testLiveness() throws Exception { String url = "/v1/console/health/liveness"; MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(url); Assert.assertEquals(200, mockmvc.perform(builder).andReturn().getResponse().getStatus()); } - + @Test public void testReadiness() throws Exception { String url = "/v1/console/health/readiness"; - + Mockito.when(persistService.configInfoCount(any(String.class))).thenReturn(0); Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenReturn(JacksonUtils.createEmptyJsonNode()); MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(url); Assert.assertEquals(200, mockmvc.perform(builder).andReturn().getResponse().getStatus()); - + // Config and Naming are not in readiness - Mockito.when(persistService.configInfoCount(any(String.class))).thenThrow( - new RuntimeException("HealthControllerTest.testReadiness")); - Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenThrow( - new RuntimeException("HealthControllerTest.testReadiness")); + Mockito.when(persistService.configInfoCount(any(String.class))) + .thenThrow(new RuntimeException("HealthControllerTest.testReadiness")); + Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))) + .thenThrow(new RuntimeException("HealthControllerTest.testReadiness")); builder = MockMvcRequestBuilders.get(url); MockHttpServletResponse response = mockmvc.perform(builder).andReturn().getResponse(); Assert.assertEquals(500, response.getStatus()); Assert.assertEquals("Config and Naming are not in readiness", response.getContentAsString()); - + // Config is not in readiness - Mockito.when(persistService.configInfoCount(any(String.class))).thenThrow( - new RuntimeException("HealthControllerTest.testReadiness")); + Mockito.when(persistService.configInfoCount(any(String.class))) + .thenThrow(new RuntimeException("HealthControllerTest.testReadiness")); Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenReturn(JacksonUtils.createEmptyJsonNode()); response = mockmvc.perform(builder).andReturn().getResponse(); Assert.assertEquals(500, response.getStatus()); Assert.assertEquals("Config is not in readiness", response.getContentAsString()); - + // Naming is not in readiness Mockito.when(persistService.configInfoCount(any(String.class))).thenReturn(0); - Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenThrow( - new RuntimeException("HealthControllerTest.testReadiness")); + Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))) + .thenThrow(new RuntimeException("HealthControllerTest.testReadiness")); builder = MockMvcRequestBuilders.get(url); response = mockmvc.perform(builder).andReturn().getResponse(); Assert.assertEquals(500, response.getStatus()); diff --git a/console/src/test/java/com/alibaba/nacos/console/controller/UserControllerTest.java b/console/src/test/java/com/alibaba/nacos/console/controller/UserControllerTest.java index e2f208769..0588372b2 100644 --- a/console/src/test/java/com/alibaba/nacos/console/controller/UserControllerTest.java +++ b/console/src/test/java/com/alibaba/nacos/console/controller/UserControllerTest.java @@ -22,39 +22,40 @@ import com.alibaba.nacos.core.auth.AccessException; import com.alibaba.nacos.core.auth.AuthConfigs; import com.alibaba.nacos.core.auth.AuthSystemTypes; import com.fasterxml.jackson.databind.JsonNode; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import java.lang.reflect.Field; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Field; import static org.hamcrest.CoreMatchers.instanceOf; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class UserControllerTest { - + @Mock private HttpServletRequest request; - + @Mock private HttpServletResponse response; - + @Mock private AuthConfigs authConfigs; - + @Mock private NacosAuthManager authManager; - + private UserController userController; - + private NacosUser user; - + @Before public void setUp() throws Exception { userController = new UserController(); @@ -65,7 +66,7 @@ public class UserControllerTest { injectObject("authConfigs", authConfigs); injectObject("authManager", authManager); } - + @Test public void testLoginWithAuthedUser() throws AccessException { when(authManager.login(request)).thenReturn(user); @@ -78,7 +79,7 @@ public class UserControllerTest { assertTrue(actualString.contains("\"tokenTtl\":18000")); assertTrue(actualString.contains("\"globalAdmin\":true")); } - + private void injectObject(String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { Field field = UserController.class.getDeclaredField(fieldName); field.setAccessible(true);