From 32fba5f65d80c66b3f48221f9b15b789e8ced3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9C=E6=B0=B8=E6=98=A5?= Date: Fri, 28 Nov 2025 17:35:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 33 ++++++ dolphin-commons/dolphin-common-core/pom.xml | 42 ++++++++ .../common/core/constants/Constants.java | 8 ++ .../dolphin/common/core/entity/Result.java | 55 ++++++++++ .../core/exception/BusinessException.java | 14 +++ .../core/exception/GlobalExceptionAdvice.java | 21 ++++ .../dolphin-common-security/pom.xml | 59 ++++++++++ .../common/security/Authentication.java | 36 +++++++ .../common/security/AuthenticationFilter.java | 58 ++++++++++ .../security/AuthenticationInitialize.java | 8 ++ .../security/AuthenticationProvider.java | 10 ++ .../security/SecurityContextHolder.java | 20 ++++ .../common/security/UserPrincipal.java | 19 ++++ .../security/annotation/AuthorityCheck.java | 18 ++++ .../annotation/AuthorityCheckAspect.java | 32 ++++++ .../security/annotation/AuthorityIgnore.java | 14 +++ .../AuthorityIgnoreInitializer.java | 101 +++++++++++++++++ .../security/annotation/AuthorityType.java | 6 ++ .../common/security/annotation/IgnoreUrl.java | 54 ++++++++++ .../security/config/SecurityConfig.java | 24 +++++ .../exception/AuthenticationException.java | 12 +++ .../exception/InvalidTokenException.java | 14 +++ .../exception/NotAuthorityException.java | 14 +++ .../security/exception/NotLoginException.java | 8 ++ .../exception/TokenExpiredException.java | 20 ++++ .../dolphin/common/security/jwt/Jwt.java | 70 ++++++++++++ .../jwt/JwtAuthenticationInitialize.java | 91 ++++++++++++++++ dolphin-commons/pom.xml | 18 ++++ dolphin-compose/pom.xml | 91 ++++++++++++++++ .../gitlab/dolphin/DolphinApplication.java | 12 +++ .../DolphinAuthenticationProvider.java | 26 +++++ .../src/main/resources/application.yml | 21 ++++ dolphin-modules/dolphin-module-rbac/pom.xml | 58 ++++++++++ .../rbac/controller/RegionController.java | 14 +++ .../gitlab/dolphin/rbac/entity/Region.java | 39 +++++++ .../day/gitlab/dolphin/rbac/entity/User.java | 19 ++++ .../dolphin/rbac/mapper/RegionMapper.java | 9 ++ .../dolphin/rbac/service/RegionService.java | 7 ++ .../rbac/service/impl/RegionServiceImpl.java | 11 ++ dolphin-modules/pom.xml | 17 +++ pom.xml | 102 ++++++++++++++++++ 41 files changed, 1305 insertions(+) create mode 100644 .gitignore create mode 100644 dolphin-commons/dolphin-common-core/pom.xml create mode 100644 dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/constants/Constants.java create mode 100644 dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/entity/Result.java create mode 100644 dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java create mode 100644 dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/GlobalExceptionAdvice.java create mode 100644 dolphin-commons/dolphin-common-security/pom.xml create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/Authentication.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationFilter.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationInitialize.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationProvider.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/SecurityContextHolder.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/UserPrincipal.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheck.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheckAspect.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnore.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityType.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/IgnoreUrl.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/config/SecurityConfig.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/AuthenticationException.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/InvalidTokenException.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotAuthorityException.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotLoginException.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/TokenExpiredException.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/Jwt.java create mode 100644 dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtAuthenticationInitialize.java create mode 100644 dolphin-commons/pom.xml create mode 100644 dolphin-compose/pom.xml create mode 100644 dolphin-compose/src/main/java/day/gitlab/dolphin/DolphinApplication.java create mode 100644 dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java create mode 100644 dolphin-compose/src/main/resources/application.yml create mode 100644 dolphin-modules/dolphin-module-rbac/pom.xml create mode 100644 dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java create mode 100644 dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java create mode 100644 dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java create mode 100644 dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java create mode 100644 dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java create mode 100644 dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java create mode 100644 dolphin-modules/pom.xml create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/dolphin-commons/dolphin-common-core/pom.xml b/dolphin-commons/dolphin-common-core/pom.xml new file mode 100644 index 0000000..df142dc --- /dev/null +++ b/dolphin-commons/dolphin-common-core/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + day.gitlab + dolphin-backend + 0.0.1-SNAPSHOT + + + dolphin-common-core + jar + + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + + diff --git a/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/constants/Constants.java b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/constants/Constants.java new file mode 100644 index 0000000..cce7b0a --- /dev/null +++ b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/constants/Constants.java @@ -0,0 +1,8 @@ +package day.gitlab.dolphin.common.core.constants; + +public class Constants { + + public static final String SUCCESS = "success"; + + public static final String FAILURE = "failure"; +} diff --git a/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/entity/Result.java b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/entity/Result.java new file mode 100644 index 0000000..e357c32 --- /dev/null +++ b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/entity/Result.java @@ -0,0 +1,55 @@ +package day.gitlab.dolphin.common.core.entity; + +import day.gitlab.dolphin.common.core.exception.BusinessException; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.function.Supplier; + +import static day.gitlab.dolphin.common.core.constants.Constants.FAILURE; +import static day.gitlab.dolphin.common.core.constants.Constants.SUCCESS; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Result { + + private int code; + + private String message; + + private Object data; + + public static Result success() { + return Result.builder().code(200).message(SUCCESS).build(); + } + + public static Result success(Object data) { + Result result = Result.builder().code(200).message(SUCCESS).build(); + if (data instanceof Supplier) { + result.setData(((Supplier) data).get()); + } else { + result.setData(data); + } + return result; + } + + public static Result failure() { + return Result.builder().code(500).message(FAILURE).build(); + } + + public static Result failure(String message) { + return Result.builder().code(500).message(message).build(); + } + + public static Result failure(int code, String message) { + return Result.builder().code(code).message(message).build(); + } + + public static Result failure(BusinessException businessException) { + return Result.builder().code(businessException.getCode()).message(businessException.getMessage()).build(); + } +} diff --git a/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java new file mode 100644 index 0000000..789c419 --- /dev/null +++ b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.common.core.exception; + +import lombok.Getter; + +@Getter +public class BusinessException extends RuntimeException { + + private final int code; + + public BusinessException(int code, String message) { + super(message); + this.code = code; + } +} diff --git a/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/GlobalExceptionAdvice.java b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/GlobalExceptionAdvice.java new file mode 100644 index 0000000..1a5e3e6 --- /dev/null +++ b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/GlobalExceptionAdvice.java @@ -0,0 +1,21 @@ +package day.gitlab.dolphin.common.core.exception; + +import day.gitlab.dolphin.common.core.entity.Result; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@Component +@ControllerAdvice +public class GlobalExceptionAdvice { + + @ExceptionHandler(value = BusinessException.class) + public Result handleBusinessException(BusinessException e) { + return Result.failure(e); + } + + @ExceptionHandler(value = Exception.class) + public Result handleException(Exception e) { + return Result.failure(e.getMessage()); + } +} diff --git a/dolphin-commons/dolphin-common-security/pom.xml b/dolphin-commons/dolphin-common-security/pom.xml new file mode 100644 index 0000000..dad3a22 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + day.gitlab + dolphin-backend + 0.0.1-SNAPSHOT + + + dolphin-common-security + jar + + + + day.gitlab + dolphin-common-core + ${project.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-data-redis + + + io.jsonwebtoken + jjwt-api + + + org.projectlombok + lombok + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + + diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/Authentication.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/Authentication.java new file mode 100644 index 0000000..1806255 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/Authentication.java @@ -0,0 +1,36 @@ +package day.gitlab.dolphin.common.security; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class Authentication { + + private final UserPrincipal userPrincipal; + + private final List userAuthorities; + + public Authentication(UserPrincipal userPrincipal, List userAuthorities) { + this.userPrincipal = userPrincipal; + this.userAuthorities = userAuthorities; + } + + public boolean hasAllAuthorities(String[] userAuthorities) { + for (String userAuthority : userAuthorities) { + if (!this.userAuthorities.contains(userAuthority)) { + return false; + } + } + return true; + } + + public boolean hasAnyAuthorities(String[] userAuthorities) { + for (String userAuthority : userAuthorities) { + if (this.userAuthorities.contains(userAuthority)) { + return true; + } + } + return false; + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationFilter.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationFilter.java new file mode 100644 index 0000000..5f67a8b --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationFilter.java @@ -0,0 +1,58 @@ +package day.gitlab.dolphin.common.security; + +import com.fasterxml.jackson.databind.ObjectMapper; +import day.gitlab.dolphin.common.core.entity.Result; +import day.gitlab.dolphin.common.core.exception.BusinessException; +import day.gitlab.dolphin.common.security.annotation.AuthorityIgnoreInitializer; +import day.gitlab.dolphin.common.security.config.SecurityConfig; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.http.MediaType; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +public class AuthenticationFilter extends OncePerRequestFilter { + + private final SecurityConfig securityConfig; + + private final AuthorityIgnoreInitializer authorityIgnoreInitializer; + + private final AuthenticationInitialize authenticationInitialize; + + public AuthenticationFilter(SecurityConfig securityConfig, + AuthorityIgnoreInitializer authorityIgnoreInitializer, + AuthenticationInitialize authenticationInitialize) { + this.securityConfig = securityConfig; + this.authorityIgnoreInitializer = authorityIgnoreInitializer; + this.authenticationInitialize = authenticationInitialize; + } + + @Override + protected void doFilterInternal(@NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain) throws ServletException, IOException { + // 在未启用或是忽略校验的地址时直接放行 + if (!securityConfig.isEnabled() || authorityIgnoreInitializer.isIgnoreUrl(request)) { + filterChain.doFilter(request, response); + } + + try { + Authentication initialize = authenticationInitialize.initialize(request); + SecurityContextHolder.setAuthentication(initialize); + filterChain.doFilter(request, response); + } catch (BusinessException e) { + response.setStatus(e.getCode()); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setCharacterEncoding("UTF-8"); + response.getWriter().write(new ObjectMapper().writeValueAsString(Result.failure(e))); + } finally { + SecurityContextHolder.clearAuthentication(); + } + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationInitialize.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationInitialize.java new file mode 100644 index 0000000..1e68fcb --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationInitialize.java @@ -0,0 +1,8 @@ +package day.gitlab.dolphin.common.security; + +import jakarta.servlet.http.HttpServletRequest; + +public interface AuthenticationInitialize { + + Authentication initialize(HttpServletRequest request); +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationProvider.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationProvider.java new file mode 100644 index 0000000..3a10bb4 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/AuthenticationProvider.java @@ -0,0 +1,10 @@ +package day.gitlab.dolphin.common.security; + +import java.util.List; + +public interface AuthenticationProvider { + + UserPrincipal getUserPrincipal(String userId); + + List getUserAuthorities(String userId); +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/SecurityContextHolder.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/SecurityContextHolder.java new file mode 100644 index 0000000..f77fb70 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/SecurityContextHolder.java @@ -0,0 +1,20 @@ +package day.gitlab.dolphin.common.security; + +public class SecurityContextHolder { + + private static final ThreadLocal CONTEXT = new ThreadLocal<>(); + + private SecurityContextHolder() {} + + public static Authentication getAuthentication() { + return CONTEXT.get(); + } + + public static void setAuthentication(Authentication authentication) { + CONTEXT.set(authentication); + } + + public static void clearAuthentication() { + CONTEXT.remove(); + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/UserPrincipal.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/UserPrincipal.java new file mode 100644 index 0000000..fc32a06 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/UserPrincipal.java @@ -0,0 +1,19 @@ +package day.gitlab.dolphin.common.security; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UserPrincipal { + + private String id; + + private String username; + + private String nickname; +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheck.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheck.java new file mode 100644 index 0000000..7e07367 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheck.java @@ -0,0 +1,18 @@ +package day.gitlab.dolphin.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 使用该注解注解的类会进行权限校验。 + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuthorityCheck { + + AuthorityType type() default AuthorityType.AND; + + String[] value(); +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheckAspect.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheckAspect.java new file mode 100644 index 0000000..7357b5e --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityCheckAspect.java @@ -0,0 +1,32 @@ +package day.gitlab.dolphin.common.security.annotation; + +import day.gitlab.dolphin.common.security.Authentication; +import day.gitlab.dolphin.common.security.SecurityContextHolder; +import day.gitlab.dolphin.common.security.exception.NotAuthorityException; +import day.gitlab.dolphin.common.security.exception.NotLoginException; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; + +@Aspect +public class AuthorityCheckAspect { + + @Before("@annotation(authorityCheck)") + public void check(JoinPoint joinPoint, AuthorityCheck authorityCheck) { + Authentication authentication = SecurityContextHolder.getAuthentication(); + if (authentication == null) { + throw new NotLoginException(); + } + + // AuthorityCheck的type如果是AND,输出1 + if (authorityCheck.type() == AuthorityType.AND) { + if (!authentication.hasAllAuthorities(authorityCheck.value())) { + throw new NotAuthorityException(authorityCheck.value()); + } + } else if (authorityCheck.type() == AuthorityType.OR) { + if (!authentication.hasAnyAuthorities(authorityCheck.value())) { + throw new NotAuthorityException(authorityCheck.value()); + } + } + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnore.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnore.java new file mode 100644 index 0000000..acf9c9b --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnore.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 使用该注解注解的类或方法会忽略校验 + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuthorityIgnore { +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java new file mode 100644 index 0000000..3936a74 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java @@ -0,0 +1,101 @@ +package day.gitlab.dolphin.common.security.annotation; + +import day.gitlab.dolphin.common.security.config.SecurityConfig; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +public class AuthorityIgnoreInitializer implements ApplicationContextAware { + + private final List ignoreUrls = new ArrayList<>(); + + private SecurityConfig securityConfig; + + @Override + public void setApplicationContext(@NonNull ApplicationContext ctx) throws BeansException { + String contextPath = ctx.getEnvironment().getProperty("server.servlet.context-path"); + RequestMappingHandlerMapping requestMappingHandlerMapping = ctx.getBean(RequestMappingHandlerMapping.class); + Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); + + if (StringUtils.hasText(securityConfig.getIgnoreUrls())) { + Arrays.stream(securityConfig.getIgnoreUrls().split(",")) + .filter(StringUtils::hasText) + .map(s -> { + String prefixUrl = StringUtils.hasLength(contextPath) ? contextPath : ""; + prefixUrl = prefixUrl.endsWith("/") ? prefixUrl.substring(0, prefixUrl.length() - 1) : prefixUrl; + return s.startsWith("/") ? prefixUrl + s : prefixUrl + "/" + s; + }) + .map(IgnoreUrl::new) + .forEach(url -> this.ignoreUrls.add(url)); + } + + for (RequestMappingInfo mappingInfo : handlerMethods.keySet()) { + HandlerMethod handlerMethod = handlerMethods.get(mappingInfo); + Class beanClass = handlerMethod.getBeanType(); + + RequestMapping requestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class); + if (requestMapping == null) { + continue; + } + AuthorityIgnore authorityIgnore = handlerMethod.getMethodAnnotation(AuthorityIgnore.class); + if (authorityIgnore == null && !beanClass.isAnnotationPresent(AuthorityIgnore.class)) { + continue; + } + + System.out.println("beanClass:" + beanClass.getCanonicalName()); + System.out.println("method:" + handlerMethod.getMethod().getName() + " -> " + mappingInfo.getPatternValues()); + + List urlPrefix = Arrays.stream(requestMapping.method()) + .map(RequestMethod::name) + .map(StringBuffer::new) + .map(sb -> sb.append(":")) + .map(sb -> StringUtils.hasText(contextPath) ? sb.append(contextPath) : sb) + .map(StringBuffer::toString) + .map(sb -> sb.endsWith("/") ? sb.substring(0, sb.length() - 1) : sb) + .collect(Collectors.toList()); + if (urlPrefix.isEmpty()) { + String prefixUrl = StringUtils.hasText(contextPath) ? contextPath : "/"; + if (prefixUrl.endsWith("/")) { + prefixUrl = prefixUrl.substring(0, prefixUrl.length() - 1); + } + urlPrefix.add(prefixUrl); + } + + urlPrefix.stream() + .flatMap(sub -> mappingInfo.getPatternValues().stream().filter(StringUtils::hasText).map(s -> sub + s)) + .map(IgnoreUrl::new) + .forEach(url -> this.ignoreUrls.add(url)); + + System.out.println("ignoreUrls: " + ignoreUrls); + } + } + + public boolean isIgnoreUrl(HttpServletRequest request) { + String method = request.getMethod(); + String url = request.getRequestURI(); + + return this.ignoreUrls.stream().anyMatch(ignoreUrl -> ignoreUrl.isIgnoreUrl(method, url)); + } + + @Autowired + public void setSecurityConfig(SecurityConfig securityConfig) { + this.securityConfig = securityConfig; + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityType.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityType.java new file mode 100644 index 0000000..3da93b4 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityType.java @@ -0,0 +1,6 @@ +package day.gitlab.dolphin.common.security.annotation; + +public enum AuthorityType { + AND, + OR +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/IgnoreUrl.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/IgnoreUrl.java new file mode 100644 index 0000000..8080587 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/IgnoreUrl.java @@ -0,0 +1,54 @@ +package day.gitlab.dolphin.common.security.annotation; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.AntPathMatcher; + +@Setter +@Getter +public class IgnoreUrl { + + private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher(); + + private String method; + + private String url; + + public IgnoreUrl(String url) { + String urlUpperCase = url.toUpperCase(); + if (urlUpperCase.startsWith("GET:")) { + this.method = "GET"; + } else if (urlUpperCase.startsWith("HEAD:")) { + this.method = "HEAD"; + } else if (urlUpperCase.startsWith("POST:")) { + this.method = "POST"; + } else if (urlUpperCase.startsWith("PUT:")) { + this.method = "PUT"; + } else if (urlUpperCase.startsWith("PATCH:")) { + this.method = "PATCH"; + } else if (urlUpperCase.startsWith("DELETE:")) { + this.method = "DELETE"; + } else if (urlUpperCase.startsWith("OPTIONS:")) { + this.method = "OPTIONS"; + } else if (urlUpperCase.startsWith("TRACE:")) { + this.method = "TRACE"; + } else { + this.method = null; + } + + this.url = url.substring(urlUpperCase.indexOf(":") + 1); + } + + public boolean isIgnoreUrl(String method, String url) { + if (!PATH_MATCHER.match(this.url, url)) { + return false; + } + + return this.method == null || this.method.equalsIgnoreCase(method); + } + + @Override + public String toString() { + return method == null ? url : method + ":" + url; + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/config/SecurityConfig.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/config/SecurityConfig.java new file mode 100644 index 0000000..892c6af --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/config/SecurityConfig.java @@ -0,0 +1,24 @@ +package day.gitlab.dolphin.common.security.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Setter +@Getter +@Component +@ConfigurationProperties("dolphin.security") +public class SecurityConfig { + + private boolean enabled = true; + + private String ignoreUrls = ""; + + private String secret = "dolphin"; + + private long expire = 3600 * 1000L; + + private long refreshTokenExpire = 7 * 24 * 3600 * 1000L; + +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/AuthenticationException.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/AuthenticationException.java new file mode 100644 index 0000000..239cc07 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/AuthenticationException.java @@ -0,0 +1,12 @@ +package day.gitlab.dolphin.common.security.exception; + +import day.gitlab.dolphin.common.core.exception.BusinessException; +import lombok.Getter; + +@Getter +public class AuthenticationException extends BusinessException { + + public AuthenticationException(int code, String message) { + super(code, message); + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/InvalidTokenException.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/InvalidTokenException.java new file mode 100644 index 0000000..5210b02 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/InvalidTokenException.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.common.security.exception; + +import lombok.Getter; + +@Getter +public class InvalidTokenException extends AuthenticationException { + + private final String token; + + public InvalidTokenException(String token) { + super(401, "Unauthorized: Invalid token"); + this.token = token; + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotAuthorityException.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotAuthorityException.java new file mode 100644 index 0000000..1928c3a --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotAuthorityException.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.common.security.exception; + +import lombok.Getter; + +@Getter +public class NotAuthorityException extends AuthenticationException { + + private final String[] userAuthorities; + + public NotAuthorityException(String[] userAuthorities) { + super(403, "Forbidden: Insufficient permissions"); + this.userAuthorities = userAuthorities; + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotLoginException.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotLoginException.java new file mode 100644 index 0000000..a36d7de --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/NotLoginException.java @@ -0,0 +1,8 @@ +package day.gitlab.dolphin.common.security.exception; + +public class NotLoginException extends AuthenticationException{ + + public NotLoginException() { + super(401, "Unauthorized"); + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/TokenExpiredException.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/TokenExpiredException.java new file mode 100644 index 0000000..d757d5b --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/exception/TokenExpiredException.java @@ -0,0 +1,20 @@ +package day.gitlab.dolphin.common.security.exception; + +import lombok.Getter; + +import java.util.Date; + +@Getter +public class TokenExpiredException extends AuthenticationException { + + private final String token; + + private final Date expiration; + + public TokenExpiredException(String token, Date expiration) { + super(401, "Unauthorized: Token expired"); + this.token = token; + this.expiration = expiration; + } + +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/Jwt.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/Jwt.java new file mode 100644 index 0000000..e77de70 --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/Jwt.java @@ -0,0 +1,70 @@ +package day.gitlab.dolphin.common.security.jwt; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.util.StringUtils; + +import javax.crypto.SecretKey; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.UUID; + +public class Jwt { + + private final String secret; + + private final long expire; + + private final long refreshTokenExpire; + + public Jwt(String secret, long expire, long refreshTokenExpire) { + this.secret = secret; + this.expire = expire; + this.refreshTokenExpire = refreshTokenExpire; + } + + public String getTokenFromRequest(HttpServletRequest request) { + String token = request.getHeader("Authorization"); + if (StringUtils.hasText(token) && token.startsWith("Bearer ")) { + return token.substring(7); + } + return null; + } + + public String generateAccessToken(String userId) { + return Jwts.builder() + .subject(userId) + .id(UUID.randomUUID().toString()) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + expire)) + .claim("type", "access") + .signWith(getSigningKey()) + .compact(); + } + + public String generateRefreshToken(String userId) { + return Jwts.builder() + .subject(userId) + .id(UUID.randomUUID().toString()) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + refreshTokenExpire)) + .claim("type", "refresh") + .signWith(getSigningKey()) + .compact(); + } + + public Claims parseToken(String token) { + return Jwts.parser() + .verifyWith(getSigningKey()) + .build() + .parseSignedClaims(token) + .getPayload(); + } + + private SecretKey getSigningKey() { + byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8); + return Keys.hmacShaKeyFor(keyBytes); + } +} diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtAuthenticationInitialize.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtAuthenticationInitialize.java new file mode 100644 index 0000000..c56c48a --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtAuthenticationInitialize.java @@ -0,0 +1,91 @@ +package day.gitlab.dolphin.common.security.jwt; + +import com.fasterxml.jackson.databind.ObjectMapper; +import day.gitlab.dolphin.common.security.Authentication; +import day.gitlab.dolphin.common.security.AuthenticationInitialize; +import day.gitlab.dolphin.common.security.AuthenticationProvider; +import day.gitlab.dolphin.common.security.UserPrincipal; +import day.gitlab.dolphin.common.security.config.SecurityConfig; +import day.gitlab.dolphin.common.security.exception.InvalidTokenException; +import day.gitlab.dolphin.common.security.exception.NotLoginException; +import day.gitlab.dolphin.common.security.exception.TokenExpiredException; +import io.jsonwebtoken.Claims; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Component +public class JwtAuthenticationInitialize implements AuthenticationInitialize { + + private final SecurityConfig securityConfig; + + private final StringRedisTemplate stringRedisTemplate; + + private final AuthenticationProvider authenticationProvider; + + public JwtAuthenticationInitialize(SecurityConfig securityConfig, + StringRedisTemplate stringRedisTemplate, + AuthenticationProvider authenticationProvider) { + this.securityConfig = securityConfig; + this.stringRedisTemplate = stringRedisTemplate; + this.authenticationProvider = authenticationProvider; + } + + @Override + public Authentication initialize(HttpServletRequest request) { + Jwt jwt = new Jwt(securityConfig.getSecret(), securityConfig.getExpire(), securityConfig.getRefreshTokenExpire()); + + // 1、获取Token + String token = jwt.getTokenFromRequest(request); + if (token == null) { + throw new NotLoginException(); + } + // 2、解析Token,获取用户ID + String userId; + Date expiration; + try { + Claims claims = jwt.parseToken(token); + userId = claims.getSubject(); + expiration = claims.getExpiration(); + Objects.requireNonNull(userId); + Objects.requireNonNull(expiration); + } catch (Exception e) { + throw new InvalidTokenException(token); + } + // 3、判断是否过期 + if (expiration.before(new Date())) { + throw new TokenExpiredException(token, expiration); + } + // 4、从Redis或数据库中加载用户信息 + UserPrincipal userPrincipal; + List userAuthorities; + try { + String userPrincipalJson = stringRedisTemplate.opsForValue().get("dolphin:user:info:" + userId); + ObjectMapper objectMapper = new ObjectMapper(); + if (!StringUtils.hasText(userPrincipalJson)) { + userPrincipal = authenticationProvider.getUserPrincipal(userId); + stringRedisTemplate.opsForValue().set("dolphin:user:info:" + userId, objectMapper.writeValueAsString(userPrincipal)); + } else { + userPrincipal = objectMapper.readValue(userPrincipalJson, UserPrincipal.class); + } + String userAuthJson = stringRedisTemplate.opsForValue().get("dolphin:user:auth:" + userId); + if (!StringUtils.hasText(userAuthJson)) { + userAuthorities = authenticationProvider.getUserAuthorities(userId); + stringRedisTemplate.opsForValue().set("dolphin:user:auth:" + userId, objectMapper.writeValueAsString(userAuthorities)); + } else { + List list = objectMapper.readValue(userAuthJson, List.class); + userAuthorities = list.stream().map(Object::toString).collect(Collectors.toList()); + } + } catch (Exception e) { + throw new InvalidTokenException(token); + } + + return new Authentication(userPrincipal, userAuthorities); + } +} diff --git a/dolphin-commons/pom.xml b/dolphin-commons/pom.xml new file mode 100644 index 0000000..668ac46 --- /dev/null +++ b/dolphin-commons/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + day.gitlab + dolphin-backend + 0.0.1-SNAPSHOT + + + dolphin-commons + pom + + + dolphin-common-core + dolphin-common-security + + diff --git a/dolphin-compose/pom.xml b/dolphin-compose/pom.xml new file mode 100644 index 0000000..9d7a4d4 --- /dev/null +++ b/dolphin-compose/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + day.gitlab + dolphin-backend + 0.0.1-SNAPSHOT + + + dolphin-compose + jar + + + + + day.gitlab + dolphin-common-security + ${project.version} + + + day.gitlab + dolphin-module-rbac + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter-data-redis + + + + com.mysql + mysql-connector-j + runtime + + + com.oracle.database.jdbc + ojdbc11 + runtime + + + org.postgresql + postgresql + runtime + + + + org.projectlombok + lombok + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/DolphinApplication.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/DolphinApplication.java new file mode 100644 index 0000000..2c31c6f --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/DolphinApplication.java @@ -0,0 +1,12 @@ +package day.gitlab.dolphin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DolphinApplication { + + public static void main(String[] args) { + SpringApplication.run(DolphinApplication.class, args); + } +} diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java new file mode 100644 index 0000000..eed41ee --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java @@ -0,0 +1,26 @@ +package day.gitlab.dolphin.authorize; + +import day.gitlab.dolphin.common.security.AuthenticationProvider; +import day.gitlab.dolphin.common.security.UserPrincipal; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class DolphinAuthenticationProvider implements AuthenticationProvider { + + @Override + public UserPrincipal getUserPrincipal(String userId) { + UserPrincipal userPrincipal = new UserPrincipal(); + userPrincipal.setId(userId); + userPrincipal.setUsername(userId); + userPrincipal.setNickname(userId); + return userPrincipal; + } + + @Override + public List getUserAuthorities(String userId) { + return new ArrayList<>(); + } +} diff --git a/dolphin-compose/src/main/resources/application.yml b/dolphin-compose/src/main/resources/application.yml new file mode 100644 index 0000000..6944be5 --- /dev/null +++ b/dolphin-compose/src/main/resources/application.yml @@ -0,0 +1,21 @@ +server: + port: 8080 + servlet: + context-path: / +spring: + application: + name: dolphin-compose + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: org.postgresql.Driver + url: jdbc:postgresql://110.42.60.129:10002/postgres + username: postgres + password: postgres + data: + redis: + host: 110.42.60.129 + port: 10001 + database: 0 + password: 123456 + + diff --git a/dolphin-modules/dolphin-module-rbac/pom.xml b/dolphin-modules/dolphin-module-rbac/pom.xml new file mode 100644 index 0000000..5d3e340 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + day.gitlab + dolphin-modules + 0.0.1-SNAPSHOT + + + dolphin-module-rbac + jar + + + + day.gitlab + dolphin-common-security + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.mybatis-flex + mybatis-flex-spring-boot3-starter + + + + org.projectlombok + lombok + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + + diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java new file mode 100644 index 0000000..b0daa4c --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.rbac.controller; + +import day.gitlab.dolphin.rbac.service.RegionService; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/region") +public class RegionController { + + @Resource + private RegionService regionService; +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java new file mode 100644 index 0000000..f0e506b --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java @@ -0,0 +1,39 @@ +package day.gitlab.dolphin.rbac.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.keygen.KeyGenerators; +import lombok.Data; + +import java.sql.Timestamp; + +@Data +@Table("sys_rbac_region") +public class Region { + + @Id(keyType = KeyType.Generator, value = KeyGenerators.flexId) + private String id; + + private String parentId; + + private String parentCode; + + private String rootId; + + private String rootCode; + + private String name; + + private String code; + + private String extCode; + + private Integer sort; + + private String description; + + private Timestamp createTime; + + private Timestamp updateTime; +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java new file mode 100644 index 0000000..4bfec07 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java @@ -0,0 +1,19 @@ +package day.gitlab.dolphin.rbac.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.keygen.KeyGenerators; + +@Table("sys_rbac_user") +public class User { + + @Id(keyType = KeyType.Generator, value = KeyGenerators.flexId) + private String id; + + private String username; + + private String password; + + private String nickname; +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java new file mode 100644 index 0000000..ff75fef --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java @@ -0,0 +1,9 @@ +package day.gitlab.dolphin.rbac.mapper; + +import com.mybatisflex.core.BaseMapper; +import day.gitlab.dolphin.rbac.entity.Region; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface RegionMapper extends BaseMapper { +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java new file mode 100644 index 0000000..13efcec --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java @@ -0,0 +1,7 @@ +package day.gitlab.dolphin.rbac.service; + +import com.mybatisflex.core.service.IService; +import day.gitlab.dolphin.rbac.entity.Region; + +public interface RegionService extends IService { +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java new file mode 100644 index 0000000..1c8267f --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java @@ -0,0 +1,11 @@ +package day.gitlab.dolphin.rbac.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import day.gitlab.dolphin.rbac.entity.Region; +import day.gitlab.dolphin.rbac.mapper.RegionMapper; +import day.gitlab.dolphin.rbac.service.RegionService; +import org.springframework.stereotype.Service; + +@Service +public class RegionServiceImpl extends ServiceImpl implements RegionService { +} diff --git a/dolphin-modules/pom.xml b/dolphin-modules/pom.xml new file mode 100644 index 0000000..eb634fb --- /dev/null +++ b/dolphin-modules/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + day.gitlab + dolphin-backend + 0.0.1-SNAPSHOT + + + dolphin-modules + pom + + + dolphin-module-rbac + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b9d260c --- /dev/null +++ b/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + day.gitlab + dolphin-backend + 0.0.1-SNAPSHOT + dolphin-backend + pom + + + 25 + 3.5.8 + 1.11.4 + 0.13.0 + + + + dolphin-commons + dolphin-modules + dolphin-compose + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + com.mybatis-flex + mybatis-flex-dependencies + ${mybatis-flex.version} + pom + import + + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + runtime + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + runtime + + + + + +