diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/CollectionUtil.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/CollectionUtil.java index 8d66b126d..21ca16efb 100644 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/CollectionUtil.java +++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/CollectionUtil.java @@ -28,12 +28,17 @@ public class CollectionUtil { return from.stream().map(func).collect(Collectors.toSet()); } + public static Map convertMap(List from, Function keyFunc) { + return from.stream().collect(Collectors.toMap(keyFunc, item -> item)); + } + public static Map convertMap(List from, Function keyFunc, Function valueFunc) { return from.stream().collect(Collectors.toMap(keyFunc, valueFunc)); } - public static Map convertMap(List from, Function keyFunc) { - return from.stream().collect(Collectors.toMap(keyFunc, item -> item)); + public static Map> convertMultiMap(List from, Function keyFunc, Function valueFunc) { + return from.stream().collect(Collectors.groupingBy(keyFunc, + Collectors.mapping(valueFunc, Collectors.toList()))); } public static boolean containsAny(Collection source, Collection candidates) { diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/config/CommonSecurityAutoConfiguration.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/config/CommonSecurityAutoConfiguration.java index de29f0046..57646d6d9 100644 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/config/CommonSecurityAutoConfiguration.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/config/CommonSecurityAutoConfiguration.java @@ -1,6 +1,9 @@ package cn.iocoder.mall.security.config; import cn.iocoder.mall.security.core.interceptor.AccountAuthInterceptor; +import cn.iocoder.mall.security.core.interceptor.AdminDemoInterceptor; +import cn.iocoder.mall.security.core.interceptor.AdminSecurityInterceptor; +import cn.iocoder.mall.security.core.interceptor.UserSecurityInterceptor; import cn.iocoder.mall.web.config.CommonWebAutoConfiguration; import cn.iocoder.mall.web.core.constant.CommonMallConstants; import org.slf4j.Logger; @@ -30,6 +33,21 @@ public class CommonSecurityAutoConfiguration implements WebMvcConfigurer { return new AccountAuthInterceptor(false); } + @Bean + public AdminSecurityInterceptor adminSecurityInterceptor() { + return new AdminSecurityInterceptor(); + } + + @Bean + public UserSecurityInterceptor userSecurityInterceptor() { + return new UserSecurityInterceptor(); + } + + @Bean + public AdminDemoInterceptor adminDemoInterceptor() { + return new AdminDemoInterceptor(); + } + @Override public void addInterceptors(InterceptorRegistry registry) { // AccountAuthInterceptor 拦截器 @@ -38,6 +56,18 @@ public class CommonSecurityAutoConfiguration implements WebMvcConfigurer { registry.addInterceptor(this.adminAccountAuthInterceptor()) .addPathPatterns(CommonMallConstants.ROOT_PATH_ADMIN + "/**"); logger.info("[addInterceptors][加载 AccountAuthInterceptor 拦截器完成]"); + // AdminSecurityInterceptor 拦截器 + registry.addInterceptor(this.adminSecurityInterceptor()) + .addPathPatterns(CommonMallConstants.ROOT_PATH_ADMIN + "/**"); + logger.info("[addInterceptors][加载 AdminSecurityInterceptor 拦截器完成]"); + // UserSecurityInterceptor 拦截器 + registry.addInterceptor(this.userAccountAuthInterceptor()) + .addPathPatterns(CommonMallConstants.ROOT_PATH_USER + "/**"); + logger.info("[addInterceptors][加载 UserSecurityInterceptor 拦截器完成]"); + // AdminDemoInterceptor 拦截器 + registry.addInterceptor(this.adminDemoInterceptor()) + .addPathPatterns(CommonMallConstants.ROOT_PATH_ADMIN + "/**"); + logger.info("[addInterceptors][加载 AdminDemoInterceptor 拦截器完成]"); } } diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/annotation/RequiresPermissions.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/annotation/RequiresPermissions.java index 561c54a0c..b40ced91a 100644 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/annotation/RequiresPermissions.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/annotation/RequiresPermissions.java @@ -19,6 +19,6 @@ public @interface RequiresPermissions { * * @return 权限标识数组 */ - String[] value(); + String[] value() default {}; } diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/context/AdminSecurityContext.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/context/AdminSecurityContext.java index 253d1ebf2..20bf3e5a1 100644 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/context/AdminSecurityContext.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/context/AdminSecurityContext.java @@ -14,9 +14,5 @@ public class AdminSecurityContext { * 管理员编号 */ private Integer adminId; - /** - * 管理员账号 - */ - private String username; } diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AccountAuthInterceptor.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AccountAuthInterceptor.java index 7c88b6405..b814b6ec2 100644 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AccountAuthInterceptor.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AccountAuthInterceptor.java @@ -8,7 +8,9 @@ import cn.iocoder.mall.security.core.annotation.RequiresAuthenticate; import cn.iocoder.mall.security.core.annotation.RequiresNone; import cn.iocoder.mall.security.core.annotation.RequiresPermissions; import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum; +import cn.iocoder.mall.system.rpc.api.authorization.AuthorizationRPC; import cn.iocoder.mall.system.rpc.api.oauth2.OAuth2RPC; +import cn.iocoder.mall.system.rpc.request.authorization.AuthorizationCheckPermissionsRequest; import cn.iocoder.mall.system.rpc.request.oauth2.OAuth2AccessTokenAuthenticateRequest; import cn.iocoder.mall.system.rpc.response.oauth2.OAuth2AccessTokenResponse; import cn.iocoder.mall.web.core.util.CommonWebUtil; @@ -21,6 +23,7 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; public class AccountAuthInterceptor extends HandlerInterceptorAdapter { @@ -28,7 +31,8 @@ public class AccountAuthInterceptor extends HandlerInterceptorAdapter { @Reference(validation = "true", version = "${dubbo.consumer.OAuth2RPC.version}") private OAuth2RPC oauth2RPC; - + @Reference(validation = "true", version = "${dubbo.consumer.AuthorizationRPC.version}") + private AuthorizationRPC authorizationRPC; /** * 是否默认要求认证 @@ -51,7 +55,7 @@ public class AccountAuthInterceptor extends HandlerInterceptorAdapter { // 判断是否需要认证 this.checkAuthenticate(handlerMethod, accountId); // 判断是否需要权限 - + this.checkPermission(handlerMethod, accountId); return true; } @@ -63,12 +67,12 @@ public class AccountAuthInterceptor extends HandlerInterceptorAdapter { // 执行认证 OAuth2AccessTokenAuthenticateRequest oauth2AccessTokenAuthenticateRequest = new OAuth2AccessTokenAuthenticateRequest() .setAccessToken(accessToken).setIp(HttpUtil.getIp(request)); - CommonResult oauth2AccessTokenResponseResult = oauth2RPC.authenticate(oauth2AccessTokenAuthenticateRequest); - if (oauth2AccessTokenResponseResult.isError()) { // TODO 有一个问题点,假设 token 认证失败,但是该 url 是无需认证的,是不是一样能够执行过去? - throw ServiceExceptionUtil.exception(oauth2AccessTokenResponseResult); + CommonResult oauth2AccessTokenResult = oauth2RPC.authenticate(oauth2AccessTokenAuthenticateRequest); + if (oauth2AccessTokenResult.isError()) { // TODO 有一个问题点,假设 token 认证失败,但是该 url 是无需认证的,是不是一样能够执行过去? + throw ServiceExceptionUtil.exception(oauth2AccessTokenResult); } // 设置账号编号 - Integer accountId = oauth2AccessTokenResponseResult.getData().getAccountId(); + Integer accountId = oauth2AccessTokenResult.getData().getAccountId(); CommonWebUtil.setAccountId(request, accountId); return accountId; } @@ -96,7 +100,12 @@ public class AccountAuthInterceptor extends HandlerInterceptorAdapter { return; } // 权限验证 - + AuthorizationCheckPermissionsRequest authorizationCheckPermissionsRequest = new AuthorizationCheckPermissionsRequest() + .setAccountId(accountId).setPermissions(Arrays.asList(permissions)); + CommonResult authorizationCheckPermissionsResult = authorizationRPC.checkPermissions(authorizationCheckPermissionsRequest); + if (authorizationCheckPermissionsResult.isError()) { // TODO 有一个问题点,假设 token 认证失败,但是该 url 是无需认证的,是不是一样能够执行过去? + throw ServiceExceptionUtil.exception(authorizationCheckPermissionsResult); + } } } diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/interceptor/AdminDemoInterceptor.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminDemoInterceptor.java similarity index 61% rename from system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/interceptor/AdminDemoInterceptor.java rename to common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminDemoInterceptor.java index e605f42b3..0bda7d9d3 100644 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/interceptor/AdminDemoInterceptor.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminDemoInterceptor.java @@ -1,29 +1,28 @@ -package cn.iocoder.mall.system.sdk.interceptor; +package cn.iocoder.mall.security.core.interceptor; import cn.iocoder.common.framework.util.ServiceExceptionUtil; -import cn.iocoder.mall.system.api.constant.AdminConstants; -import cn.iocoder.mall.system.api.constant.AdminErrorCodeEnum; -import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder; +import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder; +import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum; import org.springframework.http.HttpMethod; -import org.springframework.stereotype.Component; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Objects; /** * Admin 演示拦截器 * * 这是个比较“奇怪”的拦截器,用于演示的管理员账号,禁止使用 POST 请求,从而实现即达到阉割版的演示的效果,又避免影响了数据 */ -@Component public class AdminDemoInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - if (AdminConstants.USERNAME_DEMO.equals(AdminSecurityContextHolder.getContext().getUsername()) + // 当 Admin 编号等于 0 时,约定为演示账号 + if (Objects.equals(AdminSecurityContextHolder.getContext().getAdminId(), 0) && request.getMethod().equalsIgnoreCase(HttpMethod.POST.toString())) { - throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_DEMO_CAN_NOT_WRITE.getCode()); + throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.AUTHORIZATION_DEMO_PERMISSION_DENY.getCode()); } return true; } diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminSecurityInterceptor.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminSecurityInterceptor.java index fb68b48fd..b48e87441 100644 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminSecurityInterceptor.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/AdminSecurityInterceptor.java @@ -1,5 +1,12 @@ package cn.iocoder.mall.security.core.interceptor; +import cn.iocoder.common.framework.util.ServiceExceptionUtil; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.security.core.context.AdminSecurityContext; +import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder; +import cn.iocoder.mall.system.rpc.api.admin.AdminRPC; +import cn.iocoder.mall.system.rpc.response.admin.AdminResponse; +import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; @@ -7,16 +14,30 @@ import javax.servlet.http.HttpServletResponse; public class AdminSecurityInterceptor extends HandlerInterceptorAdapter { - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 获得 Admin 信息 + @Reference(validation = "true", version = "${dubbo.consumer.AdminRPC.version}") + private AdminRPC adminRPC; + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + Integer accountId = AdminSecurityContextHolder.getContext().getAdminId(); + if (accountId != null) { + // 获得 Admin 信息 + CommonResult adminResult = adminRPC.getAdminByAccountId(accountId); + if (adminResult.isError()) { + throw ServiceExceptionUtil.exception(adminResult); + } + // 设置到 SecurityContext 中 + AdminResponse adminResponse = adminResult.getData(); + AdminSecurityContext context = new AdminSecurityContext().setAdminId(adminResponse.getId()); + AdminSecurityContextHolder.setContext(context); + } return true; } @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + // 清空 SecurityContext + AdminSecurityContextHolder.clear(); } } diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/UserSecurityInterceptor.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/UserSecurityInterceptor.java index 4f0cd5084..336481fed 100644 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/UserSecurityInterceptor.java +++ b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/interceptor/UserSecurityInterceptor.java @@ -1,5 +1,13 @@ package cn.iocoder.mall.security.core.interceptor; +import cn.iocoder.common.framework.util.ServiceExceptionUtil; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder; +import cn.iocoder.mall.security.core.context.UserSecurityContext; +import cn.iocoder.mall.security.core.context.UserSecurityContextHolder; +import cn.iocoder.mall.system.rpc.api.user.UserRPC; +import cn.iocoder.mall.system.rpc.response.user.UserResponse; +import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; @@ -7,15 +15,30 @@ import javax.servlet.http.HttpServletResponse; public class UserSecurityInterceptor extends HandlerInterceptorAdapter { + @Reference(validation = "true", version = "${dubbo.consumer.UserRPC.version}") + private UserRPC userRPC; + @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 获得用户信息 + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + Integer accountId = AdminSecurityContextHolder.getContext().getAdminId(); + if (accountId != null) { + // 获得 Admin 信息 + CommonResult userResult = userRPC.getUserByAccountId(accountId); + if (userResult.isError()) { + throw ServiceExceptionUtil.exception(userResult); + } + // 设置到 SecurityContext 中 + UserResponse userResponse = userResult.getData(); + UserSecurityContext context = new UserSecurityContext().setUserId(userResponse.getId()); + UserSecurityContextHolder.setContext(context); + } return true; } @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - super.afterCompletion(request, response, handler, ex); + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + // 清空 SecurityContext + UserSecurityContextHolder.clear(); } } diff --git a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/package-info.java b/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/package-info.java deleted file mode 100644 index bcd1a1f87..000000000 --- a/common/mall-spring-boot-starter-security/src/main/java/cn/iocoder/mall/security/core/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.security.core; diff --git a/common/mall-spring-boot/pom.xml b/common/mall-spring-boot/pom.xml index 41809e871..8d36246d0 100644 --- a/common/mall-spring-boot/pom.xml +++ b/common/mall-spring-boot/pom.xml @@ -18,18 +18,6 @@ common-framework 1.0-SNAPSHOT - - cn.iocoder.mall - system-sdk - 1.0-SNAPSHOT - true - - - cn.iocoder.mall - user-sdk - 1.0-SNAPSHOT - true - @@ -49,17 +37,6 @@ true - - io.springfox - springfox-swagger2 - true - - - com.github.xiaoymin - swagger-bootstrap-ui - true - - org.springframework.boot diff --git a/common/mall-spring-boot/src/main/java/cn/iocoder/mall/spring/boot/web/AdminMVCAutoConfiguration.java b/common/mall-spring-boot/src/main/java/cn/iocoder/mall/spring/boot/web/AdminMVCAutoConfiguration.java deleted file mode 100644 index 6a7f74f6d..000000000 --- a/common/mall-spring-boot/src/main/java/cn/iocoder/mall/spring/boot/web/AdminMVCAutoConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.mall.spring.boot.web; - -import cn.iocoder.common.framework.constant.MallConstants; -import cn.iocoder.common.framework.servlet.CorsFilter; -import cn.iocoder.mall.system.sdk.interceptor.AdminDemoInterceptor; -import cn.iocoder.mall.spring.boot.web.interceptor.AccessLogInterceptor; -import cn.iocoder.mall.system.sdk.interceptor.AdminSecurityInterceptor; -import cn.iocoder.mall.spring.boot.web.handler.GlobalExceptionHandler; -import cn.iocoder.mall.spring.boot.web.handler.GlobalResponseBodyHandler; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) // TODO 芋艿,未来可能考虑 REACTIVE -@ConditionalOnClass({ - DispatcherServlet.class, - WebMvcConfigurer.class, // 有 Spring MVC 容器 - AdminSecurityInterceptor.class, - AccessLogInterceptor.class -}) // 有引入 system-sdk -public class AdminMVCAutoConfiguration implements WebMvcConfigurer { - - @Bean - @ConditionalOnMissingBean(AdminSecurityInterceptor.class) - public AdminSecurityInterceptor adminSecurityInterceptor() { - return new AdminSecurityInterceptor(); - } - - @Bean - @ConditionalOnMissingBean(AdminDemoInterceptor.class) - public AdminDemoInterceptor adminDemoInterceptor() { - return new AdminDemoInterceptor(); - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(adminAccessLogInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_ADMIN + "/**"); - registry.addInterceptor(adminSecurityInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_ADMIN + "/**"); - registry.addInterceptor(adminDemoInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_ADMIN + "/**"); - } - -} diff --git a/common/mall-spring-boot/src/main/java/cn/iocoder/mall/spring/boot/web/UserMVCAutoConfiguration.java b/common/mall-spring-boot/src/main/java/cn/iocoder/mall/spring/boot/web/UserMVCAutoConfiguration.java deleted file mode 100644 index 74ca07987..000000000 --- a/common/mall-spring-boot/src/main/java/cn/iocoder/mall/spring/boot/web/UserMVCAutoConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -package cn.iocoder.mall.spring.boot.web; - -import cn.iocoder.common.framework.constant.MallConstants; -import cn.iocoder.common.framework.servlet.CorsFilter; -import cn.iocoder.mall.spring.boot.web.interceptor.AccessLogInterceptor; -import cn.iocoder.mall.spring.boot.web.handler.GlobalExceptionHandler; -import cn.iocoder.mall.spring.boot.web.handler.GlobalResponseBodyHandler; -import cn.iocoder.mall.user.sdk.interceptor.UserSecurityInterceptor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) // TODO 芋艿,未来可能考虑 REACTIVE -@ConditionalOnClass({DispatcherServlet.class, WebMvcConfigurer.class, // 有 Spring MVC 容器 - UserSecurityInterceptor.class, // 有引入 user-sdk - AccessLogInterceptor.class}) // 有引入 system-sdk -public class UserMVCAutoConfiguration implements WebMvcConfigurer { - - @Bean -// @ConditionalOnMissingBean(AccessLogInterceptor.class) - public AccessLogInterceptor userAccessLogInterceptor() { - return new AccessLogInterceptor(); - } - - @Bean - @ConditionalOnMissingBean(UserSecurityInterceptor.class) - public UserSecurityInterceptor userSecurityInterceptor() { - return new UserSecurityInterceptor(); - } - - @Bean - @ConditionalOnMissingBean(GlobalResponseBodyHandler.class) - public GlobalResponseBodyHandler globalReturnValueHandler() { - return new GlobalResponseBodyHandler(); - } - - @Bean - @ConditionalOnMissingBean(GlobalExceptionHandler.class) - public GlobalExceptionHandler globalExceptionHandler() { - return new GlobalExceptionHandler(); - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(userAccessLogInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_USER + "/**"); - registry.addInterceptor(userSecurityInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_USER + "/**"); - } - - - -} diff --git a/common/mall-spring-boot/src/main/resources/META-INF/spring.factories b/common/mall-spring-boot/src/main/resources/META-INF/spring.factories index 2c1124717..c2211a8c9 100644 --- a/common/mall-spring-boot/src/main/resources/META-INF/spring.factories +++ b/common/mall-spring-boot/src/main/resources/META-INF/spring.factories @@ -1,4 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cn.iocoder.mall.spring.boot.web.AdminMVCAutoConfiguration, \ - cn.iocoder.mall.spring.boot.web.UserMVCAutoConfiguration, \ cn.iocoder.mall.spring.boot.metrics.MetricsAutoConfiguration diff --git a/system/pom.xml b/system/pom.xml index a0746feff..35db93bc9 100644 --- a/system/pom.xml +++ b/system/pom.xml @@ -15,7 +15,7 @@ system-application - system-sdk + system-rpc-api diff --git a/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java b/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java index ab06bada6..07827ac86 100644 --- a/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java +++ b/system/system-biz-api/src/main/java/cn/iocoder/mall/system/biz/enums/SystemErrorCodeEnum.java @@ -38,9 +38,7 @@ public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable { // ADMIN_DELETE_ONLY_DISABLE(1002002004, "只有关闭的账号才可以删除"), // ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE(1002002005, "管理员的账号状态不允许变更"), // ADMIN_ASSIGN_ROLE_NOT_EXISTS(1002002006, "分配员工角色时,有角色不存在"), -// ADMIN_INVALID_PERMISSION(1002002007, "没有该操作权限"), // ADMIN_ADMIN_CAN_NOT_UPDATE(1002002008, "管理员的账号不允许变更"), -// ADMIN_DEMO_CAN_NOT_WRITE(1002002009, "演示账号,暂不允许写操作。欢迎加入我们的交流群:http://t.cn/EKEr5WE"), // ========== 资源模块 1002003000 ========== // RESOURCE_NAME_DUPLICATE(1002003000, "已经存在该名字的资源"), @@ -72,8 +70,15 @@ public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable { // DEPT_NOT_EXITS(1002007003, "当前部门不存在"), // DEPT_EXITS_CHILDREN(1002007004, "当前部门存在子部门"), // DEPT_PARENT_NOT_LEGAL(1002007005, "父级部门不合法"), + + + // ========== 授权模块 1002008000 ========== + AUTHORIZATION_PERMISSION_DENY(1002008001, "没有该操作权限"), + AUTHORIZATION_DEMO_PERMISSION_DENY(1002008002, "演示账号,暂不允许写操作。欢迎加入我们的交流群:http://t.cn/EKEr5WE"), + ; + private final int code; private final String message; diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/authorization/ResourceBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/authorization/ResourceBO.java new file mode 100644 index 000000000..1031448ae --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/authorization/ResourceBO.java @@ -0,0 +1,52 @@ +package cn.iocoder.mall.system.biz.bo.authorization; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 授权模块 - 资源信息 BO + */ +@Data +@Accessors(chain = true) +public class ResourceBO { + + /** + * 资源编号 + */ + private Integer id; + /** + * 菜单名 + */ + private String name; + /** + * 权限标识 + */ + private String permission; + /** + * 资源类型 + */ + private Integer type; + /** + * 排序 + */ + private Integer sort; + /** + * 父级资源编号 + */ + private Integer pid; + /** + * 前端路由 + */ + private String route; + /** + * 菜单图标 + */ + private String icon; + /** + * 创建时间 + */ + private Date createTime; + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/authorization/RoleBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/authorization/RoleBO.java new file mode 100644 index 000000000..9d4b3cb69 --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/authorization/RoleBO.java @@ -0,0 +1,32 @@ +package cn.iocoder.mall.system.biz.bo.authorization; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 授权模块 - 角色信息 BO + */ +@Data +@Accessors(chain = true) +public class RoleBO { + + /** + * 角色编号 + */ + private Integer id; + /** + * 角色名字 + */ + private String name; + /** + * 角色编码 + */ + private String code; + /** + * 添加时间 + */ + private Date createTime; + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/user/UserBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/user/UserBO.java index f77cb8178..409829ffd 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/user/UserBO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/user/UserBO.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.experimental.Accessors; /** - * TODO 注释 + * User 模块 - User 信息 BO */ @Data @Accessors(chain = true) diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java index 02a1cb837..8bf1df19b 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java @@ -21,9 +21,9 @@ public interface SmsSignConvert { SmsSignConvert INSTANCE = Mappers.getMapper(SmsSignConvert.class); @Mappings({}) - SmsSignBO convert(SmsSignDO smsSignDO); + SmsSignBO convert(SmsSignDO bean); @Mappings({}) - List convert(List smsSignDOList); + List convert(List beans); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/account/AccountConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/account/AccountConvert.java index 619779537..de9787d18 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/account/AccountConvert.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/account/AccountConvert.java @@ -11,8 +11,8 @@ public interface AccountConvert { AccountConvert INSTANCE = Mappers.getMapper(AccountConvert.class); - AccountBO convert(AccountDO accountDO); + AccountBO convert(AccountDO bean); - AccountDO convert(AccountCreateDTO accountCreateDTO); + AccountDO convert(AccountCreateDTO bean); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/admin/AdminConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/admin/AdminConvert.java index b176b07a6..0bddb49eb 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/admin/AdminConvert.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/admin/AdminConvert.java @@ -10,6 +10,6 @@ public interface AdminConvert { AdminConvert INSTANCE = Mappers.getMapper(AdminConvert.class); - AdminBO convert(AdminDO adminDO); + AdminBO convert(AdminDO bean); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/authorization/ResourceConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/authorization/ResourceConvert.java new file mode 100644 index 000000000..5e395f915 --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/authorization/ResourceConvert.java @@ -0,0 +1,19 @@ +package cn.iocoder.mall.system.biz.convert.authorization; + +import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO; +import cn.iocoder.mall.system.biz.dataobject.authorization.ResourceDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface ResourceConvert { + + ResourceConvert INSTANCE = Mappers.getMapper(ResourceConvert.class); + + ResourceBO convert(ResourceDO bean); + + List convertList(List beans); + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/authorization/RoleConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/authorization/RoleConvert.java new file mode 100644 index 000000000..67b8fd12c --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/authorization/RoleConvert.java @@ -0,0 +1,19 @@ +package cn.iocoder.mall.system.biz.convert.authorization; + +import cn.iocoder.mall.system.biz.bo.authorization.RoleBO; +import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface RoleConvert { + + RoleConvert INSTANCE = Mappers.getMapper(RoleConvert.class); + + RoleBO convert(RoleDO bean); + + List convertList(List beans); + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/oauth2/OAuth2Convert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/oauth2/OAuth2Convert.java index 1e5142a51..79ab3582f 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/oauth2/OAuth2Convert.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/oauth2/OAuth2Convert.java @@ -10,6 +10,6 @@ public interface OAuth2Convert { OAuth2Convert INSTANCE = Mappers.getMapper(OAuth2Convert.class); - OAuth2AccessTokenBO convert(OAuth2AccessTokenDO accessTokenDO); + OAuth2AccessTokenBO convert(OAuth2AccessTokenDO bean); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/systemlog/SystemLogConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/systemlog/SystemLogConvert.java index 075823fbe..bcd750a9d 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/systemlog/SystemLogConvert.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/systemlog/SystemLogConvert.java @@ -12,8 +12,8 @@ public interface SystemLogConvert { SystemLogConvert INSTANCE = Mappers.getMapper(SystemLogConvert.class); - AccessLogDO convert(AccessLogAddDTO accessLogAddDTO); + AccessLogDO convert(AccessLogAddDTO bean); - ExceptionLogDO convert(ExceptionLogAddDTO exceptionLogAddDTO); + ExceptionLogDO convert(ExceptionLogAddDTO bean); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/user/UserConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/user/UserConvert.java index de98bfe38..6a691209c 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/user/UserConvert.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/user/UserConvert.java @@ -17,6 +17,6 @@ public interface UserConvert { @Mapping(source = "accessTokenBO", target = "token") UserAuthenticateBO convert(UserBO userBO, OAuth2AccessTokenBO accessTokenBO); - UserBO convert(UserDO userDO); + UserBO convert(UserDO bean); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/admin/AdminMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/admin/AdminMapper.java index 30d453b08..b8bce40b1 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/admin/AdminMapper.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/admin/AdminMapper.java @@ -1,10 +1,17 @@ package cn.iocoder.mall.system.biz.dao.admin; import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.springframework.stereotype.Repository; @Repository public interface AdminMapper extends BaseMapper { + default AdminDO selectByAccountId(Integer accountId) { + return selectOne(new QueryWrapper() + .eq("account_id", accountId) + ); + } + } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/AccountRoleMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/AccountRoleMapper.java new file mode 100644 index 000000000..24cc0cd47 --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/AccountRoleMapper.java @@ -0,0 +1,38 @@ +package cn.iocoder.mall.system.biz.dao.authorization; + +import cn.iocoder.mall.system.biz.dataobject.authorization.AccountRoleDO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.Collection; +import java.util.List; + +@Repository +public interface AccountRoleMapper extends BaseMapper { + + default List selectByAccountId( Integer accountId) { + return selectList(new QueryWrapper().eq("account_id", accountId)); + } + + default List selectListByAccountIds(Collection accountIds) { + return selectList(new QueryWrapper().in("account_id", accountIds)); + } + + default int deleteByAccountId(Integer accountId) { + return delete(new QueryWrapper().eq("account_id", accountId)); + } + + default int deleteByRoleId(Integer roleId) { + return delete(new QueryWrapper().eq("role_id", roleId)); + } + + /** + * 批量插入。因为 MyBaits Plus 的批量插入是基于 Service 实现,所以只好写 XML + * + * @param accountRoleDOs 数组 + */ + int insertList(@Param("accountRoleDOs") List accountRoleDOs); + +} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/ResourceMapper.java similarity index 65% rename from system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java rename to system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/ResourceMapper.java index 473065670..67281da61 100644 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/ResourceMapper.java @@ -1,12 +1,13 @@ -package cn.iocoder.mall.admin.dao; +package cn.iocoder.mall.system.biz.dao.authorization; import cn.iocoder.common.framework.mybatis.QueryWrapperX; -import cn.iocoder.mall.admin.dataobject.ResourceDO; +import cn.iocoder.mall.system.biz.dataobject.authorization.ResourceDO; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -17,18 +18,18 @@ public interface ResourceMapper extends BaseMapper { List selectListByTypeAndRoleIds(@Param("type") Integer type, @Param("roleIds") Set roleIds); - default List selectListByPermission(String permission) { - return selectList(new QueryWrapperX().like("permissions", permission)); + default ResourceDO selectByPermission(String permission) { + return selectOne(new QueryWrapper().eq("permission", permission)); + } + + default List selectListByPermissions(Collection permissions) { + return selectList(new QueryWrapper().in("permission", permissions)); } default List selectListByType(Integer type) { return selectList(new QueryWrapperX().eqIfPresent("type", type)); } - default List selectListByIds(Set ids) { - return selectList(new QueryWrapper().in("id", ids)); - } - default int selectCountByPid(Integer pid) { return selectCount(new QueryWrapper().eq("pid", pid)); } diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/RoleMapper.java similarity index 81% rename from system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleMapper.java rename to system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/RoleMapper.java index 9ff13b49e..dc007a7e1 100644 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleMapper.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/RoleMapper.java @@ -1,8 +1,8 @@ -package cn.iocoder.mall.admin.dao; +package cn.iocoder.mall.system.biz.dao.authorization; import cn.iocoder.common.framework.mybatis.QueryWrapperX; -import cn.iocoder.mall.system.api.dto.role.RolePageDTO; -import cn.iocoder.mall.admin.dataobject.RoleDO; +import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO; +import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/RoleResourceMapper.java similarity index 84% rename from system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java rename to system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/RoleResourceMapper.java index 6c31aed5c..361bb8539 100644 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/authorization/RoleResourceMapper.java @@ -1,6 +1,6 @@ -package cn.iocoder.mall.admin.dao; +package cn.iocoder.mall.system.biz.dao.authorization; -import cn.iocoder.mall.admin.dataobject.RoleResourceDO; +import cn.iocoder.mall.system.biz.dataobject.authorization.RoleResourceDO; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; @@ -23,7 +23,7 @@ public interface RoleResourceMapper extends BaseMapper { return selectList(new QueryWrapper().eq("resource_id", resourceId)); } - default List selectListByResourceId(Collection resourceIds) { + default List selectListByResourceIds(Collection resourceIds) { return selectList(new QueryWrapper().in("resource_id", resourceIds)); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/AccountRoleDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/AccountRoleDO.java index efb41fb14..b5e63c41f 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/AccountRoleDO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/AccountRoleDO.java @@ -4,14 +4,16 @@ import cn.iocoder.common.framework.dataobject.DeletableDO; import cn.iocoder.mall.system.biz.dataobject.account.AccountDO; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** * {@link AccountDO} 和 {@link RoleDO} 的关联表 */ -@TableName("admin_role") @Data +@EqualsAndHashCode(callSuper = true) @Accessors(chain = true) +@TableName("account_role") public class AccountRoleDO extends DeletableDO { /** diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/ResourceDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/ResourceDO.java index e629c3bb8..0c0fab45f 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/ResourceDO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/ResourceDO.java @@ -1,6 +1,7 @@ package cn.iocoder.mall.system.biz.dataobject.authorization; import cn.iocoder.common.framework.dataobject.DeletableDO; +import cn.iocoder.mall.system.biz.enums.authorization.ResourceTypeEnum; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -37,7 +38,7 @@ public class ResourceDO extends DeletableDO { /** * 资源类型 * - * 关联 {@link Resource} + * 关联 {@link ResourceTypeEnum} */ private Integer type; /** @@ -51,23 +52,16 @@ public class ResourceDO extends DeletableDO { */ private Integer pid; /** + * 前端路由 * - * - * 目前当且仅当资源类型为【菜单】时,才会生效,即 handler 配置为界面 URL ,或者前端组件名,或者前端的路由。 + * 目前当且仅当资源类型为 {@link ResourceTypeEnum#MENU} 时,才会生效 */ - private String handler; + private String route; /** - * 图标 + * 菜单图标 * - * 目前当且仅当资源类型为【菜单】时,才会生效 + * 目前当且仅当资源类型为 {@link ResourceTypeEnum#MENU} 时,才会生效 */ private String icon; - /** - * 权限标识数组,使用逗号分隔。 - * - * 例如:system:admin:add - * 推荐格式为 ${系统}:${模块}:${操作} - */ - private String permissions; } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleDO.java index 58f680756..573d7bf03 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleDO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleDO.java @@ -3,14 +3,16 @@ package cn.iocoder.mall.system.biz.dataobject.authorization; import cn.iocoder.common.framework.dataobject.DeletableDO; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** * 角色实体 */ -@TableName("role") @Data +@EqualsAndHashCode(callSuper = true) @Accessors(chain = true) +@TableName("role") public class RoleDO extends DeletableDO { /** @@ -21,5 +23,9 @@ public class RoleDO extends DeletableDO { * 角色名 */ private String name; + /** + * 角色编码 + */ + private String code; } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleResourceDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleResourceDO.java index 19efc9774..7765fdc56 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleResourceDO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/authorization/RoleResourceDO.java @@ -3,14 +3,16 @@ package cn.iocoder.mall.system.biz.dataobject.authorization; import cn.iocoder.common.framework.dataobject.DeletableDO; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** * {@link RoleDO} 和 {@link ResourceDO} 的关联表 */ -@TableName("role_resource") @Data +@EqualsAndHashCode(callSuper = true) @Accessors(chain = true) +@TableName("role_resource") public class RoleResourceDO extends DeletableDO { /** diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/user/UserDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/user/UserDO.java index d686097d2..5a30861d6 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/user/UserDO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/user/UserDO.java @@ -1,6 +1,6 @@ package cn.iocoder.mall.system.biz.dataobject.user; -import cn.iocoder.common.framework.dataobject.BaseDO; +import cn.iocoder.common.framework.dataobject.DeletableDO; import cn.iocoder.mall.system.biz.dataobject.account.AccountDO; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -14,7 +14,7 @@ import lombok.experimental.Accessors; @Data @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) -public class UserDO extends BaseDO { +public class UserDO extends DeletableDO { /** * 用户编号 diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/AuthorizationCheckPermissionsDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/AuthorizationCheckPermissionsDTO.java index b85fe7658..712d814ae 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/AuthorizationCheckPermissionsDTO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/AuthorizationCheckPermissionsDTO.java @@ -4,17 +4,18 @@ import lombok.Data; import lombok.experimental.Accessors; import javax.validation.constraints.NotNull; +import java.util.Collection; /** - * OAuth2 模块 - 访问令牌认证 Request + * 授权模块 - 校验账号是否有权限 DTO */ @Data @Accessors(chain = true) public class AuthorizationCheckPermissionsDTO { - @NotNull(message = "访问令牌不能为空") - private String accessToken; - @NotNull(message = "IP 不能为空") - private String ip; + @NotNull(message = "账号编号不能为空") + private Integer accountId; + @NotNull(message = "权限不能为空") + private Collection permissions; } diff --git a/system/system-service-api/src/main/java/cn/iocoder/mall/system/api/dto/role/RolePageDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/RolePageDTO.java similarity index 88% rename from system/system-service-api/src/main/java/cn/iocoder/mall/system/api/dto/role/RolePageDTO.java rename to system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/RolePageDTO.java index a9e0f35f8..0ca2e2366 100644 --- a/system/system-service-api/src/main/java/cn/iocoder/mall/system/api/dto/role/RolePageDTO.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/authorization/RolePageDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.mall.system.api.dto.role; +package cn.iocoder.mall.system.biz.dto.authorization; import cn.iocoder.common.framework.vo.PageParam; import io.swagger.annotations.ApiModel; diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/authorization/RoleCodeEnum.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/authorization/RoleCodeEnum.java new file mode 100644 index 000000000..377b2c5a3 --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/authorization/RoleCodeEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.mall.system.biz.enums.authorization; + +public enum RoleCodeEnum { + + SUPER_ADMIN("SUPER_ADMIN"), // 超级管理员 + ; + + /** + * 角色编码 + */ + private final String code; + + RoleCodeEnum(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminService.java index 6c5e24849..60e35e53d 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminService.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminService.java @@ -7,6 +7,8 @@ import cn.iocoder.mall.system.biz.bo.admin.AdminBO; */ public interface AdminService { - AdminBO get(Integer id); + AdminBO getAdmin(Integer id); + + AdminBO getAdminByAccountId(Integer accountId); } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java index 41fc442ca..616c2ceb4 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java @@ -4,7 +4,6 @@ import cn.iocoder.mall.system.biz.bo.admin.AdminBO; import cn.iocoder.mall.system.biz.convert.admin.AdminConvert; import cn.iocoder.mall.system.biz.dao.admin.AdminMapper; import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO; -import cn.iocoder.mall.system.biz.service.admin.AdminService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -15,9 +14,15 @@ public class AdminServiceImpl implements AdminService { private AdminMapper adminMapper; @Override - public AdminBO get(Integer id) { + public AdminBO getAdmin(Integer id) { AdminDO adminDO = adminMapper.selectById(id); return AdminConvert.INSTANCE.convert(adminDO); } + @Override + public AdminBO getAdminByAccountId(Integer accountId) { + AdminDO adminDO = adminMapper.selectByAccountId(accountId); + return AdminConvert.INSTANCE.convert(adminDO); + } + } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AuthorizationService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AuthorizationService.java deleted file mode 100644 index 6f2347e37..000000000 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AuthorizationService.java +++ /dev/null @@ -1,10 +0,0 @@ -package cn.iocoder.mall.system.biz.service.admin; - -/** - * 授权 Service 接口 - */ -public class AuthorizationService { - - - -} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/AuthorizationServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/AuthorizationServiceImpl.java index 5761c0700..15c1c9f03 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/AuthorizationServiceImpl.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/AuthorizationServiceImpl.java @@ -1,14 +1,68 @@ package cn.iocoder.mall.system.biz.service.authorization; +import cn.iocoder.common.framework.util.CollectionUtil; +import cn.iocoder.common.framework.util.ServiceExceptionUtil; +import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO; +import cn.iocoder.mall.system.biz.dao.authorization.AccountRoleMapper; +import cn.iocoder.mall.system.biz.dao.authorization.RoleResourceMapper; +import cn.iocoder.mall.system.biz.dataobject.authorization.AccountRoleDO; +import cn.iocoder.mall.system.biz.dataobject.authorization.RoleResourceDO; import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationCheckPermissionsDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum.AUTHORIZATION_PERMISSION_DENY; + @Service +@Slf4j public class AuthorizationServiceImpl implements AuthorizationService { + @Autowired + private AccountRoleMapper accountRoleMapper; + @Autowired + private RoleResourceMapper roleResourceMapper; + + @Autowired + private RoleService roleService; + @Autowired + private ResourceService resourceService; + @Override public void checkPermissions(AuthorizationCheckPermissionsDTO checkPermissionsDTO) { - + // 查询管理员拥有的角色关联数据 + List accountRoleDOs = accountRoleMapper.selectByAccountId(checkPermissionsDTO.getAccountId()); + if (CollectionUtil.isEmpty(accountRoleDOs)) { // 如果没有角色,默认无法访问 + throw ServiceExceptionUtil.exception(AUTHORIZATION_PERMISSION_DENY); + } + Set roleIds = CollectionUtil.convertSet(accountRoleDOs, AccountRoleDO::getRoleId); + // 判断是否为超管。若是超管,默认有所有权限 + if (roleService.hasSuperAdmin(roleIds)) { + return; + } + // 查询权限对应资源 + List resourceBOs = resourceService.getListByPermissions(checkPermissionsDTO.getPermissions()); + if (CollectionUtil.isEmpty(resourceBOs)) { // 无对应资源,则认为无需权限验证 + log.warn("[checkPermissions][permission({}) 未配置对应资源]", checkPermissionsDTO.getPermissions()); + return; + } + Set permissionIds = CollectionUtil.convertSet(resourceBOs, ResourceBO::getId); + // 权限验证 + List roleResourceDOs = roleResourceMapper.selectListByResourceIds(permissionIds); + if (CollectionUtil.isEmpty(roleResourceDOs)) { // 资源未授予任何角色,必然权限验证不通过 + throw ServiceExceptionUtil.exception(AUTHORIZATION_PERMISSION_DENY); + } + Map> resourceRoleMap = CollectionUtil.convertMultiMap(roleResourceDOs, + RoleResourceDO::getResourceId, RoleResourceDO::getRoleId); + for (Map.Entry> entry : resourceRoleMap.entrySet()) { + if (!CollectionUtil.containsAny(roleIds, entry.getValue())) { // 所以有任一不满足,就验证失败,抛出异常 + throw ServiceExceptionUtil.exception(AUTHORIZATION_PERMISSION_DENY); + } + } } } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceService.java index 9a786d879..b372a1836 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceService.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceService.java @@ -1,4 +1,12 @@ package cn.iocoder.mall.system.biz.service.authorization; +import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO; + +import java.util.Collection; +import java.util.List; + public interface ResourceService { + + List getListByPermissions(Collection permissions); + } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceServiceImpl.java new file mode 100644 index 000000000..9d6cee1b3 --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/ResourceServiceImpl.java @@ -0,0 +1,25 @@ +package cn.iocoder.mall.system.biz.service.authorization; + +import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO; +import cn.iocoder.mall.system.biz.convert.authorization.ResourceConvert; +import cn.iocoder.mall.system.biz.dao.authorization.ResourceMapper; +import cn.iocoder.mall.system.biz.dataobject.authorization.ResourceDO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +@Service +public class ResourceServiceImpl implements ResourceService { + + @Autowired + private ResourceMapper resourceMapper; + + @Override + public List getListByPermissions(Collection permissions) { + List resourceDOs = resourceMapper.selectListByPermissions(permissions); + return ResourceConvert.INSTANCE.convertList(resourceDOs); + } + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleService.java index 3a1e562c1..c17b40e01 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleService.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleService.java @@ -1,4 +1,20 @@ package cn.iocoder.mall.system.biz.service.authorization; +import cn.iocoder.mall.system.biz.bo.authorization.RoleBO; + +import java.util.Collection; +import java.util.List; + public interface RoleService { + + List getRoleList(Collection ids); + + /** + * 判断指定角色是否包含超级管理员角色 + * + * @param ids 角色编号数组 + * @return 是否有超级管理员角色 + */ + boolean hasSuperAdmin(Collection ids); + } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleServiceImpl.java new file mode 100644 index 000000000..fad1ed3f6 --- /dev/null +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/authorization/RoleServiceImpl.java @@ -0,0 +1,37 @@ +package cn.iocoder.mall.system.biz.service.authorization; + +import cn.iocoder.mall.system.biz.bo.authorization.RoleBO; +import cn.iocoder.mall.system.biz.convert.authorization.RoleConvert; +import cn.iocoder.mall.system.biz.dao.authorization.RoleMapper; +import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO; +import cn.iocoder.mall.system.biz.enums.authorization.RoleCodeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +@Service +public class RoleServiceImpl implements RoleService { + + @Autowired + private RoleMapper roleMapper; + + @Override + public List getRoleList(Collection ids) { + List roleDOs = roleMapper.selectBatchIds(ids); + return RoleConvert.INSTANCE.convertList(roleDOs); + } + + @Override + public boolean hasSuperAdmin(Collection ids) { + List roleDOs = roleMapper.selectBatchIds(ids); + for (RoleDO roleDO : roleDOs) { + if (RoleCodeEnum.SUPER_ADMIN.getCode().equals(roleDO.getCode())) { + return true; + } + } + return false; + } + +} diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java index e858d6283..e399f14b4 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java @@ -1,6 +1,7 @@ package cn.iocoder.mall.system.biz.service.user; import cn.iocoder.mall.system.biz.bo.user.UserAuthenticateBO; +import cn.iocoder.mall.system.biz.bo.user.UserBO; import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeAuthenticateDTO; /** @@ -10,4 +11,6 @@ public interface UserService { UserAuthenticateBO authenticate(OAuth2MobileCodeAuthenticateDTO authenticateDTO); + UserBO getUserByAccountId(Integer accountId); + } diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java index 554087a0e..035f3b489 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.mall.system.biz.service.user; +import cn.iocoder.common.framework.constant.DeletedStatusEnum; import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO; import cn.iocoder.mall.system.biz.bo.user.UserAuthenticateBO; import cn.iocoder.mall.system.biz.bo.user.UserBO; @@ -36,9 +37,16 @@ public class UserServiceImpl implements UserService { return UserConvert.INSTANCE.convert(userBO, accessTokenBO); } + @Override + public UserBO getUserByAccountId(Integer accountId) { + UserDO userDO = userMapper.selectById(accountId); + return UserConvert.INSTANCE.convert(userDO); + } + private UserDO creatUser(Integer accountId) { UserDO user = new UserDO(); user.setAccountId(accountId); + user.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()); userMapper.insert(user); return user; } diff --git a/system/system-biz/src/main/resources/biz.yaml b/system/system-biz/src/main/resources/biz.yaml index 133cfe8d1..c6dfd5de9 100644 --- a/system/system-biz/src/main/resources/biz.yaml +++ b/system/system-biz/src/main/resources/biz.yaml @@ -17,4 +17,3 @@ mybatis-plus: logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) mapper-locations: classpath*:mapper/*.xml type-aliases-package: cn.iocoder.mall.system.biz.dataobject - diff --git a/system/system-biz/src/main/resources/mapper/AdminRoleMapper.xml b/system/system-biz/src/main/resources/mapper/AdminRoleMapper.xml new file mode 100644 index 000000000..e0ab1da7e --- /dev/null +++ b/system/system-biz/src/main/resources/mapper/AdminRoleMapper.xml @@ -0,0 +1,14 @@ + + + + + + INSERT INTO account_role ( + account_id, role_id, create_time, deleted + ) VALUES + + (#{accountRole.accountId}, #{accountRole.roleId}, #{accountRole.createTime}, #{accountRole.deleted}) + + + + diff --git a/system/system-service-impl/src/main/resources/mapper/ResourceMapper.xml b/system/system-biz/src/main/resources/mapper/ResourceMapper.xml similarity index 100% rename from system/system-service-impl/src/main/resources/mapper/ResourceMapper.xml rename to system/system-biz/src/main/resources/mapper/ResourceMapper.xml diff --git a/system/system-service-impl/src/main/resources/mapper/RoleResourceMapper.xml b/system/system-biz/src/main/resources/mapper/RoleResourceMapper.xml similarity index 100% rename from system/system-service-impl/src/main/resources/mapper/RoleResourceMapper.xml rename to system/system-biz/src/main/resources/mapper/RoleResourceMapper.xml diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/datadict/AdminsDataDictController.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/datadict/AdminsDataDictController.java new file mode 100644 index 000000000..0c8e3d737 --- /dev/null +++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/datadict/AdminsDataDictController.java @@ -0,0 +1,74 @@ +package cn.iocoder.mall.system.rest.controller.datadict; + +import cn.iocoder.common.framework.constant.MallConstants; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.security.core.annotation.RequiresPermissions; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/data-dict") +@Api(tags = "管理员 - 数据字典 API") +public class AdminsDataDictController { + +// @Reference(validation = "true", version = "${dubbo.provider.DataDictService.version}") +// private DataDictService dataDictService; + + @GetMapping("/demo") + @ApiOperation(value = "数据字典全列表") + @RequiresPermissions("system.dataDict.list") + public CommonResult list() { + return CommonResult.success(true); + } + +// @GetMapping("/list") +// @ApiOperation(value = "数据字典全列表") +// @RequiresPermissions("system.dataDict.list") +// public CommonResult> list() { +// return success( dataDictService.selectDataDictList()); +// } +// +// @GetMapping("/tree") +// @RequiresPermissions // 因为是通用的接口,所以无需权限标识 +// @ApiOperation(value = "数据字典树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。") +// public CommonResult> tree() { +// // 查询数据字典全列表 +// List dataDicts = dataDictService.selectDataDictList(); +// // 构建基于 enumValue 聚合的 Multimap +// ImmutableListMultimap dataDictMap = Multimaps.index(dataDicts, DataDictBO::getEnumValue); // KEY 是 enumValue ,VALUE 是 DataDictBO 数组 +// // 构建返回结果 +// List dataDictEnumVOs = new ArrayList<>(dataDictMap.size()); +// dataDictMap.keys().forEach(enumValue -> { +// DataDictEnumVO dataDictEnumVO = new DataDictEnumVO().setEnumValue(enumValue) +// .setValues(DataDictConvert.INSTANCE.convert2(dataDictMap.get(enumValue))); +// dataDictEnumVOs.add(dataDictEnumVO); +// }); +// return success(dataDictEnumVOs); +// } +// +// @PostMapping("/add") +// @RequiresPermissions("system.dataDict.add") +// @ApiOperation(value = "创建数据字典") +// public CommonResult add(DataDictAddDTO dataDictAddDTO) { +// return success(dataDictService.addDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictAddDTO)); +// } +// +// @PostMapping("/update") +// @RequiresPermissions("system.dataDict.update") +// @ApiOperation(value = "更新数据字典") +// public CommonResult update(DataDictUpdateDTO dataDictUpdateDTO) { +// return success(dataDictService.updateDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictUpdateDTO)); +// } +// +// @PostMapping("/delete") +// @RequiresPermissions("system.dataDict.delete") +// @ApiOperation(value = "删除数据字典") +// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "100") +// public CommonResult delete(@RequestParam("id") Integer id) { +// return success(dataDictService.deleteDataDict(AdminSecurityContextHolder.getContext().getAdminId(), id)); +// } + +} diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java index e6a58b1a4..91f9a873c 100644 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java +++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java @@ -39,7 +39,7 @@ public class AdminsOAuth2Controller { OAuth2UsernameAuthenticateDTO authenticateDTO = AdminsOAuth2Convert.INSTANCE.convert(request); OAuth2AccessTokenBO accessTokenBO = oauth2Service.authenticate(authenticateDTO); // 获得 Admin 信息 - AdminBO adminBO = adminService.get(accessTokenBO.getAccountId()); + AdminBO adminBO = adminService.getAdmin(accessTokenBO.getAccountId()); if (adminBO == null) { throw ServiceExceptionUtil.exception(ADMIN_NOT_FOUND); } diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/admin/AdminsAdminConvert.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/admin/AdminsAdminConvert.java index 59ccceb50..cddb939d9 100644 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/admin/AdminsAdminConvert.java +++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/admin/AdminsAdminConvert.java @@ -10,6 +10,6 @@ public interface AdminsAdminConvert { AdminsAdminConvert INSTANCE = Mappers.getMapper(AdminsAdminConvert.class); - AccountUsernameAuthorizeBO convert(AdminsOAuth2UsernameAuthenticateRequest request); + AccountUsernameAuthorizeBO convert(AdminsOAuth2UsernameAuthenticateRequest bean); } diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/AdminsOAuth2Convert.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/AdminsOAuth2Convert.java index e05c25a6d..1673c51b2 100644 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/AdminsOAuth2Convert.java +++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/AdminsOAuth2Convert.java @@ -14,7 +14,7 @@ public interface AdminsOAuth2Convert { AdminsOAuth2Convert INSTANCE = Mappers.getMapper(AdminsOAuth2Convert.class); - OAuth2UsernameAuthenticateDTO convert(AdminsOAuth2UsernameAuthenticateRequest request); + OAuth2UsernameAuthenticateDTO convert(AdminsOAuth2UsernameAuthenticateRequest bean); @Mapping(source = "adminBO", target = "admin") @Mapping(source = "accessTokenBO.id", target = "token.accessToken") diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/UsersOAuth2Convert.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/UsersOAuth2Convert.java index a481d3ebb..3ca01f3da 100644 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/UsersOAuth2Convert.java +++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/oauth2/UsersOAuth2Convert.java @@ -13,9 +13,9 @@ public interface UsersOAuth2Convert { UsersOAuth2Convert INSTANCE = Mappers.getMapper(UsersOAuth2Convert.class); - OAuth2MobileCodeAuthenticateDTO convert(UsersOAuth2MobileCodeAuthenticateRequest request); + OAuth2MobileCodeAuthenticateDTO convert(UsersOAuth2MobileCodeAuthenticateRequest bean); @Mapping(source = "token.id", target = "token.accessToken") - UsersOAuth2AuthenticateResponse convert(UserAuthenticateBO userAuthenticateBO); + UsersOAuth2AuthenticateResponse convert(UserAuthenticateBO bean); } diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java index d3d559439..5054b04b8 100644 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java +++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java @@ -22,11 +22,11 @@ public interface AdminsSmsConvert { AdminsSmsConvert INSTANCE = Mappers.getMapper(AdminsSmsConvert.class); @Mappings({}) - AddSignDTO convert(AddSignRequest addSignRequest); + AddSignDTO convert(AddSignRequest bean); @Mappings({}) - UpdateSignDTO convert(UpdateSignRequest updateSignRequest); + UpdateSignDTO convert(UpdateSignRequest bean); @Mappings({}) - ListSmsTemplateDTO convert(ListSmsTemplateRequest listSmsTemplateRequest); + ListSmsTemplateDTO convert(ListSmsTemplateRequest bean); } diff --git a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/admin/AdminRPC.java b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/admin/AdminRPC.java index 5b96e1006..741662843 100644 --- a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/admin/AdminRPC.java +++ b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/admin/AdminRPC.java @@ -1,7 +1,15 @@ package cn.iocoder.mall.system.rpc.api.admin; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.system.rpc.response.admin.AdminResponse; + /** * Admin RPC 接口 */ public interface AdminRPC { + + CommonResult getAdmin(Integer id); + + CommonResult getAdminByAccountId(Integer accountId); + } diff --git a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/authorization/AuthorizationRPC.java b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/authorization/AuthorizationRPC.java new file mode 100644 index 000000000..7430f941a --- /dev/null +++ b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/authorization/AuthorizationRPC.java @@ -0,0 +1,10 @@ +package cn.iocoder.mall.system.rpc.api.authorization; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.system.rpc.request.authorization.AuthorizationCheckPermissionsRequest; + +public interface AuthorizationRPC { + + CommonResult checkPermissions(AuthorizationCheckPermissionsRequest checkPermissionsRequest); + +} diff --git a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/user/UserRPC.java b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/user/UserRPC.java new file mode 100644 index 000000000..1e04551a9 --- /dev/null +++ b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/api/user/UserRPC.java @@ -0,0 +1,15 @@ +package cn.iocoder.mall.system.rpc.api.user; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.system.rpc.response.user.UserResponse; + +/** + * User RPC 接口 + */ +public interface UserRPC { + +// CommonResult getUser(Integer id); + + CommonResult getUserByAccountId(Integer accountId); + +} diff --git a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/request/authorization/AuthorizationCheckPermissionsRequest.java b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/request/authorization/AuthorizationCheckPermissionsRequest.java index 453051c6b..1dd1b51b0 100644 --- a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/request/authorization/AuthorizationCheckPermissionsRequest.java +++ b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/request/authorization/AuthorizationCheckPermissionsRequest.java @@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull; import java.util.List; /** - * 鉴权模块 - 校验账号是否有权限 Request + * 授权模块 - 校验账号是否有权限 Request */ @Data @Accessors(chain = true) diff --git a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/admin/AdminResponse.java b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/admin/AdminResponse.java index c14a7d1ef..bb29aac0a 100644 --- a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/admin/AdminResponse.java +++ b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/admin/AdminResponse.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.experimental.Accessors; /** - * Admin 信息 Response + * Admin 模块 - Admin 信息 Response */ @Data @Accessors(chain = true) @@ -14,6 +14,5 @@ public class AdminResponse { * 管理员编号 */ private Integer id; -// private String } diff --git a/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/user/UserResponse.java b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/user/UserResponse.java new file mode 100644 index 000000000..4fae0b885 --- /dev/null +++ b/system/system-rpc-api/src/main/java/cn/iocoder/mall/system/rpc/response/user/UserResponse.java @@ -0,0 +1,18 @@ +package cn.iocoder.mall.system.rpc.response.user; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * User 模块 - User 信息 Response + */ +@Data +@Accessors(chain = true) +public class UserResponse { + + /** + * 用户编号 + */ + private Integer id; + +} diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/admn/AdminCovert.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/admn/AdminCovert.java new file mode 100644 index 000000000..b89905ead --- /dev/null +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/admn/AdminCovert.java @@ -0,0 +1,15 @@ +package cn.iocoder.mall.system.rpc.convert.admn; + +import cn.iocoder.mall.system.biz.bo.admin.AdminBO; +import cn.iocoder.mall.system.rpc.response.admin.AdminResponse; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AdminCovert { + + AdminCovert INSTANCE = Mappers.getMapper(AdminCovert.class); + + AdminResponse convert(AdminBO bean); + +} diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/authorization/AuthorizationConvert.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/authorization/AuthorizationConvert.java new file mode 100644 index 000000000..4dcd729df --- /dev/null +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/authorization/AuthorizationConvert.java @@ -0,0 +1,15 @@ +package cn.iocoder.mall.system.rpc.convert.authorization; + +import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationCheckPermissionsDTO; +import cn.iocoder.mall.system.rpc.request.authorization.AuthorizationCheckPermissionsRequest; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AuthorizationConvert { + + AuthorizationConvert INSTANCE = Mappers.getMapper(AuthorizationConvert.class); + + AuthorizationCheckPermissionsDTO convert(AuthorizationCheckPermissionsRequest bean); + +} diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/oauth2/OAuth2Convert.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/oauth2/OAuth2Convert.java index 57895bbc5..3a9606e3c 100644 --- a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/oauth2/OAuth2Convert.java +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/oauth2/OAuth2Convert.java @@ -14,6 +14,6 @@ public interface OAuth2Convert { OAuth2AccessTokenAuthenticateDTO convert(OAuth2AccessTokenAuthenticateRequest authenticateRequest); - OAuth2AccessTokenResponse convert(OAuth2AccessTokenBO accessTokenBO); + OAuth2AccessTokenResponse convert(OAuth2AccessTokenBO bean); } diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/systemlog/SystemLogConvert.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/systemlog/SystemLogConvert.java index 2fafecdf5..02b949642 100644 --- a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/systemlog/SystemLogConvert.java +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/systemlog/SystemLogConvert.java @@ -12,8 +12,8 @@ public interface SystemLogConvert { SystemLogConvert INSTANCE = Mappers.getMapper(SystemLogConvert.class); - AccessLogAddDTO convert(AccessLogAddRequest accessLogAddRequest); + AccessLogAddDTO convert(AccessLogAddRequest bean); - ExceptionLogAddDTO convert(ExceptionLogAddRequest exceptionLogAddRequest); + ExceptionLogAddDTO convert(ExceptionLogAddRequest bean); } diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/user/UserConvert.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/user/UserConvert.java new file mode 100644 index 000000000..1afbe42f4 --- /dev/null +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/convert/user/UserConvert.java @@ -0,0 +1,15 @@ +package cn.iocoder.mall.system.rpc.convert.user; + +import cn.iocoder.mall.system.biz.bo.user.UserBO; +import cn.iocoder.mall.system.rpc.response.user.UserResponse; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface UserConvert { + + UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); + + UserResponse convert(UserBO bean); + +} diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/admin/AdminRPCImpl.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/admin/AdminRPCImpl.java new file mode 100644 index 000000000..2e1fb990d --- /dev/null +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/admin/AdminRPCImpl.java @@ -0,0 +1,30 @@ +package cn.iocoder.mall.system.rpc.rpc.admin; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.system.biz.bo.admin.AdminBO; +import cn.iocoder.mall.system.biz.service.admin.AdminService; +import cn.iocoder.mall.system.rpc.api.admin.AdminRPC; +import cn.iocoder.mall.system.rpc.convert.admn.AdminCovert; +import cn.iocoder.mall.system.rpc.response.admin.AdminResponse; +import org.apache.dubbo.config.annotation.Service; +import org.springframework.beans.factory.annotation.Autowired; + +@Service(version = "${dubbo.provider.AdminRPC.version}", validation = "true") +public class AdminRPCImpl implements AdminRPC { + + @Autowired + private AdminService adminService; + + @Override + public CommonResult getAdmin(Integer id) { + AdminBO adminBO = adminService.getAdmin(id); + return CommonResult.success(AdminCovert.INSTANCE.convert(adminBO)); + } + + @Override + public CommonResult getAdminByAccountId(Integer accountId) { + AdminBO adminBO = adminService.getAdminByAccountId(accountId); + return CommonResult.success(AdminCovert.INSTANCE.convert(adminBO)); + } + +} diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/authorization/AuthorizationRPCImpl.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/authorization/AuthorizationRPCImpl.java new file mode 100644 index 000000000..afedb4ca2 --- /dev/null +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/authorization/AuthorizationRPCImpl.java @@ -0,0 +1,25 @@ +package cn.iocoder.mall.system.rpc.rpc.authorization; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationCheckPermissionsDTO; +import cn.iocoder.mall.system.biz.service.authorization.AuthorizationService; +import cn.iocoder.mall.system.rpc.api.authorization.AuthorizationRPC; +import cn.iocoder.mall.system.rpc.convert.authorization.AuthorizationConvert; +import cn.iocoder.mall.system.rpc.request.authorization.AuthorizationCheckPermissionsRequest; +import org.apache.dubbo.config.annotation.Service; +import org.springframework.beans.factory.annotation.Autowired; + +@Service(version = "${dubbo.provider.AuthorizationRPC.version}", validation = "true") +public class AuthorizationRPCImpl implements AuthorizationRPC { + + @Autowired + private AuthorizationService authorizationService; + + @Override + public CommonResult checkPermissions(AuthorizationCheckPermissionsRequest checkPermissionsRequest) { + AuthorizationCheckPermissionsDTO checkPermissionsDTO = AuthorizationConvert.INSTANCE.convert(checkPermissionsRequest); + authorizationService.checkPermissions(checkPermissionsDTO); + return CommonResult.success(true); + } + +} diff --git a/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/user/UserRPCImpl.java b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/user/UserRPCImpl.java new file mode 100644 index 000000000..729932a77 --- /dev/null +++ b/system/system-rpc/src/main/java/cn/iocoder/mall/system/rpc/rpc/user/UserRPCImpl.java @@ -0,0 +1,24 @@ +package cn.iocoder.mall.system.rpc.rpc.user; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.system.biz.bo.user.UserBO; +import cn.iocoder.mall.system.biz.service.user.UserService; +import cn.iocoder.mall.system.rpc.api.user.UserRPC; +import cn.iocoder.mall.system.rpc.convert.user.UserConvert; +import cn.iocoder.mall.system.rpc.response.user.UserResponse; +import org.apache.dubbo.config.annotation.Service; +import org.springframework.beans.factory.annotation.Autowired; + +@Service(version = "${dubbo.provider.UserRPC.version}", validation = "true") +public class UserRPCImpl implements UserRPC { + + @Autowired + private UserService userService; + + @Override + public CommonResult getUserByAccountId(Integer accountId) { + UserBO userBO = userService.getUserByAccountId(accountId); + return CommonResult.success(UserConvert.INSTANCE.convert(userBO)); + } + +} diff --git a/system/system-rpc/src/main/resources/rpc.yaml b/system/system-rpc/src/main/resources/rpc.yaml index e0b942d2b..f81f45d1a 100644 --- a/system/system-rpc/src/main/resources/rpc.yaml +++ b/system/system-rpc/src/main/resources/rpc.yaml @@ -17,9 +17,21 @@ dubbo: version: 1.0.0 OAuth2RPC: version: 1.0.0 + AuthorizationRPC: + version: 1.0.0 + AdminRPC: + version: 1.0.0 + UserRPC: + version: 1.0.0 # Dubbo 服务消费者的配置 consumer: SystemLogRPC: # 用于 AccessLogInterceptor 等拦截器,记录 HTTP API 请求的访问日志 version: 1.0.0 - OAuth2RPC: + OAuth2RPC: # 用于 AccountAuthInterceptor 拦截器,执行认证 + version: 1.0.0 + AuthorizationRPC: # 用于 AccountAuthInterceptor 拦截器,执行鉴权(权限验证) + version: 1.0.0 + AdminRPC: + version: 1.0.0 + UserRPC: version: 1.0.0 diff --git a/system/system-sdk/pom.xml b/system/system-sdk/pom.xml deleted file mode 100644 index 9b180faa7..000000000 --- a/system/system-sdk/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - system - cn.iocoder.mall - 1.0-SNAPSHOT - - 4.0.0 - jar - - system-sdk - - - - - cn.iocoder.mall - common-framework - 1.0-SNAPSHOT - - - cn.iocoder.mall - system-service-api - 1.0-SNAPSHOT - - - - - javax.servlet - servlet-api - - - - org.springframework - spring-webmvc - - - - - org.apache.dubbo - dubbo - - - - - - diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/annotation/RequiresPermissions.java b/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/annotation/RequiresPermissions.java deleted file mode 100644 index e1d472823..000000000 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/annotation/RequiresPermissions.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.mall.system.sdk.annotation; - -import java.lang.annotation.*; - -/** - * 参考 Shiro @RequiresPermissions 设计 http://shiro.apache.org/static/1.3.2/apidocs/org/apache/shiro/authz/annotation/RequiresPermissions.html - * - * 通过将该注解添加到 Controller 的方法上,进行授权鉴定 - */ -@Documented -@Target({ElementType.METHOD}) // 暂时不支持 ElementType.TYPE ,因为没有场景 -@Retention(RetentionPolicy.RUNTIME) -public @interface RequiresPermissions { - - /** - * 当有多个标识时,必须全部拥有权限,才可以操作 - * - * @return 权限标识数组 - */ - String[] value(); - -} diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/constant/LogicalEnum.java b/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/constant/LogicalEnum.java deleted file mode 100644 index edc626b9f..000000000 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/constant/LogicalEnum.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.mall.system.sdk.constant; - -/** - * 逻辑类型枚举 - */ -public enum LogicalEnum { - - /** - * 并且 - */ - AND, - /** - * 或者 - */ - OR, - -} diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/context/AdminSecurityContext.java b/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/context/AdminSecurityContext.java deleted file mode 100644 index c1679f789..000000000 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/context/AdminSecurityContext.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.mall.system.sdk.context; - -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.Set; - -/** - * Security 上下文 - */ -@Data -@Accessors(chain = true) -public class AdminSecurityContext { - - /** - * 管理员编号 - */ - private Integer adminId; - /** - * 管理员账号 - */ - private String username; - /** - * 拥有的角色编号 - */ - private Set roleIds; - -} diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/context/AdminSecurityContextHolder.java b/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/context/AdminSecurityContextHolder.java deleted file mode 100644 index 569d91f4a..000000000 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/context/AdminSecurityContextHolder.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.mall.system.sdk.context; - -/** - * {@link AdminSecurityContext} Holder - * - * 参考 spring security 的 ThreadLocalSecurityContextHolderStrategy 类,简单实现。 - */ -public class AdminSecurityContextHolder { - - private static final ThreadLocal SECURITY_CONTEXT = new ThreadLocal<>(); - - public static void setContext(AdminSecurityContext context) { - SECURITY_CONTEXT.set(context); - } - - public static AdminSecurityContext getContext() { - AdminSecurityContext ctx = SECURITY_CONTEXT.get(); - // 为空时,设置一个空的进去 - if (ctx == null) { - ctx = new AdminSecurityContext(); - SECURITY_CONTEXT.set(ctx); - } - return ctx; - } - - public static void clear() { - SECURITY_CONTEXT.remove(); - } - -} diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/interceptor/AdminSecurityInterceptor.java b/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/interceptor/AdminSecurityInterceptor.java deleted file mode 100644 index da0a5d303..000000000 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/interceptor/AdminSecurityInterceptor.java +++ /dev/null @@ -1,117 +0,0 @@ -package cn.iocoder.mall.system.sdk.interceptor; - -import cn.iocoder.common.framework.constant.UserTypeEnum; -import cn.iocoder.common.framework.exception.ServiceException; -import cn.iocoder.common.framework.util.HttpUtil; -import cn.iocoder.common.framework.util.MallUtil; -import cn.iocoder.common.framework.util.StringUtil; -import cn.iocoder.mall.system.api.AdminService; -import cn.iocoder.mall.system.api.OAuth2Service; -import cn.iocoder.mall.system.api.bo.admin.AdminAuthorizationBO; -import cn.iocoder.mall.system.api.bo.oauth2.OAuth2AuthenticationBO; -import cn.iocoder.mall.system.api.constant.AdminErrorCodeEnum; -import cn.iocoder.mall.system.api.dto.oauth2.OAuth2GetTokenDTO; -import cn.iocoder.mall.system.sdk.annotation.RequiresPermissions; -import cn.iocoder.mall.system.sdk.context.AdminSecurityContext; -import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder; -import org.apache.dubbo.config.annotation.Reference; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.util.Assert; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Arrays; -import java.util.Set; - -/** - * Admin 安全拦截器 - */ -@Component -public class AdminSecurityInterceptor extends HandlerInterceptorAdapter { - - @Reference(validation = "true", version = "${dubbo.consumer.OAuth2Service.version:1.0.0}") - private OAuth2Service oauth2Service; - @Reference(validation = "true", version = "${dubbo.consumer.AdminService.version:1.0.0}") - private AdminService adminService; - - /** - * 忽略的 URL 集合,即无需经过认证 - * - * 对于 Admin 的系统,默认所有接口都需要进行认证 - */ - @Value("${admins.security.ignore_urls:#{null}}") - private Set ignoreUrls; - - public AdminSecurityInterceptor setIgnoreUrls(Set ignoreUrls) { - this.ignoreUrls = ignoreUrls; - return this; - } - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 设置当前访问的用户类型。注意,即使未登陆,我们也认为是管理员 - MallUtil.setUserType(request, UserTypeEnum.ADMIN.getValue()); - - // 根据 accessToken 获得认证信息,判断是谁 - String accessToken = HttpUtil.obtainAuthorization(request); - OAuth2AuthenticationBO authentication = null; - ServiceException serviceException = null; - if (StringUtil.hasText(accessToken)) { - try { - authentication = oauth2Service.getAuthentication(new OAuth2GetTokenDTO().setAccessToken(accessToken) - .setUserType(UserTypeEnum.ADMIN.getValue())); - } catch (ServiceException e) { - serviceException = e; - } - } - - // 进行鉴权 - String url = request.getRequestURI(); - boolean needAuthentication = ignoreUrls == null || !ignoreUrls.contains(url); - AdminAuthorizationBO authorization = null; - if (needAuthentication) { - if (serviceException != null) { // 认证失败,抛出上面认证失败的 ServiceException 异常 - throw serviceException; - } - if (authentication == null) { // 无认证信息,抛出未登陆 ServiceException 异常 - throw new ServiceException(AdminErrorCodeEnum.OAUTH2_NOT_LOGIN.getCode(), AdminErrorCodeEnum.OAUTH2_NOT_LOGIN.getMessage()); - } - authorization = checkPermission(handler, authentication); - } - - // 鉴权完成,初始化 AdminSecurityContext 上下文 - AdminSecurityContext context = new AdminSecurityContext(); - AdminSecurityContextHolder.setContext(context); - if (authentication != null) { - context.setAdminId(authentication.getUserId()); - MallUtil.setUserId(request, authentication.getUserId()); // 记录到 request 中,避免 AdminSecurityContext 后续清理掉后,其它地方需要用到 userId - if (authorization != null) { - context.setUsername(authorization.getUsername()); - context.setRoleIds(authorization.getRoleIds()); - } - } - - // 返回成功 - return super.preHandle(request, response, handler); - } - - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { - // 清空 SecurityContext - AdminSecurityContextHolder.clear(); - } - - private AdminAuthorizationBO checkPermission(Object handler, OAuth2AuthenticationBO authentication) { - // 获得 @RequiresPermissions 注解 - Assert.isTrue(handler instanceof HandlerMethod, "handler 必须是 HandlerMethod 类型"); - HandlerMethod handlerMethod = (HandlerMethod) handler; - RequiresPermissions requiresPermissions = handlerMethod.getMethodAnnotation(RequiresPermissions.class); - // 执行校验 - return adminService.checkPermissions(authentication.getUserId(), - requiresPermissions != null ? Arrays.asList(requiresPermissions.value()) : null); - } - -} diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/package-info.java b/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/package-info.java deleted file mode 100644 index d0f606584..000000000 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/system/sdk/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 SDK 给其它服务,使用如下功能: - * - * 1. 通过 {@link cn.iocoder.mall.system.sdk.interceptor.AdminSecurityInterceptor} 拦截器,实现需要登陆 URL 的鉴权 - */ -package cn.iocoder.mall.system.sdk; diff --git a/system/system-service-api/src/main/java/cn/iocoder/mall/system/api/RoleService.java b/system/system-service-api/src/main/java/cn/iocoder/mall/system/api/RoleService.java index 1efed86b3..ac4c0aaa4 100644 --- a/system/system-service-api/src/main/java/cn/iocoder/mall/system/api/RoleService.java +++ b/system/system-service-api/src/main/java/cn/iocoder/mall/system/api/RoleService.java @@ -19,8 +19,6 @@ public interface RoleService { */ List getRoleList(); - List getRoleList(Collection ids); - RoleBO addRole(Integer adminId, RoleAddDTO roleAddDTO); Boolean updateRole(Integer adminId, RoleUpdateDTO roleUpdateDTO); diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/config/DatabaseConfiguration.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/config/DatabaseConfiguration.java deleted file mode 100644 index 6a944d0ec..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/config/DatabaseConfiguration.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.mall.admin.config; - -import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; -import com.baomidou.mybatisplus.core.injector.ISqlInjector; -import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -@Configuration -@MapperScan("cn.iocoder.mall.admin.dao") // 扫描对应的 Mapper 接口 -@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。为什么使用 proxyTargetClass 参数,参见 https://blog.csdn.net/huang_550/article/details/76492600 -public class DatabaseConfiguration { - - // 数据库连接池 Druid - - @Bean - public ISqlInjector sqlInjector() { - return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除 - } - - @Bean - public PaginationInterceptor paginationInterceptor() { - return new PaginationInterceptor(); // MyBatis Plus 分页插件 - } - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/config/ServiceExceptionConfiguration.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/config/ServiceExceptionConfiguration.java deleted file mode 100644 index b66ff4fc4..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/config/ServiceExceptionConfiguration.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.mall.admin.config; - -import cn.iocoder.common.framework.util.ServiceExceptionUtil; -import cn.iocoder.mall.system.api.constant.AdminErrorCodeEnum; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; - -@Configuration -public class ServiceExceptionConfiguration { - - @EventListener(ApplicationReadyEvent.class) // 可参考 https://www.cnblogs.com/ssslinppp/p/7607509.html - public void initMessages() { - for (AdminErrorCodeEnum item : AdminErrorCodeEnum.values()) { - ServiceExceptionUtil.put(item.getCode(), item.getMessage()); - } - } - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminRoleMapper.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminRoleMapper.java deleted file mode 100644 index a584990f3..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminRoleMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.mall.admin.dao; - -import cn.iocoder.mall.admin.dataobject.AdminRoleDO; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Param; -import org.springframework.stereotype.Repository; - -import java.util.Collection; -import java.util.List; - -@Repository -public interface AdminRoleMapper extends BaseMapper { - - default List selectByAdminId( Integer adminId) { - return selectList(new QueryWrapper().eq("admin_id", adminId)); - } - - default List selectListByAdminIds(Collection adminIds) { - return selectList(new QueryWrapper().in("admin_id", adminIds)); - } - - default int deleteByAdminId(Integer adminId) { - return delete(new QueryWrapper().eq("admin_id", adminId)); - } - - default int deleteByRoleId(Integer roleId) { - return delete(new QueryWrapper().eq("role_id", roleId)); - } - - /** - * 批量插入。因为 MyBaits Plus 的批量插入是基于 Service 实现,所以只好写 XML - * - * @param adminRoleDOs 数组 - */ - int insertList(@Param("adminRoleDOs") List adminRoleDOs); - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ExceptionLogMapper.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ExceptionLogMapper.java deleted file mode 100644 index 1e292a54b..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ExceptionLogMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.mall.admin.dao; - -import cn.iocoder.mall.admin.dataobject.ExceptionLogDO; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.springframework.stereotype.Repository; - -@Repository -public interface ExceptionLogMapper extends BaseMapper { -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/OAuth2AccessTokenMapper.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/OAuth2AccessTokenMapper.java deleted file mode 100644 index af0e90161..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/OAuth2AccessTokenMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.mall.admin.dao; - -import cn.iocoder.mall.admin.dataobject.OAuth2AccessTokenDO; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.springframework.stereotype.Repository; - -@Repository -public interface OAuth2AccessTokenMapper extends BaseMapper { - - default int updateToInvalid(Integer userId, Integer userType) { - QueryWrapper query = new QueryWrapper() - .eq("user_id", userId).eq("user_type", userType) - .eq("valid", true); - return update(new OAuth2AccessTokenDO().setValid(false), query); - } - - default int updateToInvalidByRefreshToken(String refreshToken) { - QueryWrapper query = new QueryWrapper() - .eq("refresh_token", refreshToken).eq("valid", true); - return update(new OAuth2AccessTokenDO().setValid(false), query); - } - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/OAuth2RefreshTokenMapper.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/OAuth2RefreshTokenMapper.java deleted file mode 100644 index 4fb3af973..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/OAuth2RefreshTokenMapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.mall.admin.dao; - -import cn.iocoder.mall.admin.dataobject.OAuth2RefreshTokenDO; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.springframework.stereotype.Repository; - -@Repository -public interface OAuth2RefreshTokenMapper extends BaseMapper { - - default int updateToInvalid(Integer userId, Integer userType) { - QueryWrapper query = new QueryWrapper() - .eq("user_id", userId).eq("user_type", userType) - .eq("valid", true); - return update(new OAuth2RefreshTokenDO().setValid(false), query); - } - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminRoleDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminRoleDO.java deleted file mode 100644 index b3e365b72..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminRoleDO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.DeletableDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -/** - * {@link AdminDO} 和 {@link RoleDO} 的关联表 - */ -@TableName("admin_role") -@Data -@Accessors(chain = true) -public class AdminRoleDO extends DeletableDO { - - /** - * 编号 - */ - private Integer id; - /** - * 管理员编号(外键:{@link AdminDO} - */ - private Integer adminId; - /** - * 角色编号(外键:{@link RoleDO} - */ - private Integer roleId; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ExceptionLogDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ExceptionLogDO.java deleted file mode 100644 index e324c58e1..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ExceptionLogDO.java +++ /dev/null @@ -1,118 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.BaseDO; -import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.Date; - -/** - * 异常日志 DO - */ -@Data -@Accessors(chain = true) -@TableName("exception_log") -public class ExceptionLogDO extends BaseDO { - - /** - * 编号 - */ - private Integer id; - /** - * 链路追踪编号 - * - * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 - */ - private String traceId; - /** - * 用户编号. - * - * 当管理员为空时,该值为 {@link AccessLogAddDTO#USER_ID_NULL} - */ - private Integer userId; - /** - * 用户类型 - */ - private Integer userType; - /** - * 应用名 - * - * 目前读取 spring.application.name - */ - private String applicationName; - /** - * 访问地址 - */ - private String uri; - /** - * 参数 - */ - private String queryString; - /** - * http 方法 - */ - private String method; - /** - * userAgent - */ - private String userAgent; - /** - * ip - */ - private String ip; - /** - * 异常发生时间 - */ - private Date exceptionTime; - /** - * 异常名 - * - * {@link Throwable#getClass()} 的类全名 - */ - private String exceptionName; - /** - * 异常导致的消息 - * - * {@link cn.iocoder.common.framework.util.ExceptionUtil#getMessage(Throwable)} - */ - private String exceptionMessage; - /** - * 异常导致的根消息 - * - * {@link cn.iocoder.common.framework.util.ExceptionUtil#getRootCauseMessage(Throwable)} - */ - private String exceptionRootCauseMessage; - /** - * 异常的栈轨迹 - * - * {@link cn.iocoder.common.framework.util.ExceptionUtil#getServiceException(Exception)} - */ - private String exceptionStackTrace; - /** - * 异常发生的类全名 - * - * {@link StackTraceElement#getClassName()} - */ - private String exceptionClassName; - /** - * 异常发生的类文件 - * - * {@link StackTraceElement#getFileName()} - */ - private String exceptionFileName; - /** - * 异常发生的方法名 - * - * {@link StackTraceElement#getMethodName()} - */ - private String exceptionMethodName; - /** - * 异常发生的方法所在行 - * - * {@link StackTraceElement#getLineNumber()} - */ - private Integer exceptionLineNumber; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/OAuth2AccessTokenDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/OAuth2AccessTokenDO.java deleted file mode 100644 index ec87c25c0..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/OAuth2AccessTokenDO.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.Date; - -/** - * OAUTH2 AccessToken - */ -@TableName("oauth2_access_token") -@Data -@Accessors(chain = true) -public class OAuth2AccessTokenDO extends BaseDO { - - /** - * 访问令牌 - */ - @TableId(type = IdType.INPUT) - private String id; - /** - * 刷新令牌 - */ - private String refreshToken; - /** - * 用户编号 - */ - private Integer userId; - /** - * 用户类型 - */ - private Integer userType; - /** - * 过期时间 - */ - private Date expiresTime; - /** - * 是否有效 - */ - private Boolean valid; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/OAuth2RefreshTokenDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/OAuth2RefreshTokenDO.java deleted file mode 100644 index da1261915..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/OAuth2RefreshTokenDO.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.Date; - -/** - * 刷新令牌 - * - * idx_uid - */ -@TableName("oauth2_refresh_token") -@Data -@Accessors(chain = true) -public class OAuth2RefreshTokenDO extends BaseDO { - - /** - * 刷新令牌 - */ - @TableId(type = IdType.INPUT) - private String id; - /** - * 用户编号 - */ - private Integer userId; - /** - * 用户类型 - */ - private Integer userType; - /** - * 是否有效 - */ - private Boolean valid; - /** - * 过期时间 - */ - private Date expiresTime; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java deleted file mode 100644 index 57a4fae96..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.DeletableDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -/** - * 资源实体 - */ -@TableName(value = "resource") -@Data -@Accessors(chain = true) -public class ResourceDO extends DeletableDO { - - /** - * 资源编号 - */ - private Integer id; - /** - * 资源类型 - */ - private Integer type; - /** - * 排序 - */ - private Integer sort; - /** - * 展示名 - */ - private String displayName; - /** - * 父级资源编号(外键:{@link ResourceDO#id}) - */ - private Integer pid; - /** - * 操作 - * - * 目前当且仅当资源类型为【菜单】时,才会生效,即 handler 配置为界面 URL ,或者前端组件名,或者前端的路由。 - */ - private String handler; - /** - * 图表 - * - * 目前当且仅当资源类型为【菜单】时,才会生效 - */ - private String icon; - /** - * 权限标识数组,使用逗号分隔。 - * - * 例如:system.admin.add 。 - * 推荐格式为 ${系统}.${模块}.${操作} 。 - */ - private String permissions; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java deleted file mode 100644 index 9fc58be16..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.DeletableDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -/** - * 角色实体 - */ -@TableName("role") -@Data -@Accessors(chain = true) -public class RoleDO extends DeletableDO { - - /** - * 角色编号 - */ - private Integer id; - /** - * 角色名 - */ - private String name; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleResourceDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleResourceDO.java deleted file mode 100644 index 5a29bad35..000000000 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleResourceDO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.mall.admin.dataobject; - -import cn.iocoder.common.framework.dataobject.DeletableDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.experimental.Accessors; - -/** - * {@link RoleDO} 和 {@link ResourceDO} 的关联表 - */ -@TableName("role_resource") -@Data -@Accessors(chain = true) -public class RoleResourceDO extends DeletableDO { - - /** - * 编号 - */ - private Integer id; - /** - * 角色编号(外键:{@link RoleDO} - */ - private Integer roleId; - /** - * 资源编号(外键:{@link ResourceDO} - */ - private Integer resourceId; - -} diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java index b7e11e49e..30a23c0b4 100644 --- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java +++ b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java @@ -48,28 +48,6 @@ public class AdminServiceImpl implements AdminService { @Autowired private RoleServiceImpl roleService; - @Override - public AdminAuthenticationBO authentication(AdminAuthenticationDTO adminAuthenticationDTO) { - AdminDO admin = adminMapper.selectByUsername(adminAuthenticationDTO.getUsername()); - // 账号不存在 - if (admin == null) { - throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode()); - } - // 密码不正确 - if (!encodePassword(adminAuthenticationDTO.getPassword()).equals(admin.getPassword())) { - throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_PASSWORD_ERROR.getCode()); - } - // 账号被禁用 - if (CommonStatusEnum.DISABLE.getValue().equals(admin.getStatus())) { - throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_IS_DISABLE.getCode()); - } - // 创建 accessToken - OAuth2AccessTokenBO accessTokenBO = oauth2Service.createToken(new OAuth2CreateTokenDTO().setUserId(admin.getId()) - .setUserType(UserTypeEnum.ADMIN.getValue())); - // 转换返回 - return AdminConvert.INSTANCE.convert2(admin).setToken(accessTokenBO); - } - @Override public PageResult getAdminPage(AdminPageDTO adminPageDTO) { IPage page = adminMapper.selectPage(adminPageDTO); @@ -227,29 +205,4 @@ public class AdminServiceImpl implements AdminService { return true; } - @Override - public AdminAuthorizationBO checkPermissions(Integer adminId, List permissions) { - // 查询管理员拥有的角色关联数据 - List adminRoleList = adminRoleMapper.selectByAdminId(adminId); - Set adminRoleIds = CollectionUtil.convertSet(adminRoleList, AdminRoleDO::getRoleId); - // 授权校验 - if (!CollectionUtil.isEmpty(permissions)) { - Map> permissionRoleMap = roleService.getPermissionRoleMap(permissions); - for (Map.Entry> entry : permissionRoleMap.entrySet()) { - if (!CollectionUtil.containsAny(entry.getValue(), adminRoleIds)) { // 所以有任一不满足,就验证失败,抛出异常 - throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_INVALID_PERMISSION.getCode()); - } - } - } - // 获得用户 - AdminDO admin = adminMapper.selectById(adminId); - // 返回成功 - return new AdminAuthorizationBO().setId(adminId).setUsername(admin.getUsername()) - .setRoleIds(adminRoleIds); - } - - private String encodePassword(String password) { - return DigestUtils.md5DigestAsHex(password.getBytes()); - } - } diff --git a/system/system-service-impl/src/main/resources/config/application.properties b/system/system-service-impl/src/main/resources/config/application.properties deleted file mode 100644 index 2196c16be..000000000 --- a/system/system-service-impl/src/main/resources/config/application.properties +++ /dev/null @@ -1,4 +0,0 @@ -##################### 业务模块 ##################### -## OAuth2CodeService -modules.oauth2-code-service.access-token-expire-time-millis = 2880000 -modules.oauth2-code-service.refresh-token-expire-time-millis = 43200000 \ No newline at end of file diff --git a/system/system-service-impl/src/main/resources/mapper/AdminRoleMapper.xml b/system/system-service-impl/src/main/resources/mapper/AdminRoleMapper.xml deleted file mode 100644 index c734f858b..000000000 --- a/system/system-service-impl/src/main/resources/mapper/AdminRoleMapper.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - INSERT INTO admin_role ( - admin_id, role_id, create_time, deleted - ) VALUES - - (#{adminRole.adminId}, #{adminRole.roleId}, #{adminRole.createTime}, #{adminRole.deleted}) - - - - diff --git a/user/pom.xml b/user/pom.xml index 473e4ed14..81aae4ffc 100644 --- a/user/pom.xml +++ b/user/pom.xml @@ -14,7 +14,6 @@ - user-application user-rest diff --git a/user/user-sdk/pom.xml b/user/user-sdk/pom.xml deleted file mode 100644 index 8a80f9dbf..000000000 --- a/user/user-sdk/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - user - cn.iocoder.mall - 1.0-SNAPSHOT - - 4.0.0 - - user-sdk - - - - cn.iocoder.mall - common-framework - 1.0-SNAPSHOT - - - cn.iocoder.mall - user-service-api - 1.0-SNAPSHOT - - - - - javax.servlet - servlet-api - - - - org.springframework - spring-webmvc - - - - - org.apache.dubbo - dubbo - - - - - - diff --git a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/annotation/RequiresLogin.java b/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/annotation/RequiresLogin.java deleted file mode 100644 index 528c795b5..000000000 --- a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/annotation/RequiresLogin.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.mall.user.sdk.annotation; - -import java.lang.annotation.*; - -/** - * 要求用户登录注解。通过将该注解添加到 Controller 上,会自动校验用户是否登陆。 - * - * 默认请求下,用户访问的 API 接口,无需登陆。主要的考虑是, - * 1. 需要用户登陆的接口,本身会获取在线用户的编号。如果不添加 @RequiresLogin 注解就会报错。 - * 2. 大多数情况下,用户的 API 接口无需登陆。 - */ -@Documented -@Target({ElementType.METHOD}) // 暂时不支持 ElementType.TYPE ,因为没有场景 -@Retention(RetentionPolicy.RUNTIME) -public @interface RequiresLogin { -} diff --git a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/context/UserSecurityContext.java b/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/context/UserSecurityContext.java deleted file mode 100644 index c6ab1a707..000000000 --- a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/context/UserSecurityContext.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.mall.user.sdk.context; - -import lombok.Data; -import lombok.experimental.Accessors; - -/** - * User Security 上下文 - */ -@Data -@Accessors(chain = true) -public class UserSecurityContext { - - /** - * 用户编号 - */ - private Integer userId; - -} diff --git a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/context/UserSecurityContextHolder.java b/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/context/UserSecurityContextHolder.java deleted file mode 100644 index c63c1a43b..000000000 --- a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/context/UserSecurityContextHolder.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.mall.user.sdk.context; - -/** - * {@link UserSecurityContext} Holder - * - * 参考 spring security 的 ThreadLocalSecurityContextHolderStrategy 类,简单实现。 - */ -public class UserSecurityContextHolder { - - private static final ThreadLocal SECURITY_CONTEXT = new ThreadLocal(); - - public static void setContext(UserSecurityContext context) { - SECURITY_CONTEXT.set(context); - } - - public static UserSecurityContext getContext() { - UserSecurityContext ctx = SECURITY_CONTEXT.get(); - // 为空时,设置一个空的进去 - if (ctx == null) { - ctx = new UserSecurityContext(); - SECURITY_CONTEXT.set(ctx); - } - return ctx; - } - - public static void clear() { - SECURITY_CONTEXT.remove(); - } - -} diff --git a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/interceptor/UserSecurityInterceptor.java b/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/interceptor/UserSecurityInterceptor.java deleted file mode 100644 index ee54f243a..000000000 --- a/user/user-sdk/src/main/java/cn/iocoder/mall/user/sdk/interceptor/UserSecurityInterceptor.java +++ /dev/null @@ -1,82 +0,0 @@ -package cn.iocoder.mall.user.sdk.interceptor; - -import cn.iocoder.common.framework.constant.UserTypeEnum; -import cn.iocoder.common.framework.exception.ServiceException; -import cn.iocoder.common.framework.util.HttpUtil; -import cn.iocoder.common.framework.util.MallUtil; -import cn.iocoder.common.framework.util.StringUtil; -import cn.iocoder.mall.system.api.OAuth2Service; -import cn.iocoder.mall.system.api.bo.oauth2.OAuth2AuthenticationBO; -import cn.iocoder.mall.system.api.constant.AdminErrorCodeEnum; -import cn.iocoder.mall.system.api.dto.oauth2.OAuth2GetTokenDTO; -import cn.iocoder.mall.user.sdk.annotation.RequiresLogin; -import cn.iocoder.mall.user.sdk.context.UserSecurityContext; -import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder; -import org.apache.dubbo.config.annotation.Reference; -import org.springframework.stereotype.Component; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * User 安全拦截器 - */ -@Component -public class UserSecurityInterceptor extends HandlerInterceptorAdapter { - - @Reference(validation = "true", version = "${dubbo.consumer.OAuth2Service.version:1.0.0}") - private OAuth2Service oauth2Service; - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 设置当前访问的用户类型。注意,即使未登陆,我们也认为是用户 - MallUtil.setUserType(request, UserTypeEnum.USER.getValue()); - - // 根据 accessToken 获得认证信息,判断是谁 - String accessToken = HttpUtil.obtainAuthorization(request); - OAuth2AuthenticationBO authentication = null; - ServiceException serviceException = null; - if (StringUtil.hasText(accessToken)) { - try { - authentication = oauth2Service.getAuthentication(new OAuth2GetTokenDTO().setAccessToken(accessToken) - .setUserType(UserTypeEnum.USER.getValue())); - } catch (ServiceException e) { - serviceException = e; - } - } - - // 进行鉴权 - HandlerMethod method = (HandlerMethod) handler; - boolean requiresLogin = method.hasMethodAnnotation(RequiresLogin.class); - if (requiresLogin) { // 如果需要鉴权 - if (serviceException != null) { // 认证失败,抛出上面认证失败的 ServiceException 异常 - throw serviceException; - } - if (authentication == null) { // 无认证信息,抛出未登陆 ServiceException 异常 - throw new ServiceException(AdminErrorCodeEnum.OAUTH2_NOT_LOGIN.getCode(), AdminErrorCodeEnum.OAUTH2_NOT_LOGIN.getMessage()); - } - // TODO 芋艿,后续拓展读取用户信息 - } - - // 鉴权完成,初始化 AdminSecurityContext 上下文 - UserSecurityContext context = new UserSecurityContext(); - UserSecurityContextHolder.setContext(context); - if (authentication != null) { - context.setUserId(authentication.getUserId()); - MallUtil.setUserId(request, authentication.getUserId()); // 记录到 request 中,避免 AdminSecurityContext 后续清理掉后,其它地方需要用到 userId - // TODO 芋艿,后续拓展读取用户信息 - } - - // 返回成功 - return super.preHandle(request, response, handler); - } - - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { - // 清空 SecurityContext - UserSecurityContextHolder.clear(); - } - -}