feat(密钥管理): 列表按用户聚合三字段列 + 代理配置服务端上报
- Java:后台列表一行一用户(货源查询密钥/外观专利密钥/代理设置),行级状态三项全通过才算通过;检测/清空改为按用户;搜索仅按用户名(去 UID);新增代理检测(经用户代理请求自家域名)与代理掩码(隐去账密) - 后台前端:三字段列改版 + 行级状态筛选 + 用户名筛选 - 桌面前端:登录加载密钥时补报本地代理(只填空缺不覆盖)、保存/清空代理实时上报
This commit is contained in:
+99
@@ -2,10 +2,13 @@ package com.nanri.aiimage.modules.usersecret.service;
|
||||
|
||||
import com.nanri.aiimage.common.security.ShopCredentialCryptoService;
|
||||
import com.nanri.aiimage.modules.permission.mapper.AdminUserMapper;
|
||||
import com.nanri.aiimage.modules.permission.model.entity.AdminUserEntity;
|
||||
import com.nanri.aiimage.modules.usersecret.client.JikipProxyClient;
|
||||
import com.nanri.aiimage.modules.usersecret.mapper.UserApiSecretMapper;
|
||||
import com.nanri.aiimage.modules.usersecret.model.dto.AdminUserSecretQuery;
|
||||
import com.nanri.aiimage.modules.usersecret.model.dto.UserApiSecretMigrateRequest;
|
||||
import com.nanri.aiimage.modules.usersecret.model.entity.UserApiSecretEntity;
|
||||
import com.nanri.aiimage.modules.usersecret.model.vo.AdminUserSecretModuleVo;
|
||||
import com.nanri.aiimage.modules.usersecret.model.vo.UserApiSecretBundleVo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -154,6 +157,102 @@ class UserApiSecretServiceTest {
|
||||
verify(mapper).delete(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void bundleExcludesProxyModule() {
|
||||
UserApiSecretService service = newService();
|
||||
when(mapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
UserApiSecretBundleVo bundle = service.bundle(7L);
|
||||
|
||||
assertThat(bundle.getItems()).extracting(item -> item.getModuleKey())
|
||||
.containsExactlyInAnyOrder("appearance-patent", "similar-asin");
|
||||
assertThat(bundle.getRequiredModules()).doesNotContain("proxy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveRejectsInvalidProxyUrl() {
|
||||
UserApiSecretService service = newService();
|
||||
|
||||
org.assertj.core.api.Assertions.assertThatThrownBy(() -> service.save(7L, "proxy", "1.2.3.4:8080"))
|
||||
.isInstanceOf(com.nanri.aiimage.common.exception.BusinessException.class)
|
||||
.hasMessageContaining("代理地址格式不正确");
|
||||
}
|
||||
|
||||
@Test
|
||||
void summarizeRequiresAllThreePassed() {
|
||||
UserApiSecretService service = newService();
|
||||
|
||||
assertThat(service.summarizeRowStatus(List.of(
|
||||
moduleVo(true, "passed"), moduleVo(true, "passed"), moduleVo(true, "passed")))
|
||||
).isEqualTo("passed");
|
||||
|
||||
assertThat(service.summarizeRowStatus(List.of(
|
||||
moduleVo(true, "passed"), moduleVo(false, "unknown"), moduleVo(true, "passed")))
|
||||
).isEqualTo("incomplete");
|
||||
|
||||
assertThat(service.summarizeRowStatus(List.of(
|
||||
moduleVo(true, "failed"), moduleVo(false, "unknown"), moduleVo(true, "passed")))
|
||||
).isEqualTo("failed");
|
||||
|
||||
assertThat(service.summarizeRowStatus(List.of(
|
||||
moduleVo(true, "passed"), moduleVo(true, "error"), moduleVo(true, "passed")))
|
||||
).isEqualTo("error");
|
||||
|
||||
assertThat(service.summarizeRowStatus(List.of(
|
||||
moduleVo(true, "passed"), moduleVo(true, "unknown"), moduleVo(true, "passed")))
|
||||
).isEqualTo("unknown");
|
||||
}
|
||||
|
||||
@Test
|
||||
void adminPageAggregatesOneRowPerUserWithProxyMasked() {
|
||||
UserApiSecretService service = newService();
|
||||
when(mapper.selectList(any())).thenReturn(List.of(
|
||||
row(1L, "similar-asin", "enc:sk-sa-1234", "passed"),
|
||||
row(1L, "appearance-patent", "enc:sk-ap-5678", "passed"),
|
||||
row(1L, "proxy", "enc:http://user:pass@1.2.3.4:8080", "failed")));
|
||||
AdminUserEntity user = new AdminUserEntity();
|
||||
user.setId(1L);
|
||||
user.setUsername("张三");
|
||||
when(adminUserMapper.selectById(1L)).thenReturn(user);
|
||||
|
||||
var page = service.adminPage(new AdminUserSecretQuery());
|
||||
|
||||
assertThat(page.getItems()).hasSize(1);
|
||||
var rowVo = page.getItems().get(0);
|
||||
assertThat(rowVo.getUsername()).isEqualTo("张三");
|
||||
assertThat(rowVo.getStatus()).isEqualTo("failed");
|
||||
assertThat(rowVo.getSimilarAsin().getMasked()).isEqualTo("sk-s****1234");
|
||||
assertThat(rowVo.getProxy().getExists()).isTrue();
|
||||
assertThat(rowVo.getProxy().getMasked()).isEqualTo("http://***@1.2.3.4:8080");
|
||||
}
|
||||
|
||||
@Test
|
||||
void adminClearByUserDeletesAllRowsOfUser() {
|
||||
UserApiSecretService service = newService();
|
||||
|
||||
service.adminClearByUser(7L);
|
||||
|
||||
verify(mapper).delete(any());
|
||||
}
|
||||
|
||||
private AdminUserSecretModuleVo moduleVo(boolean exists, String status) {
|
||||
AdminUserSecretModuleVo vo = new AdminUserSecretModuleVo();
|
||||
vo.setExists(exists);
|
||||
vo.setCheckStatus(status);
|
||||
return vo;
|
||||
}
|
||||
|
||||
private UserApiSecretEntity row(Long userId, String moduleKey, String cipher, String status) {
|
||||
UserApiSecretEntity entity = new UserApiSecretEntity();
|
||||
entity.setId((long) (Math.random() * 100000));
|
||||
entity.setUserId(userId);
|
||||
entity.setModuleKey(moduleKey);
|
||||
entity.setSecretValue(cipher);
|
||||
entity.setCheckStatus(status);
|
||||
entity.setUpdatedAt(java.time.LocalDateTime.now());
|
||||
return entity;
|
||||
}
|
||||
|
||||
private UserApiSecretMigrateRequest.Item item(String moduleKey, String value) {
|
||||
UserApiSecretMigrateRequest.Item item = new UserApiSecretMigrateRequest.Item();
|
||||
item.setModuleKey(moduleKey);
|
||||
|
||||
Reference in New Issue
Block a user