This commit is contained in:
YunaiV 2025-08-24 10:39:00 +08:00
commit c647a4fb9d
11 changed files with 29 additions and 17 deletions

View File

@ -31,7 +31,7 @@
<mybatis-plus-join.version>1.5.4</mybatis-plus-join.version> <mybatis-plus-join.version>1.5.4</mybatis-plus-join.version>
<dynamic-datasource.version>4.3.1</dynamic-datasource.version> <dynamic-datasource.version>4.3.1</dynamic-datasource.version>
<easy-trans.version>3.0.6</easy-trans.version> <easy-trans.version>3.0.6</easy-trans.version>
<redisson.version>3.41.0</redisson.version> <redisson.version>3.50.0</redisson.version>
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version> <dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
<kingbase.jdbc.version>8.6.0</kingbase.jdbc.version> <kingbase.jdbc.version>8.6.0</kingbase.jdbc.version>
<opengauss.jdbc.version>5.1.0</opengauss.jdbc.version> <opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>

View File

@ -101,13 +101,14 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
} }
private boolean isIgnoreUrl(HttpServletRequest request) { private boolean isIgnoreUrl(HttpServletRequest request) {
String apiUri = request.getRequestURI().substring(request.getContextPath().length());
// 快速匹配保证性能 // 快速匹配保证性能
if (CollUtil.contains(tenantProperties.getIgnoreUrls(), request.getRequestURI())) { if (CollUtil.contains(tenantProperties.getIgnoreUrls(), apiUri)) {
return true; return true;
} }
// 逐个 Ant 路径匹配 // 逐个 Ant 路径匹配
for (String url : tenantProperties.getIgnoreUrls()) { for (String url : tenantProperties.getIgnoreUrls()) {
if (pathMatcher.match(url, request.getRequestURI())) { if (pathMatcher.match(url, apiUri)) {
return true; return true;
} }
} }

View File

@ -29,6 +29,11 @@ public class BpmProcessInstanceStatusEvent extends ApplicationEvent {
*/ */
@NotNull(message = "流程实例的状态不能为空") @NotNull(message = "流程实例的状态不能为空")
private Integer status; private Integer status;
/**
* 流程实例结束的原因
*/
private String reason;
/** /**
* 流程实例对应的业务标识 * 流程实例对应的业务标识
* 例如说请假 * 例如说请假

View File

@ -119,8 +119,9 @@ public interface BpmProcessInstanceConvert {
@Mapping(source = "from.id", target = "to.id", ignore = true) @Mapping(source = "from.id", target = "to.id", ignore = true)
void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to); void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to);
default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) { default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance,
return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status) Integer status, String reason) {
return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status).setReason(reason)
.setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey()); .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey());
} }

View File

@ -960,7 +960,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
// 3. 发送流程实例的状态事件 // 3. 发送流程实例的状态事件
processInstanceEventPublisher.sendProcessInstanceResultEvent( processInstanceEventPublisher.sendProcessInstanceResultEvent(
BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status)); BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status, reason));
// 4. 流程后置通知 // 4. 流程后置通知
if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) { if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {

View File

@ -35,6 +35,14 @@ tenant-id: {{adminTenantId}}
grant_type=password&username=admin&password=admin123&scope=user.read grant_type=password&username=admin&password=admin123&scope=user.read
### 请求 /system/oauth2/token + client_credentials 接口 => 成功
POST {{baseUrl}}/system/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
tenant-id: {{adminTenantId}}
grant_type=client_credentials&scope=user.read
### 请求 /system/oauth2/token + refresh_token 接口 => 成功 ### 请求 /system/oauth2/token + refresh_token 接口 => 成功
POST {{baseUrl}}/system/oauth2/token POST {{baseUrl}}/system/oauth2/token
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded

View File

@ -94,6 +94,7 @@ public class OAuth2OpenController {
@Parameter(name = "scope", example = "user_info"), @Parameter(name = "scope", example = "user_info"),
@Parameter(name = "refresh_token", example = "123424233"), @Parameter(name = "refresh_token", example = "123424233"),
}) })
@SuppressWarnings("EnhancedSwitchMigration")
public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request, public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request,
@RequestParam("grant_type") String grantType, @RequestParam("grant_type") String grantType,
@RequestParam(value = "code", required = false) String code, // 授权码模式 @RequestParam(value = "code", required = false) String code, // 授权码模式

View File

@ -86,8 +86,8 @@ public class OAuth2GrantServiceImpl implements OAuth2GrantService {
@Override @Override
public OAuth2AccessTokenDO grantClientCredentials(String clientId, List<String> scopes) { public OAuth2AccessTokenDO grantClientCredentials(String clientId, List<String> scopes) {
// TODO 芋艿项目中使用 OAuth2 解决的是三方应用的授权内部的 SSO 等问题所以暂时不考虑 client_credentials 这个场景 // 特殊https://yuanbao.tencent.com/bot/app/share/chat/wFj642xSZHHx
throw new UnsupportedOperationException("暂时不支持 client_credentials 授权模式"); return oauth2TokenService.createAccessToken(0L, UserTypeEnum.ADMIN.getValue(), clientId, scopes);
} }
@Override @Override

View File

@ -197,6 +197,9 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
* @return 用户信息 * @return 用户信息
*/ */
private Map<String, String> buildUserInfo(Long userId, Integer userType) { private Map<String, String> buildUserInfo(Long userId, Integer userType) {
if (userId == null || userId <= 0) {
return Collections.emptyMap();
}
if (userType.equals(UserTypeEnum.ADMIN.getValue())) { if (userType.equals(UserTypeEnum.ADMIN.getValue())) {
AdminUserDO user = adminUserService.getUser(userId); AdminUserDO user = adminUserService.getUser(userId);
return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname()) return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname())
@ -205,7 +208,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
// 注意目前 Member 暂时不读取可以按需实现 // 注意目前 Member 暂时不读取可以按需实现
return Collections.emptyMap(); return Collections.emptyMap();
} }
return null; throw new IllegalArgumentException("未知用户类型:" + userType);
} }
private static String generateAccessToken() { private static String generateAccessToken() {

View File

@ -16,7 +16,6 @@ import java.util.List;
import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static java.util.Collections.emptyList;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -135,13 +134,6 @@ public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest {
refreshToken, clientId)); refreshToken, clientId));
} }
@Test
public void testGrantClientCredentials() {
assertThrows(UnsupportedOperationException.class,
() -> oauth2GrantService.grantClientCredentials(randomString(), emptyList()),
"暂时不支持 client_credentials 授权模式");
}
@Test @Test
public void testRevokeToken_clientIdError() { public void testRevokeToken_clientIdError() {
// 准备参数 // 准备参数

View File

@ -236,6 +236,7 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
public void testCheckAccessToken_refreshToken() { public void testCheckAccessToken_refreshToken() {
// mock 数据访问令牌 // mock 数据访问令牌
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class) OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
.setUserId(0L)
.setExpiresTime(LocalDateTime.now().plusDays(1)); .setExpiresTime(LocalDateTime.now().plusDays(1));
oauth2RefreshTokenMapper.insert(refreshTokenDO); oauth2RefreshTokenMapper.insert(refreshTokenDO);
// 准备参数 // 准备参数