支持单位授权与客户端限制

This commit is contained in:
Codex
2026-06-01 11:58:14 +08:00
parent 28adc8143a
commit c136cc2cc8
36 changed files with 861 additions and 49 deletions

View File

@@ -199,15 +199,16 @@ public class SandboxConfigController {
RequestContext.get().setLangMap(user.getLangMap());
}
SandboxConfigDto dto = new SandboxConfigDto();
String clientName = StringUtils.trimToNull(sandboxRegDto.getName());
dto.setUserId(user.getId());
dto.setScope(SandboxScopeEnum.USER);
dto.setConfigKey(UUID.randomUUID().toString().replace("-", ""));
dto.setName(I18nUtil.systemMessage("Backend.Sandbox.MyComputer"));
dto.setName(clientName != null ? clientName : I18nUtil.systemMessage("Backend.Sandbox.MyComputer"));
dto.setConfigValue(sandboxRegDto.getSandboxConfigValue());
dto.setDescription("");
dto.setIsActive(true);
dto.setOnline(false);
sandboxConfigApplicationService.create(dto, false);
sandboxConfigApplicationService.create(dto, clientName != null);
String token = authService.createToken(user, StringUtils.isNotBlank(sandboxRegDto.getDeviceId()) ? sandboxRegDto.getDeviceId() : UUID.randomUUID().toString().replace("-", ""));
dto.setToken(token);
return ReqResult.success(sandboxConfigApplicationService.getByKey(dto.getConfigKey()));

View File

@@ -5,9 +5,16 @@ import com.xspaceagi.sandbox.application.dto.SandboxConfigDto;
import com.xspaceagi.sandbox.application.dto.SandboxConfigQueryDto;
import com.xspaceagi.sandbox.application.dto.SandboxGlobalConfigDto;
import com.xspaceagi.sandbox.application.service.SandboxConfigApplicationService;
import com.xspaceagi.system.application.dto.UserDto;
import com.xspaceagi.system.application.service.SysGroupApplicationService;
import com.xspaceagi.system.infra.dao.entity.SysGroup;
import com.xspaceagi.system.infra.dao.entity.User;
import com.xspaceagi.system.spec.annotation.RequireResource;
import com.xspaceagi.system.spec.common.RequestContext;
import com.xspaceagi.system.spec.dto.ReqResult;
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
import com.xspaceagi.system.spec.exception.BizException;
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -15,6 +22,8 @@ import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.xspaceagi.system.spec.enums.ResourceEnum.*;
@@ -29,10 +38,15 @@ public class SandboxConfigManageController {
@Resource
private SandboxConfigApplicationService sandboxConfigApplicationService;
@Resource
private SysGroupApplicationService sysGroupApplicationService;
@RequireResource(SANDBOX_CONFIG_QUERY)
@Operation(summary = "分页查询配置列表")
@PostMapping("/page")
public ReqResult<Page<SandboxConfigDto>> pageQuery(@RequestBody SandboxConfigQueryDto queryDto) {
queryDto = queryDto == null ? new SandboxConfigQueryDto() : queryDto;
applySandboxConfigManageScope(queryDto);
return ReqResult.success(sandboxConfigApplicationService.pageQuery(queryDto));
}
@@ -41,13 +55,16 @@ public class SandboxConfigManageController {
@GetMapping("/get/{id}")
public ReqResult<SandboxConfigDto> getById(
@Parameter(description = "配置ID") @PathVariable Long id) {
return ReqResult.success(sandboxConfigApplicationService.getById(id));
SandboxConfigDto dto = sandboxConfigApplicationService.getById(id);
checkSandboxConfigManageScope(dto);
return ReqResult.success(dto);
}
@Operation(summary = "沙箱连通性测试")
@GetMapping("/test/{id}")
public ReqResult<Void> testConnection(@Parameter(description = "配置ID") @PathVariable Long id) {
try {
checkSandboxConfigManageScope(sandboxConfigApplicationService.getById(id));
sandboxConfigApplicationService.testConnection(id);
} catch (Exception e) {
return ReqResult.error("0007", e.getMessage());
@@ -60,7 +77,14 @@ public class SandboxConfigManageController {
@GetMapping("/user/list")
public ReqResult<List<SandboxConfigDto>> listUserConfigsByType(
@Parameter(description = "用户ID为空时查询当前用户") @RequestParam(required = false) Long userId) {
return ReqResult.success(sandboxConfigApplicationService.listUserConfigsByType(userId));
List<SandboxConfigDto> configs = sandboxConfigApplicationService.listUserConfigsByType(userId);
if (!isPlatformAdmin()) {
Set<Long> allowedGroupIds = currentUserGroupIds();
configs = configs.stream()
.filter(config -> config.getGroupId() != null && allowedGroupIds.contains(config.getGroupId()))
.collect(Collectors.toList());
}
return ReqResult.success(configs);
}
@RequireResource(SANDBOX_CONFIG_QUERY)
@@ -74,6 +98,7 @@ public class SandboxConfigManageController {
@Operation(summary = "创建配置")
@PostMapping("/create")
public ReqResult<Void> create(@RequestBody SandboxConfigDto dto) {
checkSandboxConfigManageScope(dto);
sandboxConfigApplicationService.create(dto, false);
return ReqResult.success();
}
@@ -82,6 +107,7 @@ public class SandboxConfigManageController {
@Operation(summary = "更新配置")
@PostMapping("/update")
public ReqResult<Void> update(@RequestBody SandboxConfigDto dto) {
checkSandboxConfigManageScope(sandboxConfigApplicationService.getById(dto.getId()));
sandboxConfigApplicationService.update(dto);
return ReqResult.success();
}
@@ -91,6 +117,7 @@ public class SandboxConfigManageController {
@PostMapping("/delete/{id}")
public ReqResult<Void> delete(
@Parameter(description = "配置ID") @PathVariable Long id) {
checkSandboxConfigManageScope(sandboxConfigApplicationService.getById(id));
sandboxConfigApplicationService.delete(id);
return ReqResult.success();
}
@@ -100,6 +127,7 @@ public class SandboxConfigManageController {
@PostMapping("/toggle/{id}")
public ReqResult<Void> toggle(
@Parameter(description = "配置ID") @PathVariable Long id) {
checkSandboxConfigManageScope(sandboxConfigApplicationService.getById(id));
sandboxConfigApplicationService.toggle(id);
return ReqResult.success();
}
@@ -119,4 +147,45 @@ public class SandboxConfigManageController {
SandboxGlobalConfigDto globalConfig = sandboxConfigApplicationService.getGlobalConfig(RequestContext.get().getTenantId());
return ReqResult.success(globalConfig);
}
private void applySandboxConfigManageScope(SandboxConfigQueryDto queryDto) {
if (queryDto == null || isPlatformAdmin()) {
return;
}
Set<Long> allowedGroupIds = currentUserGroupIds();
if (queryDto.getGroupId() != null) {
if (!allowedGroupIds.contains(queryDto.getGroupId())) {
throw BizException.of(ErrorCodeEnum.PERMISSION_DENIED, BizExceptionCodeEnum.permissionDenied);
}
return;
}
queryDto.setGroupIds(allowedGroupIds.isEmpty() ? List.of(-1L) : allowedGroupIds.stream().toList());
}
private void checkSandboxConfigManageScope(SandboxConfigDto dto) {
if (dto == null || isPlatformAdmin()) {
return;
}
if (dto.getGroupId() == null || !currentUserGroupIds().contains(dto.getGroupId())) {
throw BizException.of(ErrorCodeEnum.PERMISSION_DENIED, BizExceptionCodeEnum.permissionDenied);
}
}
private Set<Long> currentUserGroupIds() {
return sysGroupApplicationService.getEffectiveGroupListByUserId(getCurrentUserDto().getId()).stream()
.map(SysGroup::getId)
.collect(Collectors.toSet());
}
private boolean isPlatformAdmin() {
return getCurrentUserDto().getRole() == User.Role.Admin;
}
private UserDto getCurrentUserDto() {
UserDto userDto = (UserDto) RequestContext.get().getUser();
if (userDto == null) {
throw BizException.of(ErrorCodeEnum.UNAUTHORIZED, BizExceptionCodeEnum.systemUserNotLoggedInWeb);
}
return userDto;
}
}

View File

@@ -19,6 +19,9 @@ public class SandboxRegDto {
@Schema(description = "设备ID")
private String deviceId;
@Schema(description = "客户端注册名称")
private String name;
@Schema(description = "终端配置信息")
private SandboxConfigValue sandboxConfigValue;
}