Skip to content

Commit

Permalink
Merge branch 'blossom-editor:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
T1anjiu authored Feb 7, 2024
2 parents 1c59f0a + 3d8d501 commit 106ae03
Show file tree
Hide file tree
Showing 184 changed files with 3,087 additions and 931 deletions.
2 changes: 1 addition & 1 deletion blossom-backend/backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>blossom-backend</artifactId>
<groupId>com.blossom</groupId>
<version>1.12.0-SNAPSHOT</version>
<version>1.13.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.blossom.backend.base.auth;

import cn.hutool.core.util.StrUtil;
import com.blossom.backend.base.auth.pojo.LoginReq;
import com.blossom.backend.base.auth.annotation.AuthIgnore;
import com.blossom.backend.base.auth.annotation.AuthUserType;
import com.blossom.backend.base.auth.pojo.AccessToken;
import com.blossom.backend.base.auth.pojo.KickOutReq;
import com.blossom.backend.base.auth.pojo.LoginReq;
import com.blossom.backend.base.user.UserTypeEnum;
import com.blossom.common.base.exception.XzException400;
import com.blossom.common.base.pojo.R;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -52,6 +55,18 @@ public R<?> logout() {
return R.ok();
}

/**
* 踢出用户
*
* @since 1.13.0
*/
@AuthUserType(UserTypeEnum.ADMIN)
@PostMapping("kickout")
public R<?> kickout(@RequestBody KickOutReq req) {
authService.kickout(req.getUserId());
return R.ok();
}

/**
* 检查 Token 状态
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ protected void loginByPassword(AccessToken accessToken, LoginDTO login) {
AuthException.throwBy(StrUtil.isBlank(login.getPassword()), AuthRCode.USERNAME_OR_PWD_FAULT);
UserEntity user = userService.selectByUsername(login.getUsername());
AuthException.throwBy(ObjUtil.isNull(user), AuthRCode.USERNAME_OR_PWD_FAULT);
AuthException.throwBy(user.getDelTime() == null || !user.getDelTime().equals(0L), AuthRCode.USER_NOT_ENABLED);
AuthException.throwBy(!passwordEncoder.matches(login.getPassword() + user.getSalt(), user.getPassword()), AuthRCode.USERNAME_OR_PWD_FAULT);
fillUserDetail(accessToken, user);
}
Expand All @@ -59,6 +60,15 @@ public void logout(String token) {
tokenRepository.remove(token);
}

/**
* 踢出用户的所有令牌
*
* @param userId 用户ID
*/
public void kickout(Long userId) {
tokenRepository.removeAll(userId);
}

/**
* 用户注册
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.blossom.backend.base.auth.annotation;

import com.blossom.backend.base.user.UserTypeEnum;

import java.lang.annotation.*;

/**
* 接口校验用户类型
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthUserType {

/**
* 用户的类型, 接口只允许该类型用户调用
*/
UserTypeEnum value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
Expand Down Expand Up @@ -42,17 +43,18 @@ public CaffeineTokenRepository(AuthProperties props) {
.initialCapacity(1000)
.expireAfterWrite(client.getDuration(), TimeUnit.SECONDS)
.removalListener((String key, AccessToken value, RemovalCause cause) ->
log.info("Token [" + key + "] 被删除")
log.info("Token [" + key + "] has been deleted")
)
.build();

uniqueTokenCache = Caffeine.newBuilder()
.initialCapacity(1000)
.expireAfterWrite(client.getDuration(), TimeUnit.SECONDS)
.removalListener((String userId, String token, RemovalCause cause) ->
log.info("Unique Token(userId) [" + userId + "] 被删除")
log.info("Unique Token(userId) [" + userId + "] has been deleted")
)
.build();

}

@Override
Expand All @@ -78,6 +80,17 @@ public void remove(String token) {
tokenCache.invalidate(token);
}

@Override
public void removeAll(Long userId) {
uniqueTokenCache.invalidate(userId);
Map<String, AccessToken> maps = tokenCache.asMap();
maps.forEach((k, t) -> {
if (t.getUserId().equals(userId)) {
tokenCache.invalidate(k);
}
});
}

@Override
public void saveUniqueToken(AccessToken accessToken) {
if (accessToken == null || StrUtil.isBlank(accessToken.getToken())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public enum AuthRCode implements IRCode {
*/
USERNAME_OR_PWD_FAULT ("AUTH-40004", "用户名或密码错误","用户名或密码错误, 或用户名不存在。"),
CAPTCHA_FAULT ("AUTH-40005", "验证码错误","验证码错误, 或手机号不存在。"),
USER_NOT_ENABLED ("AUTH-40010", "用户已禁用, 暂时无法登录","用户已禁用, 暂时无法登录。"),
USER_NOT_ENABLED ("AUTH-40010", "您的账户已被已禁用, 暂时无法登录","您的账户已被已禁用, 暂时无法登录。"),

/**
* 401: 未经过认证
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.blossom.backend.base.auth.AuthContext;
import com.blossom.backend.base.auth.annotation.AuthIgnore;
import com.blossom.backend.base.auth.annotation.AuthUserType;
import com.blossom.backend.base.auth.exception.AuthException;
import com.blossom.backend.base.auth.exception.AuthRCode;
import com.blossom.backend.base.user.UserTypeEnum;
import com.blossom.common.base.exception.XzException400;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.web.method.HandlerMethod;
Expand All @@ -14,7 +16,7 @@
import javax.servlet.http.HttpServletResponse;

/**
* 判断用户的类型, 只读用户只允许发送 get 请求
* 接口对于用户的校验
*/
@Slf4j
public class UserTypeInterceptor implements HandlerInterceptor {
Expand All @@ -28,7 +30,7 @@ public class UserTypeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 忽略静态资源处理器
if(handler instanceof ResourceHttpRequestHandler) {
if (handler instanceof ResourceHttpRequestHandler) {
return true;
}

Expand All @@ -40,12 +42,25 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
if (isIgnore) {
return true;
}
// GET请求校验
if (HttpMethod.GET.name().equals(request.getMethod())) {
return true;

// 校验接口允许的用户类型
boolean isCheckUserType = handlerMethod.hasMethodAnnotation(AuthUserType.class);
if (isCheckUserType) {
AuthUserType userType = handlerMethod.getMethodAnnotation(AuthUserType.class);
if (userType != null) {
UserTypeEnum type = userType.value();
if (!type.getType().equals(AuthContext.getType())) {
throw new AuthException(AuthRCode.PERMISSION_DENIED);
}
return true;
}
}

// 只读账号不非 GET 请求
if (UserTypeEnum.READONLY.getType().equals(AuthContext.getType()) && !HttpMethod.GET.name().equals(request.getMethod())) {
throw new AuthException(AuthRCode.PERMISSION_DENIED.getCode(), "您的账号为只读账号, 无法使用该功能");
}

XzException400.throwBy(UserTypeEnum.READONLY.getType().equals(AuthContext.getType()), "您的账号为只读账号, 无法使用该功能");
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public void remove(String token) {

}

@Override
public void removeAll(Long userId) {
}

@Override
public void saveUniqueToken(AccessToken accessToken) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.blossom.backend.base.auth.pojo;

import lombok.Data;

import javax.validation.constraints.NotNull;

/**
* 踢出用户
*/
@Data
public class KickOutReq {

/**
* 用户ID
*/
@NotNull(message = "userId 为必填项")
private Long userId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ public interface TokenRepository {
*/
void remove(String token);

/**
* 删除某个用户的所有 token
*
* @param userId 用户ID
*/
void removeAll(Long userId);

/**
* 保存唯一生效的 token 对象
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.blossom.backend.base.paramu;

import cn.hutool.core.util.ObjUtil;
import com.blossom.backend.base.auth.AuthContext;
import com.blossom.backend.base.auth.annotation.AuthUserType;
import com.blossom.backend.base.paramu.pojo.UserParamUpdReq;
import com.blossom.backend.base.user.UserTypeEnum;
import com.blossom.common.base.exception.XzException400;
import com.blossom.common.base.pojo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -45,6 +49,20 @@ public R<Map<String, String>> upd(@Validated @RequestBody UserParamUpdReq req) {
return R.ok(baseService.selectMap(AuthContext.getUserId(), true, UserParamEnum.values()));
}

/**
* 修改用户参数
*
* @apiNote 需要管理员权限
*/
@AuthUserType(UserTypeEnum.ADMIN)
@PostMapping("/upd/admin")
public R<Map<String, String>> updByAdmin(@Validated @RequestBody UserParamUpdReq req) {
XzException400.throwBy(ObjUtil.isNull(req.getUserId()), "用户ID为必填项");
baseService.update(req);
baseService.refresh();
return R.ok(baseService.selectMap(req.getUserId(), true, UserParamEnum.values()));
}

/**
* 刷新用户配置
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public enum UserParamEnum {
* 更多链接 JSON
*/
WEB_BLOG_LINKS(false, 0, ""),
/**
* 博客端专题特殊形式, 0:false;1:是
* @since 1.13.0
*/
WEB_BLOG_SUBJECT_TITLE(false, 0, "0"),
;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,10 @@ public interface UserParamMapper extends BaseMapper<UserParamEntity> {
* 新增参数
*/
int insertByUserId(UserParamEntity param);

/**
* 删除参数
* @param userId 用户ID
*/
void delByUserId(@Param("userId") Long userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.blossom.backend.base.auth.AuthContext;
import com.blossom.backend.base.auth.annotation.AuthIgnore;
import com.blossom.backend.base.auth.annotation.AuthUserType;
import com.blossom.backend.base.param.ParamEnum;
import com.blossom.backend.base.param.ParamService;
import com.blossom.backend.base.param.pojo.ParamUpdReq;
Expand Down Expand Up @@ -63,6 +64,7 @@ public R<Map<String, String>> list() {
/**
* 修改系统参数
*/
@AuthUserType(UserTypeEnum.ADMIN)
@PostMapping("/param/upd")
public R<Map<String, String>> upd(@Validated @RequestBody ParamUpdReq req) {
if (!UserTypeEnum.ADMIN.getType().equals(AuthContext.getType())) {
Expand All @@ -76,6 +78,7 @@ public R<Map<String, String>> upd(@Validated @RequestBody ParamUpdReq req) {
/**
* 刷新系统配置
*/
@AuthUserType(UserTypeEnum.ADMIN)
@PostMapping("/param/refresh")
public R<?> paramRefresh() {
paramService.refresh();
Expand Down
Loading

0 comments on commit 106ae03

Please sign in to comment.