Parcourir la source

@AuthUser 的 target 既可是 method, 也可是 type, 这二者应该互斥

reghao il y a 6 mois
Parent
commit
4cb8f8ad53

+ 28 - 9
account/account-service/src/main/java/cn/reghao/tnb/account/app/db/repository/AccountRepository.java

@@ -61,8 +61,26 @@ public class AccountRepository {
         userAccountMapper.updateUserAvatar(userId, avatarUrl);
     }
 
-    public Long getMaxUserId() {
-        return userAccountMapper.findMaxUserId();
+    public void addUserRole(long userId, String role) {
+        UserAccountRole userAccountRole = new UserAccountRole(userId, role);
+        userAccountRoleMapper.save(userAccountRole);
+    }
+
+    public void updateUserRegistry() {
+        UserRegistry userRegistry = getUserRegistry();
+        userRegistryMapper.update(userRegistry);
+    }
+
+    public synchronized long getNextUserId() {
+        long userId;
+        Long maxUserId = userAccountMapper.findMaxUserId();
+        if (maxUserId == null) {
+            userId = 10001L;
+        } else {
+            userId = maxUserId + 1;
+        }
+
+        return userId;
     }
 
     @Cacheable(cacheNames = "tnb:account:info", key = "#userId", unless = "#result == null")
@@ -71,9 +89,10 @@ public class AccountRepository {
         return accountInfo;
     }
 
-    public void updateUserRegistry() {
-        UserRegistry userRegistry = getUserRegistry();
-        userRegistryMapper.update(userRegistry);
+    public Set<String> getUserRoles(long userId) {
+        return userAccountRoleMapper.findByUserId(userId).stream()
+                .map(UserAccountRole::getName)
+                .collect(Collectors.toSet());
     }
 
     public UserRegistry getUserRegistry() {
@@ -109,20 +128,20 @@ public class AccountRepository {
 
     public UserAccount getUserAccountByUsername(String username) {
         UserAccount userAccount = userAccountMapper.findByUsername(username);
-        return userAccount != null ? setAuthorities(userAccount) : null;
+        return userAccount != null ? setAccountAuthorities(userAccount) : null;
     }
 
     public UserAccount getUserAccountByEmail(String email) {
         UserAccount userAccount = userAccountMapper.findByEmail(email);
-        return userAccount != null ? setAuthorities(userAccount) : null;
+        return userAccount != null ? setAccountAuthorities(userAccount) : null;
     }
 
     public UserAccount getUserAccountByMobile(String mobile) {
         UserAccount userAccount = userAccountMapper.findByMobile(mobile);
-        return userAccount != null ? setAuthorities(userAccount) : null;
+        return userAccount != null ? setAccountAuthorities(userAccount) : null;
     }
 
-    private UserAccount setAuthorities(UserAccount userAccount) {
+    private UserAccount setAccountAuthorities(UserAccount userAccount) {
         Set<UserAuthority> set = userAccountRoleMapper.findByUserId(userAccount.getUserId()).stream()
                 .map(userAccountRole -> new UserAuthority(userAccountRole.getName()))
                 .collect(Collectors.toSet());

+ 1 - 1
account/account-service/src/main/java/cn/reghao/tnb/account/app/model/po/UserAuthority.java

@@ -1,6 +1,6 @@
 package cn.reghao.tnb.account.app.model.po;
 
-import cn.reghao.tnb.account.api.constant.AccountRole;
+import cn.reghao.tnb.common.auth.AccountRole;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.SpringSecurityCoreVersion;
 import org.springframework.util.Assert;

+ 3 - 8
account/account-service/src/main/java/cn/reghao/tnb/account/app/rpc/AccountQueryImpl.java

@@ -6,13 +6,10 @@ import cn.reghao.tnb.account.api.iface.AccountQuery;
 import cn.reghao.tnb.account.app.db.repository.AccountRepository;
 import cn.reghao.tnb.account.app.model.po.UserAccount;
 import cn.reghao.tnb.account.app.service.AccountTokenService;
-import cn.reghao.tnb.account.app.service.impl.AccountRegistryServiceImpl;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.stereotype.Service;
 
-import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -26,14 +23,12 @@ import java.util.stream.Collectors;
 public class AccountQueryImpl implements AccountQuery {
     private final int pageSize = 100;
     private final AccountRepository accountRepository;
-    private final AccountRegistryServiceImpl accountRegistryService;
     private final AccountTokenService accountTokenService;
     private final IDObfuscation userIdObfuscation;
 
-    public AccountQueryImpl(AccountRepository accountRepository, AccountRegistryServiceImpl accountRegistryService,
-                            AccountTokenService accountTokenService, IDObfuscation userIdObfuscation) {
+    public AccountQueryImpl(AccountRepository accountRepository, AccountTokenService accountTokenService,
+                            IDObfuscation userIdObfuscation) {
         this.accountRepository = accountRepository;
-        this.accountRegistryService = accountRegistryService;
         this.accountTokenService = accountTokenService;
         this.userIdObfuscation = userIdObfuscation;
     }
@@ -100,7 +95,7 @@ public class AccountQueryImpl implements AccountQuery {
         if (userId != null) {
             return userId;
         } else {
-            userId = accountRegistryService.getNextUserId();
+            userId = accountRepository.getNextUserId();
         }
 
         String email = String.format("%s@tnb.cn", userId);

+ 20 - 6
account/account-service/src/main/java/cn/reghao/tnb/account/app/service/AccountProfileService.java

@@ -4,12 +4,16 @@ import cn.reghao.jutil.jdk.result.Result;
 import cn.reghao.jutil.jdk.security.RandomString;
 import cn.reghao.tnb.account.api.constant.VerifyChannel;
 import cn.reghao.tnb.account.app.db.mapper.UserAccountMapper;
+import cn.reghao.tnb.account.app.db.repository.AccountRepository;
 import cn.reghao.tnb.account.app.model.dto.*;
 import cn.reghao.tnb.account.app.model.po.UserAccount;
 import cn.reghao.tnb.account.app.security.form.AccountAuthToken;
+import cn.reghao.tnb.common.auth.AccountRole;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 
+import java.util.Set;
+
 /**
  * @author reghao
  * @date 2023-02-18 14:42:57
@@ -17,15 +21,17 @@ import org.springframework.stereotype.Service;
 @Service
 public class AccountProfileService {
     private final UserAccountMapper userAccountMapper;
+    private final AccountRepository accountRepository;
     private final PubkeyService pubkeyService;
     private final CodeService codeService;
     private final AccountTokenService accountTokenService;
     private final PasswordEncoder passwordEncoder;
 
-    public AccountProfileService(UserAccountMapper userAccountMapper, CodeService codeService,
-                                 AccountTokenService accountTokenService, PubkeyService pubkeyService,
-                                 PasswordEncoder passwordEncoder) {
+    public AccountProfileService(UserAccountMapper userAccountMapper, AccountRepository accountRepository,
+                                 CodeService codeService, AccountTokenService accountTokenService,
+                                 PubkeyService pubkeyService, PasswordEncoder passwordEncoder) {
         this.userAccountMapper = userAccountMapper;
+        this.accountRepository = accountRepository;
         this.accountTokenService = accountTokenService;
         this.pubkeyService = pubkeyService;
         this.codeService = codeService;
@@ -35,7 +41,7 @@ public class AccountProfileService {
     public Result updateUserScreenName(String screenName) {
         AccountAuthToken authToken = accountTokenService.getAuthToken();
         long userId = authToken.getUserId();
-        userAccountMapper.updateUserScreenName(userId, screenName);
+        accountRepository.updateUserScreenName(userId, screenName);
         return Result.success();
     }
 
@@ -77,7 +83,7 @@ public class AccountProfileService {
         AccountAuthToken authToken = accountTokenService.getAuthToken();
         long userId = authToken.getUserId();
 
-        UserAccount userAccount = userAccountMapper.findByUserId(userId);
+        UserAccount userAccount = accountRepository.getUserAccountByUserId(userId);
         String oldPassword = passwordUpdateDto.getOldPassword();
         String newPassword = passwordUpdateDto.getNewPassword();
         try {
@@ -126,7 +132,7 @@ public class AccountProfileService {
                 return Result.fail("短信验证码不正确, 请重新获取");
             }
 
-            UserAccount userAccount = userAccountMapper.findByEmail(email);
+            UserAccount userAccount = accountRepository.getUserAccountByEmail(email);
             if (userAccount == null) {
                 return Result.fail("帐号不存在");
             }
@@ -142,4 +148,12 @@ public class AccountProfileService {
 
         return Result.success();
     }
+
+    public void setUserAdmin(long userId) {
+        String adminRole = AccountRole.admin.getValue();
+        Set<String> userRoles = accountRepository.getUserRoles(userId);
+        if (!userRoles.contains(adminRole)) {
+            accountRepository.addUserRole(userId, adminRole);
+        }
+    }
 }

+ 3 - 15
account/account-service/src/main/java/cn/reghao/tnb/account/app/service/impl/AccountRegistryServiceImpl.java

@@ -83,7 +83,7 @@ public class AccountRegistryServiceImpl implements AccountRegistryService {
             return Result.result(ResultStatus.FAIL, "密码不正确, 请刷新页面后重新注册");
         }
 
-        long userId = getNextUserId();
+        long userId = accountRepository.getNextUserId();
         String salt = RandomString.getSalt(64);
         String encodedPassword = passwordEncoder.encode(decryptCredential + salt);
         UserAccount userAccount = new UserAccount(userId, email, mobile, encodedPassword, salt, avatarUrl);
@@ -103,25 +103,13 @@ public class AccountRegistryServiceImpl implements AccountRegistryService {
         }
 
         String decryptCredential = adminCreateAccount.getPassword();
-        long userId = getNextUserId();
+        long userId = accountRepository.getNextUserId();
         String salt = RandomString.getSalt(64);
         String encodedPassword = passwordEncoder.encode(decryptCredential + salt);
         UserAccount userAccount = new UserAccount(userId, email, mobile, encodedPassword, salt, avatarUrl);
         accountRepository.saveAccount(userAccount);
     }
 
-    public synchronized long getNextUserId() {
-        long userId;
-        Long maxUserId = accountRepository.getMaxUserId();
-        if (maxUserId == null) {
-            userId = 10001L;
-        } else {
-            userId = maxUserId + 1;
-        }
-
-        return userId;
-    }
-
     @Override
     public UserAccount createAccount(String principal, String password) {
         String email = null;
@@ -132,7 +120,7 @@ public class AccountRegistryServiceImpl implements AccountRegistryService {
             mobile = principal;
         }
 
-        long userId = getNextUserId();
+        long userId = accountRepository.getNextUserId();
         UserAccount userAccount = new UserAccount(userId, email, mobile, avatarUrl);
         accountRepository.saveAccount(userAccount);
         return accountRepository.getUserAccountByMobile(mobile);

+ 16 - 0
account/account-service/src/test/java/UserAccountTest.java

@@ -64,4 +64,20 @@ public class UserAccountTest {
         authAppDto.setCallbackUrl("");
         oAuthAppService.create(authAppDto);
     }
+
+    @Test
+    public void updateUserMobileTest() {
+    }
+
+    private String getUserMobile(long userId) {
+        String userIdStr = ""+userId;
+        int len = userIdStr.length();
+        StringBuilder sb = new StringBuilder();
+        sb.append("086");
+        sb.append("0".repeat(Math.max(0, 8 - len)));
+        sb.append(userId);
+
+        String mobile = sb.toString();
+        return mobile.length() == 11 ? mobile : "";
+    }
 }

+ 1 - 1
account/account-api/src/main/java/cn/reghao/tnb/account/api/constant/AccountRole.java → common/src/main/java/cn/reghao/tnb/common/auth/AccountRole.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.account.api.constant;
+package cn.reghao.tnb.common.auth;
 
 /**
  * @author reghao

+ 1 - 1
common/src/main/java/cn/reghao/tnb/common/auth/AuthUser.java

@@ -6,7 +6,7 @@ import java.lang.annotation.*;
  * @author reghao
  * @date 2023-07-18 15:15:10
  */
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface AuthUser {

+ 13 - 1
common/src/main/java/cn/reghao/tnb/common/auth/AuthUserAspect.java

@@ -21,12 +21,24 @@ public class AuthUserAspect {
     }
 
     @Around("loginPointCut()")
-    public Object tokenHandler(ProceedingJoinPoint point) throws Throwable {
+    public Object processMethod(ProceedingJoinPoint point) throws Throwable {
         Class<?> aClass = point.getTarget().getClass();
         MethodSignature ms = (MethodSignature)point.getSignature();
         Method method = aClass.getDeclaredMethod(ms.getName(),ms.getParameterTypes());
 
         AuthUser authUser = method.getAnnotation(AuthUser.class);
+        boolean auth = authUser.value();
+        LoginUser loginUser = UserContext.getLoginUser();
+        if (auth && loginUser.getUserId() != -1) {
+            boolean ret = loginUser.getRoles().contains(AccountRole.user.getValue());
+            return point.proceed(point.getArgs());
+        }
+
+        throw new AuthException("接口需要认证后才可访问");
+    }
+
+    @Around("@within(authUser)")
+    public Object processClass(ProceedingJoinPoint point, AuthUser authUser) throws Throwable {
         boolean auth = authUser.value();
         LoginUser loginUser = UserContext.getLoginUser();
         if (auth && loginUser.getUserId() != -1) {

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/ExamController.java

@@ -2,7 +2,7 @@ package cn.reghao.tnb.content.app.exam.controller;
 
 import cn.reghao.jutil.jdk.db.PageList;
 import cn.reghao.jutil.web.WebResult;
-import cn.reghao.tnb.account.api.constant.AccountRole;
+import cn.reghao.tnb.common.auth.AccountRole;
 import cn.reghao.tnb.common.auth.UserContext;
 import cn.reghao.tnb.content.app.exam.model.constant.PaperViewType;
 import cn.reghao.tnb.content.app.exam.model.dto.UserResult;

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/PaperViewService.java

@@ -1,6 +1,6 @@
 package cn.reghao.tnb.content.app.exam.service;
 
-import cn.reghao.tnb.account.api.constant.AccountRole;
+import cn.reghao.tnb.common.auth.AccountRole;
 import cn.reghao.tnb.common.auth.UserContext;
 import cn.reghao.tnb.content.app.exam.db.mapper.*;
 import cn.reghao.tnb.content.app.exam.model.constant.PaperViewType;

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/web/ExamRoleInterceptor.java

@@ -1,7 +1,7 @@
 package cn.reghao.tnb.content.app.exam.web;
 
 import cn.reghao.jutil.web.WebResult;
-import cn.reghao.tnb.account.api.constant.AccountRole;
+import cn.reghao.tnb.common.auth.AccountRole;
 import cn.reghao.tnb.common.auth.UserContext;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.lang.Nullable;

+ 0 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/VideoQueryController.java

@@ -2,7 +2,6 @@ package cn.reghao.tnb.content.app.vod.controller;
 
 import cn.reghao.jutil.jdk.db.PageList;
 import cn.reghao.jutil.web.WebResult;
-import cn.reghao.tnb.account.api.constant.AccountRole;
 import cn.reghao.tnb.account.api.iface.AccountQuery;
 import cn.reghao.tnb.common.auth.AuthUser;
 import cn.reghao.tnb.common.auth.UserContext;