Merge remote-tracking branch 'origin/master' into feature/update-dify
This commit is contained in:
commit
95f80df743
16
pom.xml
16
pom.xml
@ -132,6 +132,22 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||||
|
<!-- <artifactId>spring-boot-starter-data-r2dbc</artifactId>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>pro.chenggang</groupId>-->
|
||||||
|
<!-- <artifactId>mybatis-r2dbc-spring</artifactId>-->
|
||||||
|
<!-- <version>3.0.6.RELEASE</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>pro.chenggang</groupId>-->
|
||||||
|
<!-- <artifactId>mybatis-r2dbc</artifactId>-->
|
||||||
|
<!-- <version>3.0.6.RELEASE</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
@ -6,6 +6,7 @@ import jakarta.servlet.ServletException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||||
@ -38,11 +39,10 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler {
|
|||||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||||
result = new ExceptionResult("凭证已过期,请重新登录", HttpStatus.UNAUTHORIZED.value(),
|
result = new ExceptionResult("凭证已过期,请重新登录", HttpStatus.UNAUTHORIZED.value(),
|
||||||
LocalDateTime.now());
|
LocalDateTime.now());
|
||||||
} else if (ex instanceof AuthorizationDeniedException) {
|
// } else if (ex instanceof AuthorizationDeniedException) {
|
||||||
// 会话已存在,禁止重复登录,返回401
|
// response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
// result = new ExceptionResult("权限不足", HttpStatus.FORBIDDEN.value(),
|
||||||
result = new ExceptionResult("当前账号已在其他设备登录,请先退出再尝试登录", HttpStatus.UNAUTHORIZED.value(),
|
// LocalDateTime.now());
|
||||||
LocalDateTime.now());
|
|
||||||
} else {
|
} else {
|
||||||
// 403
|
// 403
|
||||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||||
|
@ -9,6 +9,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,8 +27,9 @@ public class CustomSessionInformationExpiredStrategy implements SessionInformati
|
|||||||
response.getWriter().print(objectMapper.writeValueAsString(Map.of(
|
response.getWriter().print(objectMapper.writeValueAsString(Map.of(
|
||||||
"msg", "会话已过期(有可能是您同时登录了太多的客户端)",
|
"msg", "会话已过期(有可能是您同时登录了太多的客户端)",
|
||||||
"code", HttpStatus.UNAUTHORIZED.value(),
|
"code", HttpStatus.UNAUTHORIZED.value(),
|
||||||
"timestamp", LocalDateTime.now()
|
"timestamp", new Date()
|
||||||
)));
|
)));
|
||||||
|
|
||||||
response.flushBuffer();
|
response.flushBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,8 @@ import org.springframework.security.authentication.ProviderManager;
|
|||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
|
||||||
|
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||||
import org.springframework.security.core.session.SessionRegistry;
|
import org.springframework.security.core.session.SessionRegistry;
|
||||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
@ -20,11 +22,13 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
|||||||
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
|
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
|
||||||
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
|
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
|
||||||
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
|
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
|
||||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||||
import org.springframework.security.web.session.HttpSessionEventPublisher;
|
import org.springframework.security.web.session.HttpSessionEventPublisher;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author harry_yao
|
* @author harry_yao
|
||||||
*/
|
*/
|
||||||
@ -39,7 +43,6 @@ public class SpringSecurityConfig {
|
|||||||
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
|
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
|
||||||
private final CustomAccessDeniedHandler customAccessDeniedHandler;
|
private final CustomAccessDeniedHandler customAccessDeniedHandler;
|
||||||
private final CustomSessionInformationExpiredStrategy customSessionInformationExpiredStrategy;
|
private final CustomSessionInformationExpiredStrategy customSessionInformationExpiredStrategy;
|
||||||
// private final SessionRegistry sessionRegistry;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
@ -63,7 +66,7 @@ public class SpringSecurityConfig {
|
|||||||
public ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy() {
|
public ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy() {
|
||||||
ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
|
ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
|
||||||
concurrentSessionControlAuthenticationStrategy.setMaximumSessions(1);
|
concurrentSessionControlAuthenticationStrategy.setMaximumSessions(1);
|
||||||
concurrentSessionControlAuthenticationStrategy.setExceptionIfMaximumExceeded(true);
|
concurrentSessionControlAuthenticationStrategy.setExceptionIfMaximumExceeded(false);
|
||||||
return concurrentSessionControlAuthenticationStrategy;
|
return concurrentSessionControlAuthenticationStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +129,7 @@ public class SpringSecurityConfig {
|
|||||||
.ignoringRequestMatchers("v1/**","/api/internal/**", "/api/rest/user/logout","/api/rest/user/register"))
|
.ignoringRequestMatchers("v1/**","/api/internal/**", "/api/rest/user/logout","/api/rest/user/register"))
|
||||||
.sessionManagement(session -> session
|
.sessionManagement(session -> session
|
||||||
.maximumSessions(1)
|
.maximumSessions(1)
|
||||||
.maxSessionsPreventsLogin(true)
|
.maxSessionsPreventsLogin(false)
|
||||||
.sessionRegistry(sessionRegistry())
|
.sessionRegistry(sessionRegistry())
|
||||||
.expiredSessionStrategy(customSessionInformationExpiredStrategy)
|
.expiredSessionStrategy(customSessionInformationExpiredStrategy)
|
||||||
).build();
|
).build();
|
||||||
|
@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yanghq
|
* @author yanghq
|
||||||
@ -45,6 +46,7 @@ public class V1ChatController {
|
|||||||
* apikey 建议在数据库进行存储,前端调用时传智能体 id,从数据库查询
|
* apikey 建议在数据库进行存储,前端调用时传智能体 id,从数据库查询
|
||||||
*/
|
*/
|
||||||
@PostMapping("/completions/{appId}")
|
@PostMapping("/completions/{appId}")
|
||||||
|
@PreAuthorize("hasAuthority('difyChat:query')")
|
||||||
@OperationLogAnnotation(content = "'dify对话'", operationType = "发送")
|
@OperationLogAnnotation(content = "'dify对话'", operationType = "发送")
|
||||||
public ChatMessageSendResponse sendChatMessage(
|
public ChatMessageSendResponse sendChatMessage(
|
||||||
@RequestBody ChatMessageSendRequest sendRequest,
|
@RequestBody ChatMessageSendRequest sendRequest,
|
||||||
@ -125,11 +127,12 @@ public class V1ChatController {
|
|||||||
*/
|
*/
|
||||||
@DeleteMapping("/conversation")
|
@DeleteMapping("/conversation")
|
||||||
@OperationLogAnnotation(content = "'dify对话'", operationType = "删除")
|
@OperationLogAnnotation(content = "'dify对话'", operationType = "删除")
|
||||||
public void deleteConversation(@RequestParam String conversationId, @RequestParam String appId) {
|
public Map<String, String> deleteConversation(@RequestParam String conversationId, @RequestParam String appId) {
|
||||||
String apiKey = appEntityService.getApikey(appId);
|
String apiKey = appEntityService.getApikey(appId);
|
||||||
String userId = SecurityUtil.getUserInfo().id.toString();
|
String userId = SecurityUtil.getUserInfo().id.toString();
|
||||||
try{
|
try{
|
||||||
difyChat.deleteConversation(conversationId, apiKey, userId);
|
difyChat.deleteConversation(conversationId, apiKey, userId);
|
||||||
|
return Map.of("message", "删除成功");
|
||||||
}catch (RuntimeException e){
|
}catch (RuntimeException e){
|
||||||
throw new ApiException("删除会话失败"+e.getMessage());
|
throw new ApiException("删除会话失败"+e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -139,4 +139,9 @@ public class V1ServerController {
|
|||||||
ResponseEntity.ok("关联成功") :
|
ResponseEntity.ok("关联成功") :
|
||||||
ResponseEntity.status(HttpStatus.BAD_REQUEST).body("关联失败");
|
ResponseEntity.status(HttpStatus.BAD_REQUEST).body("关联失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/link/{workflowId}")
|
||||||
|
public List<WorkflowDept> linked(@PathVariable String workflowId) {
|
||||||
|
return workflowDeptService.lambdaQuery().eq(WorkflowDept::getWorkflowId, workflowId).list();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public class OperationController {
|
|||||||
* 获取操作日志详情
|
* 获取操作日志详情
|
||||||
*/
|
*/
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
@PreAuthorize("hasAuthority('operationLog:query')")
|
@PreAuthorize("hasAuthority('system:operationLog:query')")
|
||||||
public OperationLog crate(@PathVariable("id") Long id) {
|
public OperationLog crate(@PathVariable("id") Long id) {
|
||||||
return repo.selectById(id);
|
return repo.selectById(id);
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ public class OperationController {
|
|||||||
* 获取操作日志分页
|
* 获取操作日志分页
|
||||||
*/
|
*/
|
||||||
@GetMapping("")
|
@GetMapping("")
|
||||||
@PreAuthorize("hasAuthority('operationLog:query')")
|
@PreAuthorize("hasAuthority('system:operationLog:query')")
|
||||||
public Page<OperationLog> query(Page<OperationLog> page, OperationLogQuery query) {
|
public Page<OperationLog> query(Page<OperationLog> page, OperationLogQuery query) {
|
||||||
return repo.selectPage(page, query.wrapper());
|
return repo.selectPage(page, query.wrapper());
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ public class OperationController {
|
|||||||
* 批量删除操作日志
|
* 批量删除操作日志
|
||||||
*/
|
*/
|
||||||
@DeleteMapping("/batch")
|
@DeleteMapping("/batch")
|
||||||
@PreAuthorize("hasAuthority('operationLog:delete')")
|
@PreAuthorize("hasAuthority('system:operationLog:delete')")
|
||||||
public int deleteBatch(@RequestBody List<Long> ids) {
|
public int deleteBatch(@RequestBody List<Long> ids) {
|
||||||
LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.in(OperationLog::getId, ids);
|
wrapper.in(OperationLog::getId, ids);
|
||||||
|
Loading…
Reference in New Issue
Block a user