增加密码加密
This commit is contained in:
parent
3d454a0802
commit
9d42dd1ba3
@ -0,0 +1,75 @@
|
||||
package com.qqchen.deploy.backend.deploy.integration.impl;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
|
||||
import com.qqchen.deploy.backend.framework.util.SensitiveDataEncryptor;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 外部系统集成基类
|
||||
* 提供统一的密码解密功能
|
||||
*
|
||||
* @author qqchen
|
||||
* @since 2025-11-11
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseExternalSystemIntegration {
|
||||
|
||||
@Resource
|
||||
protected SensitiveDataEncryptor encryptor;
|
||||
|
||||
/**
|
||||
* 解密外部系统的敏感数据(密码和Token)
|
||||
* 创建一个新对象,不影响原对象
|
||||
*
|
||||
* @param system 原始的外部系统对象(包含加密的密码)
|
||||
* @return 解密后的外部系统对象
|
||||
*/
|
||||
protected ExternalSystem decryptSystem(ExternalSystem system) {
|
||||
if (system == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 创建新对象,避免修改原对象
|
||||
ExternalSystem decrypted = new ExternalSystem();
|
||||
|
||||
// 复制所有属性
|
||||
decrypted.setId(system.getId());
|
||||
decrypted.setName(system.getName());
|
||||
decrypted.setType(system.getType());
|
||||
decrypted.setUrl(system.getUrl());
|
||||
decrypted.setAuthType(system.getAuthType());
|
||||
decrypted.setUsername(system.getUsername());
|
||||
decrypted.setEnabled(system.getEnabled());
|
||||
decrypted.setConfig(system.getConfig());
|
||||
decrypted.setRemark(system.getRemark());
|
||||
decrypted.setSort(system.getSort());
|
||||
|
||||
// 解密密码
|
||||
if (StringUtils.isNotBlank(system.getPassword())) {
|
||||
try {
|
||||
String decryptedPassword = encryptor.decrypt(system.getPassword());
|
||||
decrypted.setPassword(decryptedPassword);
|
||||
log.debug("外部系统密码已解密: systemId={}, systemName={}", system.getId(), system.getName());
|
||||
} catch (Exception e) {
|
||||
log.warn("解密密码失败,使用原值: systemId={}, error={}", system.getId(), e.getMessage());
|
||||
decrypted.setPassword(system.getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
// 解密Token
|
||||
if (StringUtils.isNotBlank(system.getToken())) {
|
||||
try {
|
||||
String decryptedToken = encryptor.decrypt(system.getToken());
|
||||
decrypted.setToken(decryptedToken);
|
||||
log.debug("外部系统Token已解密: systemId={}, systemName={}", system.getId(), system.getName());
|
||||
} catch (Exception e) {
|
||||
log.warn("解密Token失败,使用原值: systemId={}, error={}", system.getId(), e.getMessage());
|
||||
decrypted.setToken(system.getToken());
|
||||
}
|
||||
}
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
}
|
||||
@ -27,12 +27,13 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
public class GitServiceIntegrationImpl extends BaseExternalSystemIntegration implements IGitServiceIntegration {
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Override
|
||||
public boolean testConnection(ExternalSystem system) {
|
||||
system = decryptSystem(system);
|
||||
try {
|
||||
String url = system.getUrl() + "/api/v4/version";
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
@ -54,6 +55,7 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
|
||||
@Override
|
||||
public List<GitGroupResponse> groups(ExternalSystem system) {
|
||||
system = decryptSystem(system);
|
||||
try {
|
||||
String url = String.format("%s/api/v4/groups?per_page=100", system.getUrl());
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
@ -76,6 +78,7 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
|
||||
@Override
|
||||
public List<GitProjectResponse> projects(ExternalSystem system) {
|
||||
system = decryptSystem(system);
|
||||
try {
|
||||
String url = String.format("%s/api/v4/projects", system.getUrl());
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
@ -98,6 +101,7 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
|
||||
@Override
|
||||
public List<GitProjectResponse> projectsByGroup(ExternalSystem system, Long groupId) {
|
||||
system = decryptSystem(system);
|
||||
try {
|
||||
String url = String.format("%s/api/v4/groups/%d/projects?per_page=100", system.getUrl(), groupId);
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
@ -120,6 +124,7 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
|
||||
@Override
|
||||
public List<GitBranchResponse> branches(ExternalSystem system, Long projectId) {
|
||||
system = decryptSystem(system);
|
||||
try {
|
||||
String url = String.format("%s/api/v4/projects/%d/repository/branches?per_page=100", system.getUrl(), projectId);
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
|
||||
@ -51,7 +51,7 @@ import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration {
|
||||
public class JenkinsServiceIntegrationImpl extends BaseExternalSystemIntegration implements IJenkinsServiceIntegration {
|
||||
|
||||
@Resource
|
||||
private IExternalSystemRepository systemRepository;
|
||||
@ -60,16 +60,12 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public boolean testConnection(ExternalSystem system) {
|
||||
// 解密系统信息
|
||||
system = decryptSystem(system);
|
||||
|
||||
try {
|
||||
String url = system.getUrl() + "/api/json";
|
||||
|
||||
// 详细日志:检查认证信息
|
||||
log.info("===== Jenkins连接测试调试信息 =====");
|
||||
log.info("URL: {}", url);
|
||||
log.info("认证类型: {}", system.getAuthType());
|
||||
log.info("用户名: {}", system.getUsername());
|
||||
log.info("密码是否为空: {}", system.getPassword() == null || system.getPassword().isEmpty());
|
||||
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
|
||||
// 打印实际发送的请求头
|
||||
@ -137,6 +133,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public JenkinsCrumbIssuerResponse getJenkinsCrumbIssue(ExternalSystem externalSystem) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
String url = externalSystem.getUrl() + "/crumbIssuer/api/json";
|
||||
HttpHeaders headers = createHeaders(externalSystem);
|
||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||||
@ -145,6 +142,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public String buildWithParameters(ExternalSystem externalSystem, String jobName, Map<String, String> parameters) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
try {
|
||||
// 如果参数中包含PIPELINE_SCRIPT,确保Job配置中有该参数
|
||||
if (parameters.containsKey("PIPELINE_SCRIPT")) {
|
||||
@ -375,6 +373,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public JenkinsQueueBuildInfoResponse getQueuedBuildInfo(ExternalSystem externalSystem, String queueId) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
String queueUrl = String.format("%s/queue/item/%s/api/json", externalSystem.getUrl().trim(), queueId);
|
||||
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(queueUrl, HttpMethod.GET, createHttpEntity(externalSystem), new ParameterizedTypeReference<>() {
|
||||
});
|
||||
@ -405,6 +404,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public JenkinsBuildStatus getBuildStatus(ExternalSystem externalSystem, String jobName, Integer buildNumber) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
try {
|
||||
String url = String.format("%s/job/%s/%d/api/json", externalSystem.getUrl().trim(), jobName, buildNumber);
|
||||
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(
|
||||
@ -435,6 +435,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public JenkinsBuildResponse getBuildDetails(ExternalSystem externalSystem, String jobName, Integer buildNumber) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
try {
|
||||
// 构建 tree 参数,只获取我们需要的字段
|
||||
String treeQuery = "number,url,result,duration,timestamp,building," +
|
||||
@ -562,9 +563,10 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
* @return 视图列表
|
||||
*/
|
||||
public List<JenkinsViewResponse> listViews(ExternalSystem externalSystem) {
|
||||
final ExternalSystem decryptedSystem = decryptSystem(externalSystem);
|
||||
String treeQuery = "views[name,url,description,_class]";
|
||||
List<JenkinsViewResponse> views = callJenkinsApi(
|
||||
externalSystem,
|
||||
decryptedSystem,
|
||||
"/api/json",
|
||||
treeQuery,
|
||||
"views",
|
||||
@ -572,6 +574,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
);
|
||||
|
||||
// 过滤和清洗数据
|
||||
final String baseUrl = StringUtils.removeEnd(decryptedSystem.getUrl(), "/");
|
||||
return views.stream()
|
||||
.filter(view -> !"all".equalsIgnoreCase(view.getName()))
|
||||
.peek(view -> {
|
||||
@ -581,7 +584,6 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
}
|
||||
// 转换URL为相对路径
|
||||
if (view.getUrl() != null) {
|
||||
String baseUrl = StringUtils.removeEnd(externalSystem.getUrl(), "/");
|
||||
view.setUrl(view.getUrl().replace(baseUrl, ""));
|
||||
}
|
||||
})
|
||||
@ -596,6 +598,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
* @return 任务列表
|
||||
*/
|
||||
public List<JenkinsJobResponse> listJobs(ExternalSystem externalSystem, String viewName) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
// 只查询必要的字段,确保包含lastBuild的timestamp字段
|
||||
String treeQuery = "jobs[name,url,description,buildable,nextBuildNumber," +
|
||||
"lastBuild[number,timestamp,result],color]";
|
||||
@ -629,6 +632,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
|
||||
@Override
|
||||
public JenkinsJobResponse job(ExternalSystem externalSystem, String jobName) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
try {
|
||||
// 1. 构建请求URL
|
||||
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
|
||||
@ -677,6 +681,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
* @return 构建信息列表
|
||||
*/
|
||||
public List<JenkinsBuildResponse> listBuilds(ExternalSystem externalSystem, String jobName) {
|
||||
externalSystem = decryptSystem(externalSystem);
|
||||
// Jenkins API 默认只返回最近的若干个构建,通过 {from,to} 可以指定范围
|
||||
String treeQuery = "builds[number,url,result,timestamp,duration,building,actions[_class,parameters[_class,name,value]]]";
|
||||
List<JenkinsBuildResponse> builds = callJenkinsApi(
|
||||
|
||||
@ -197,6 +197,22 @@ public class ExternalSystemServiceImpl extends BaseServiceImpl<ExternalSystem, E
|
||||
return dtos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.springframework.data.domain.Page<ExternalSystemDTO> page(ExternalSystemQuery query) {
|
||||
org.springframework.data.domain.Page<ExternalSystemDTO> page = super.page(query);
|
||||
// 查询后处理:用掩码替换敏感数据
|
||||
page.getContent().forEach(this::maskSensitiveData);
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExternalSystemDTO> findAll(ExternalSystemQuery query) {
|
||||
List<ExternalSystemDTO> dtos = super.findAll(query);
|
||||
// 查询后处理:用掩码替换敏感数据
|
||||
dtos.forEach(this::maskSensitiveData);
|
||||
return dtos;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean testConnection(Long id) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user