优化
This commit is contained in:
@@ -19,6 +19,10 @@ public interface AuthorizationQueryMapper {
|
||||
AND u.status = 'ACTIVE' AND u.deleted = 0
|
||||
AND m.id = #{membershipId} AND m.tenant_id = #{tenantId}
|
||||
AND m.status = 'ACTIVE' AND m.deleted = 0
|
||||
AND (m.tenant_id = 0 OR EXISTS (
|
||||
SELECT 1 FROM iam_tenant t WHERE t.id = m.tenant_id AND t.deleted = 0
|
||||
AND t.status IN ('ACTIVE', 'PROFILE_REQUIRED', 'PENDING', 'REJECTED')
|
||||
))
|
||||
""")
|
||||
int countActiveIdentity(@Param("userId") long userId,
|
||||
@Param("tenantId") long tenantId,
|
||||
|
||||
@@ -165,7 +165,7 @@ public class PlatformUserManagementService {
|
||||
members.save(membership);
|
||||
if (scopeChanged) members.replaceRoles(oldTenantId, membershipId, List.of());
|
||||
members.replaceRoles(newTenantId, membershipId, roleIds);
|
||||
if ((rolesChanged || warehouseChanged) && !profileChanged && !scopeChanged) {
|
||||
if ((rolesChanged || warehouseChanged) && !scopeChanged) {
|
||||
call(() -> authClient.revokeSessions(internalToken,
|
||||
new AuthAccountClient.RevokeAccountSessionsRequest(Set.of(user.getAuthUserId()))));
|
||||
}
|
||||
|
||||
@@ -423,10 +423,30 @@ public class TenantService {
|
||||
}
|
||||
tenant.setStatus(request.status());
|
||||
repository.saveTenant(tenant);
|
||||
revokeMerchantSessions(tenantId);
|
||||
securityEvents.tenantStatus(tenantId, request.status());
|
||||
return response(tenant);
|
||||
}
|
||||
|
||||
private void revokeMerchantSessions(long tenantId) {
|
||||
List<Long> accounts = memberRepository.findByTenant(tenantId).stream()
|
||||
.map(member -> memberRepository.findUser(member.getUserId()))
|
||||
.filter(java.util.Objects::nonNull).map(IamUser::getAuthUserId)
|
||||
.filter(java.util.Objects::nonNull).distinct().toList();
|
||||
for (int start = 0; start < accounts.size(); start += 200) {
|
||||
Set<Long> batch = Set.copyOf(accounts.subList(start, Math.min(start + 200, accounts.size())));
|
||||
try {
|
||||
ApiResponse<Void> result = authClient.revokeSessions(internalToken,
|
||||
new AuthAccountClient.RevokeAccountSessionsRequest(batch));
|
||||
if (result == null || !result.successful()) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "客户会话撤销失败,请重试");
|
||||
}
|
||||
} catch (FeignException exception) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "客户会话撤销失败,请重试");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@BusinessAudit(event = "PLATFORM_TENANT_SUBMIT_REVIEW", resourceType = "TENANT", resourceId = "#tenantId",
|
||||
description = "平台提交企业客户审核")
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.baiyue.iam.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import java.util.UUID;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class AuthorizationIdentitySqlTest {
|
||||
@Test
|
||||
void disabledArchivedDeletedOrMissingCustomerCannotGetNewAuthorizationSnapshot() throws Exception {
|
||||
var jdbc = new JdbcTemplate(new DriverManagerDataSource("jdbc:h2:mem:" + UUID.randomUUID() + ";DB_CLOSE_DELAY=-1", "sa", ""));
|
||||
jdbc.execute("CREATE TABLE iam_user(id BIGINT, auth_user_id BIGINT, status VARCHAR(30), deleted INT)");
|
||||
jdbc.execute("CREATE TABLE iam_membership(id BIGINT, user_id BIGINT, tenant_id BIGINT, status VARCHAR(30), deleted INT)");
|
||||
jdbc.execute("CREATE TABLE iam_tenant(id BIGINT, status VARCHAR(30), deleted INT)");
|
||||
jdbc.update("INSERT INTO iam_user VALUES(1,42,'ACTIVE',0)");
|
||||
jdbc.update("INSERT INTO iam_membership VALUES(9,1,7,'ACTIVE',0)");
|
||||
jdbc.update("INSERT INTO iam_tenant VALUES(7,'ACTIVE',0)");
|
||||
String sql = String.join("\n", AuthorizationQueryMapper.class.getMethod("countActiveIdentity", long.class, long.class, long.class)
|
||||
.getAnnotation(Select.class).value()).replace("#{userId}", "42").replace("#{membershipId}", "9").replace("#{tenantId}", "7");
|
||||
for (String status : new String[]{"ACTIVE", "PROFILE_REQUIRED", "PENDING", "REJECTED"}) {
|
||||
jdbc.update("UPDATE iam_tenant SET status=?", status);
|
||||
assertThat(jdbc.queryForObject(sql, Integer.class)).as(status).isEqualTo(1);
|
||||
}
|
||||
for (String status : new String[]{"DISABLED", "ARCHIVED", "UNKNOWN"}) {
|
||||
jdbc.update("UPDATE iam_tenant SET status=?", status);
|
||||
assertThat(jdbc.queryForObject(sql, Integer.class)).as(status).isZero();
|
||||
}
|
||||
jdbc.update("UPDATE iam_tenant SET status='ACTIVE', deleted=1");
|
||||
assertThat(jdbc.queryForObject(sql, Integer.class)).isZero();
|
||||
jdbc.update("DELETE FROM iam_tenant");
|
||||
assertThat(jdbc.queryForObject(sql, Integer.class)).isZero();
|
||||
jdbc.update("UPDATE iam_membership SET tenant_id=0");
|
||||
assertThat(jdbc.queryForObject(sql.replace("m.tenant_id = 7", "m.tenant_id = 0"), Integer.class)).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
@@ -201,6 +201,18 @@ class PlatformUserManagementServiceTest {
|
||||
"PLATFORM_USER_AUTHORIZATION_CHANGED");
|
||||
}
|
||||
|
||||
@Test
|
||||
void changingNameTogetherWithWarehouseStillRevokesSessions() {
|
||||
when(auth.profile(eq("internal-token"), eq(10L), any())).thenReturn(ApiResponse.success(null));
|
||||
platformRole.setRoleCode("OVERSEAS_WAREHOUSE_PDA_OPERATOR");
|
||||
membership.setOverseasWarehouseId(900L);
|
||||
service.update(30L, new UpdateUserRequest("新姓名", "13800138000", null,
|
||||
0L, List.of(40001L), 901L), Set.of("platform:user:grant-role"));
|
||||
verify(auth).profile(eq("internal-token"), eq(10L), any());
|
||||
verify(auth).revokeSessions(eq("internal-token"),
|
||||
eq(new AuthAccountClient.RevokeAccountSessionsRequest(Set.of(10L))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void clearingWarehouseBindingAlsoRevokesAllAuthSessions() {
|
||||
platformRole.setRoleCode("WAREHOUSE_OPERATOR");
|
||||
|
||||
@@ -181,6 +181,30 @@ class TenantServiceTest {
|
||||
verify(repository, org.mockito.Mockito.times(2)).saveTenant(tenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
void disablingCustomerRevokesEveryMemberAccountAndRejectsFailedRevocation() {
|
||||
IamTenant tenant = merchant(10001L, "ACTIVE");
|
||||
when(repository.findTenant(10001L)).thenReturn(tenant);
|
||||
IamMembership first = new IamMembership(); first.setUserId(1L);
|
||||
IamMembership second = new IamMembership(); second.setUserId(2L);
|
||||
IamUser firstUser = new IamUser(); firstUser.setAuthUserId(101L);
|
||||
IamUser secondUser = new IamUser(); secondUser.setAuthUserId(102L);
|
||||
when(members.findByTenant(10001L)).thenReturn(List.of(first, second));
|
||||
when(members.findUser(1L)).thenReturn(firstUser);
|
||||
when(members.findUser(2L)).thenReturn(secondUser);
|
||||
var request = new AuthAccountClient.RevokeAccountSessionsRequest(Set.of(101L, 102L));
|
||||
when(authClient.revokeSessions("internal-token", request)).thenReturn(null);
|
||||
assertThrows(BizException.class,
|
||||
() -> service.changeMerchantStatus(10001L, new ChangeTenantStatusRequest("DISABLED")));
|
||||
verify(securityEvents, never()).tenantStatus(org.mockito.ArgumentMatchers.anyLong(), any());
|
||||
|
||||
when(authClient.revokeSessions("internal-token", request))
|
||||
.thenReturn(com.baiyue.common.core.api.ApiResponse.success(null));
|
||||
assertEquals("DISABLED", service.changeMerchantStatus(10001L,
|
||||
new ChangeTenantStatusRequest("DISABLED")).status());
|
||||
verify(securityEvents).tenantStatus(10001L, "DISABLED");
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeCustomerCanChangeCompanyContactPhoneWithoutChangingAnyLoginIdentity() {
|
||||
IamTenant tenant = merchant(10001L, "ACTIVE");
|
||||
|
||||
Reference in New Issue
Block a user