新增禁言和封禁处理

This commit is contained in:
柏码の讲师 2025-01-05 01:28:33 +08:00
parent 735024b7ce
commit 23c17f34a9
5 changed files with 51 additions and 5 deletions

View File

@ -105,6 +105,10 @@ public class SecurityConfiguration {
} else if(exceptionOrAuthentication instanceof Authentication authentication){
User user = (User) authentication.getPrincipal();
Account account = service.findAccountByNameOrEmail(user.getUsername());
if(account.isBanned()) {
writer.write(RestBean.forbidden("登录失败,此账户已被封禁").asJsonString());
return;
}
String jwt = utils.createJwt(user, account.getUsername(), account.getId());
if(jwt == null) {
writer.write(RestBean.forbidden("登录验证频繁,请稍后再试").asJsonString());

View File

@ -1,11 +1,13 @@
package com.example.controller;
import com.example.entity.RestBean;
import com.example.entity.dto.Account;
import com.example.entity.dto.Interact;
import com.example.entity.vo.request.AddCommentVO;
import com.example.entity.vo.request.TopicCreateVO;
import com.example.entity.vo.request.TopicUpdateVO;
import com.example.entity.vo.response.*;
import com.example.service.AccountService;
import com.example.service.TopicService;
import com.example.service.WeatherService;
import com.example.utils.Const;
@ -32,6 +34,9 @@ public class ForumController {
@Resource
ControllerUtils utils;
@Resource
AccountService accountService;
@GetMapping("/weather")
public RestBean<WeatherVO> weather(double longitude, double latitude){
WeatherVO vo = service.fetchWeather(longitude, latitude);
@ -51,6 +56,10 @@ public class ForumController {
@PostMapping("/create-topic")
public RestBean<Void> createTopic(@Valid @RequestBody TopicCreateVO vo,
@RequestAttribute(Const.ATTR_USER_ID) int id) {
Account account = accountService.findAccountById(id);
if(account.isMute()) {
return RestBean.forbidden("您已被禁言,无法创建新的主题");
}
return utils.messageHandle(() -> topicService.createTopic(id, vo));
}
@ -94,6 +103,10 @@ public class ForumController {
@PostMapping("/add-comment")
public RestBean<Void> addComment(@Valid @RequestBody AddCommentVO vo,
@RequestAttribute(Const.ATTR_USER_ID) int id){
Account account = accountService.findAccountById(id);
if(account.isMute()) {
return RestBean.forbidden("您已被禁言,无法创建新的回复");
}
return utils.messageHandle(() -> topicService.createComment(id, vo));
}

View File

@ -10,11 +10,15 @@ import com.example.entity.vo.response.AccountVO;
import com.example.service.AccountDetailsService;
import com.example.service.AccountPrivacyService;
import com.example.service.AccountService;
import com.example.utils.Const;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/api/admin/user")
@ -29,6 +33,12 @@ public class AccountAdminController {
@Resource
AccountPrivacyService privacyService;
@Resource
StringRedisTemplate template;
@Value("${spring.security.jwt.expire}")
private int expire;
@GetMapping("/list")
public RestBean<JSONObject> accountList(int page, int size) {
JSONObject object = new JSONObject();
@ -55,6 +65,7 @@ public class AccountAdminController {
int id = object.getInteger("id");
Account account = service.findAccountById(id);
Account save = object.toJavaObject(Account.class);
handleBanned(account, save);
BeanUtils.copyProperties(save, account, "password", "registerTime");
service.saveOrUpdate(account);
AccountDetails details = detailsService.findAccountDetailsById(id);
@ -67,4 +78,13 @@ public class AccountAdminController {
privacyService.saveOrUpdate(savePrivacy);
return RestBean.success();
}
private void handleBanned(Account old, Account current) {
String key = Const.BANNED_BLOCK + old.getId();
if(!old.isBanned() && current.isBanned()) {
template.opsForValue().set(key, "true", expire, TimeUnit.HOURS);
} else if(old.isBanned() && !current.isBanned()) {
template.delete(key);
}
}
}

View File

@ -8,6 +8,7 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
@ -27,6 +28,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Resource
JwtUtils utils;
@Resource
StringRedisTemplate template;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
@ -35,11 +39,15 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
DecodedJWT jwt = utils.resolveJwt(authorization);
if(jwt != null) {
UserDetails user = utils.toUser(jwt);
if(!template.hasKey(Const.BANNED_BLOCK + utils.toId(jwt))) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
request.setAttribute(Const.ATTR_USER_ID, utils.toId(jwt));
} else {
utils.invalidateJwt(authorization);
}
}
filterChain.doFilter(request, response);
}

View File

@ -10,6 +10,7 @@ public final class Const {
//请求频率限制
public final static String FLOW_LIMIT_COUNTER = "flow:counter:";
public final static String FLOW_LIMIT_BLOCK = "flow:block:";
public final static String BANNED_BLOCK = "banned:block:";
//邮件验证码
public final static String VERIFY_EMAIL_LIMIT = "verify:email:limit:";
public final static String VERIFY_EMAIL_DATA = "verify:email:data:";