优化
This commit is contained in:
@@ -83,6 +83,7 @@ public class PlatformMeasurementImageController {
|
||||
|
||||
private long requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equalsIgnoreCase(user.appCode())
|
||||
|| user.tenantId() == null || user.tenantId() != 0L
|
||||
|| user.userId() == null || user.userId() <= 0) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "需要平台端身份");
|
||||
}
|
||||
|
||||
+11
-1
@@ -47,6 +47,7 @@ public class PlatformQualificationFileController {
|
||||
@RequestParam(required = false) LocalDate validTo,
|
||||
@RequestParam(defaultValue = "false") boolean replace) {
|
||||
requirePlatform(user);
|
||||
requireCustomer(tenantId);
|
||||
qualificationType = QualificationTypes.requireOptional(qualificationType);
|
||||
var stored = storage.store(tenantId, file);
|
||||
try {
|
||||
@@ -94,6 +95,7 @@ public class PlatformQualificationFileController {
|
||||
@RequestParam(defaultValue = "false") boolean replaceBusinessLicense,
|
||||
@RequestParam(defaultValue = "false") boolean replaceLegalPersonId) {
|
||||
requirePlatform(user);
|
||||
requireCustomer(tenantId);
|
||||
return ApiResponse.success(packageService.upload(tenantId, businessLicense, legalPersonId,
|
||||
unifiedSocialCreditCode, businessLicenseValidTo, legalPersonIdValidTo,
|
||||
replaceBusinessLicense, replaceLegalPersonId, true));
|
||||
@@ -105,6 +107,7 @@ public class PlatformQualificationFileController {
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable long tenantId, @PathVariable String fileName) {
|
||||
requirePlatform(user);
|
||||
requireCustomer(tenantId);
|
||||
var resource = storage.load(tenantId, fileName);
|
||||
String mediaType = fileName.endsWith(".png") ? MediaType.IMAGE_PNG_VALUE
|
||||
: (fileName.endsWith(".pdf") ? MediaType.APPLICATION_PDF_VALUE : MediaType.IMAGE_JPEG_VALUE);
|
||||
@@ -113,8 +116,15 @@ public class PlatformQualificationFileController {
|
||||
}
|
||||
|
||||
private void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equalsIgnoreCase(user.appCode())) {
|
||||
if (user == null || !"PLATFORM".equalsIgnoreCase(user.appCode())
|
||||
|| user.tenantId() == null || user.tenantId() != 0L) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "Platform identity is required");
|
||||
}
|
||||
}
|
||||
|
||||
private void requireCustomer(long tenantId) {
|
||||
if (tenantId <= 0L) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "Customer identity must be positive");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ public class ExportTaskService {
|
||||
|
||||
private void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || user.userId() == null || user.tenantId() == null
|
||||
|| !"PLATFORM".equalsIgnoreCase(user.appCode())) {
|
||||
|| user.tenantId() != 0L || !"PLATFORM".equalsIgnoreCase(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "Platform identity is required");
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -61,4 +61,14 @@ class PlatformMeasurementImageControllerContractTest {
|
||||
|
||||
verify(images).download(10001L, 88L, 99L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsPlatformTokenWithCustomerTenantScope() {
|
||||
var file = new MockMultipartFile("file", "weight.png", MediaType.IMAGE_PNG_VALUE, new byte[]{1});
|
||||
var malformed = new AuthenticatedUser(1L, 10001L, 10001L, 1L,
|
||||
"admin", "PLATFORM", "WEB", Set.of());
|
||||
|
||||
assertThatThrownBy(() -> controller.upload(malformed, 10001L, 88L, file))
|
||||
.isInstanceOf(BizException.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,32 @@ class QualificationFileContractTest {
|
||||
assertEquals("hasAuthority('platform:customer:view')", method.getAnnotation(PreAuthorize.class).value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformQualificationRejectsCustomerScopedPlatformToken() {
|
||||
var storage = mock(LocalQualificationStorage.class);
|
||||
var controller = platformController(storage, mock(IamQualificationClient.class));
|
||||
var file = new MockMultipartFile("file", "license.pdf", "application/pdf", "%PDF-1.4".getBytes());
|
||||
var malformed = new AuthenticatedUser(1L, 10001L, 10001L, 1L,
|
||||
"admin", "PLATFORM", "WEB", Set.of());
|
||||
|
||||
assertThrows(BizException.class,
|
||||
() -> controller.upload(malformed, 10001L, file,
|
||||
"BANK_ACCOUNT_LICENSE", null, null, false));
|
||||
verify(storage, never()).store(any(Long.class), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformQualificationRejectsPlatformScopeAsCustomerTarget() {
|
||||
var storage = mock(LocalQualificationStorage.class);
|
||||
var controller = platformController(storage, mock(IamQualificationClient.class));
|
||||
var file = new MockMultipartFile("file", "license.pdf", "application/pdf", "%PDF-1.4".getBytes());
|
||||
|
||||
assertThrows(BizException.class,
|
||||
() -> controller.upload(platformUser(), 0L, file,
|
||||
"BANK_ACCOUNT_LICENSE", null, null, false));
|
||||
verify(storage, never()).store(any(Long.class), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformReplacementIsForwardedAndCleansThePreviousFileAfterIamSucceeds() {
|
||||
var storage = mock(LocalQualificationStorage.class);
|
||||
|
||||
@@ -74,6 +74,16 @@ class ExportTaskServiceTest {
|
||||
assertEquals(ResultCode.VALIDATION_FAILED,error.getResultCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsPlatformTokenWithCustomerTenantScope() {
|
||||
var malformed = new AuthenticatedUser(1L, 10001L, 10001L, 1L,
|
||||
"user1", "PLATFORM", "WEB", Set.of("platform:customer:export"));
|
||||
assertEquals(ResultCode.FORBIDDEN, assertThrows(BizException.class,
|
||||
() -> service.create(malformed,
|
||||
new CreateExportTaskRequest("CUSTOMER_LIST", "XLSX", "客户列表", Map.of())))
|
||||
.getResultCode());
|
||||
}
|
||||
|
||||
private AuthenticatedUser user(long id, Set<String> permissions) {
|
||||
return new AuthenticatedUser(id, 0L, 0L, id, "user" + id, "PLATFORM", "WEB", permissions);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ package com.baiyue.file.service;
|
||||
import com.baiyue.file.client.WeightOcrClient;
|
||||
import com.baiyue.file.entity.FileObjectEntity;
|
||||
import com.baiyue.file.mapper.FileObjectMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -28,6 +33,14 @@ class MeasurementImageServiceEvidenceTest {
|
||||
@MockBean private FileObjectMapper files;
|
||||
@MockBean private WeightOcrClient ocr;
|
||||
@Resource private MeasurementImageService service;
|
||||
|
||||
@BeforeAll
|
||||
static void initializeEntityMetadata() {
|
||||
TableInfoHelper.initTableInfo(
|
||||
new MapperBuilderAssistant(new MybatisConfiguration(), "measurement-image-test"),
|
||||
FileObjectEntity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleCase01() {
|
||||
var image = new MockMultipartFile("file", "measure.png", MediaType.IMAGE_PNG_VALUE,
|
||||
@@ -62,4 +75,20 @@ class MeasurementImageServiceEvidenceTest {
|
||||
.hasMessageContaining("不执行重量OCR");
|
||||
verifyNoInteractions(ocr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void refusesAFileTupleFromAnotherCustomer() {
|
||||
when(files.selectOne(any())).thenAnswer(invocation -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
LambdaQueryWrapper<FileObjectEntity> query = invocation.getArgument(0);
|
||||
query.getSqlSegment();
|
||||
assertThat(query.getParamNameValuePairs().values())
|
||||
.contains(11L, 41L, "21", false);
|
||||
return null;
|
||||
});
|
||||
|
||||
assertThatThrownBy(() -> service.download(11L, 21L, 41L))
|
||||
.isInstanceOf(com.baiyue.common.core.exception.BizException.class);
|
||||
verifyNoInteractions(storage);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user