优化
This commit is contained in:
@@ -66,6 +66,25 @@ class PlatformTenantControllerContractTest {
|
||||
returnType.getActualTypeArguments()[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExposeCustomerOwnerPasswordResetWithDedicatedPermission() throws Exception {
|
||||
Method method = PlatformTenantController.class.getMethod("resetOwnerPassword", long.class,
|
||||
com.baiyue.iam.dto.TenantDtos.ResetCustomerOwnerPasswordRequest.class, AuthenticatedUser.class);
|
||||
assertEquals("/tenants/{tenantId:\\d+}/owner/password", method.getAnnotation(org.springframework.web.bind.annotation.PutMapping.class).value()[0]);
|
||||
assertEquals("hasAuthority('platform:customer:reset-password')", method.getAnnotation(PreAuthorize.class).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExposeArchiveAndImpersonationWithDedicatedPermissions() throws Exception {
|
||||
Method archive = PlatformTenantController.class.getMethod("archive", long.class, AuthenticatedUser.class);
|
||||
assertEquals("/tenants/{tenantId:\\d+}/archive", archive.getAnnotation(org.springframework.web.bind.annotation.PostMapping.class).value()[0]);
|
||||
assertEquals("hasAuthority('platform:customer:delete')", archive.getAnnotation(PreAuthorize.class).value());
|
||||
Method impersonation = PlatformTenantController.class.getMethod("createImpersonation", long.class,
|
||||
com.baiyue.iam.dto.TenantDtos.CustomerImpersonationRequest.class, AuthenticatedUser.class);
|
||||
assertEquals("/tenants/{tenantId:\\d+}/impersonation", impersonation.getAnnotation(org.springframework.web.bind.annotation.PostMapping.class).value()[0]);
|
||||
assertEquals("hasAuthority('platform:customer:impersonate')", impersonation.getAnnotation(PreAuthorize.class).value());
|
||||
}
|
||||
|
||||
private <T extends Annotation> T annotation(Method method, int parameter, Class<T> type) {
|
||||
return method.getParameters()[parameter].getAnnotation(type);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ import com.baiyue.iam.dto.TenantDtos.UpdateProfileRequest;
|
||||
import com.baiyue.iam.dto.TenantDtos.RegisterRequest;
|
||||
import com.baiyue.iam.entity.IamTenantQualification;
|
||||
import com.baiyue.iam.entity.IamTenantReview;
|
||||
import com.baiyue.iam.entity.IamMembership;
|
||||
import com.baiyue.iam.entity.IamUser;
|
||||
import com.baiyue.iam.dto.TenantDtos.ResetCustomerOwnerPasswordRequest;
|
||||
import com.baiyue.iam.dto.TenantDtos.CustomerImpersonationRequest;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.iam.repository.TenantRepository;
|
||||
import com.baiyue.iam.repository.ProfileResourceRepository;
|
||||
import com.baiyue.iam.repository.MemberRepository;
|
||||
@@ -137,6 +142,57 @@ class TenantServiceTest {
|
||||
verify(authClient).availability("internal-token", "13800138000");
|
||||
}
|
||||
|
||||
@Test
|
||||
void resetOwnerPasswordResolvesOwnerAuthAccountAndForwardsForceChangeFlag() {
|
||||
when(repository.findTenant(10001L)).thenReturn(merchant(10001L, "ACTIVE"));
|
||||
IamMembership owner = new IamMembership(); owner.setId(70L); owner.setTenantId(10001L);
|
||||
owner.setUserId(71L); owner.setMemberType("OWNER"); owner.setStatus("ACTIVE");
|
||||
IamUser user = new IamUser(); user.setId(71L); user.setAuthUserId(72L); user.setStatus("ACTIVE");
|
||||
when(members.findOwnerByTenant(10001L)).thenReturn(owner);
|
||||
when(members.findUser(71L)).thenReturn(user);
|
||||
when(authClient.reset(eq("internal-token"), eq(72L), any(AuthAccountClient.PasswordRequest.class)))
|
||||
.thenReturn(com.baiyue.common.core.api.ApiResponse.success(null));
|
||||
|
||||
service.resetOwnerPassword(10001L, new ResetCustomerOwnerPasswordRequest("NewPass2", null));
|
||||
|
||||
verify(authClient).reset(eq("internal-token"), eq(72L),
|
||||
argThat(request -> request.forceChangePassword() && "NewPass2".equals(request.newPassword())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void archiveIsIdempotentForDisabledCustomerWithoutCallingAuth() {
|
||||
IamTenant tenant = merchant(10001L, "DISABLED");
|
||||
when(repository.findTenantForUpdate(10001L)).thenReturn(tenant);
|
||||
|
||||
assertEquals("DISABLED", service.archiveMerchant(10001L).status());
|
||||
verify(authClient, never()).archiveTenant(any(), any());
|
||||
verify(repository, never()).saveTenant(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void impersonationTicketUsesActiveOwnerAndCurrentPlatformActor() {
|
||||
when(repository.findTenant(10001L)).thenReturn(merchant(10001L, "ACTIVE"));
|
||||
IamMembership owner = new IamMembership(); owner.setId(70L); owner.setTenantId(10001L);
|
||||
owner.setUserId(71L); owner.setMemberType("OWNER"); owner.setStatus("ACTIVE");
|
||||
IamUser user = new IamUser(); user.setId(71L); user.setAuthUserId(72L); user.setStatus("ACTIVE");
|
||||
when(members.findOwnerByTenant(10001L)).thenReturn(owner);
|
||||
when(members.findUser(71L)).thenReturn(user);
|
||||
when(authClient.createImpersonationTicket(eq("internal-token"), any(AuthAccountClient.ImpersonationTicketRequest.class)))
|
||||
.thenReturn(com.baiyue.common.core.api.ApiResponse.success(
|
||||
new AuthAccountClient.ImpersonationTicketResponse("one-time-code", "ticket-1", 60)));
|
||||
AuthenticatedUser actor = new AuthenticatedUser(9001L, 0L, 0L, 9002L,
|
||||
"operator", "PLATFORM", "WEB", java.util.Set.of("platform:customer:impersonate"));
|
||||
|
||||
var result = service.createImpersonationTicket(10001L,
|
||||
new CustomerImpersonationRequest("support investigation"), actor);
|
||||
|
||||
assertEquals("one-time-code", result.code());
|
||||
verify(authClient).createImpersonationTicket(eq("internal-token"), argThat(request ->
|
||||
request.targetAuthUserId().equals(72L) && request.tenantId().equals(10001L)
|
||||
&& request.membershipId().equals(70L) && request.actorUserId().equals(9001L)
|
||||
&& request.actorMembershipId().equals(9002L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformCannotBypassReviewToActivatePendingTenant() {
|
||||
when(repository.findTenant(10001L)).thenReturn(merchant(10001L, "PENDING"));
|
||||
|
||||
Reference in New Issue
Block a user