This commit is contained in:
fit2-zhao 2021-03-12 17:14:36 +08:00
commit 7093a8a921
26 changed files with 690 additions and 299 deletions

View File

@ -20,6 +20,7 @@ import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
import io.metersphere.performance.service.PerformanceTestService; import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.CheckPermissionService; import io.metersphere.service.CheckPermissionService;
@ -104,7 +105,7 @@ public class APITestController {
} }
@PostMapping(value = "/schedule/create") @PostMapping(value = "/schedule/create")
public void createSchedule(@RequestBody Schedule request) { public void createSchedule(@RequestBody ScheduleRequest request) {
apiTestService.createSchedule(request); apiTestService.createSchedule(request);
} }

View File

@ -16,6 +16,7 @@ import io.metersphere.commons.constants.RoleConstants;
import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
import io.metersphere.track.request.testplan.FileOperationRequest; import io.metersphere.track.request.testplan.FileOperationRequest;
import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.Logical;
@ -149,7 +150,7 @@ public class ApiAutomationController {
} }
@PostMapping(value = "/schedule/create") @PostMapping(value = "/schedule/create")
public void createSchedule(@RequestBody Schedule request) { public void createSchedule(@RequestBody ScheduleRequest request) {
apiAutomationService.createSchedule(request); apiAutomationService.createSchedule(request);
} }

View File

@ -20,6 +20,7 @@ import io.metersphere.commons.utils.CronUtils;
import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.service.CheckPermissionService; import io.metersphere.service.CheckPermissionService;
import io.metersphere.service.ScheduleService; import io.metersphere.service.ScheduleService;
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
@ -156,7 +157,7 @@ public class ApiDefinitionController {
//定时任务创建 //定时任务创建
@PostMapping(value = "/schedule/create") @PostMapping(value = "/schedule/create")
public void createSchedule(@RequestBody Schedule request) { public void createSchedule(@RequestBody ScheduleRequest request) {
apiDefinitionService.createSchedule(request); apiDefinitionService.createSchedule(request);
} }
@PostMapping(value = "/schedule/update") @PostMapping(value = "/schedule/update")

View File

@ -21,6 +21,7 @@ import io.metersphere.commons.constants.ScheduleType;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.ApiTestJob; import io.metersphere.job.sechedule.ApiTestJob;
@ -328,12 +329,12 @@ public class APITestService {
addOrUpdateApiTestCronJob(request); addOrUpdateApiTestCronJob(request);
} }
public void createSchedule(Schedule request) { public void createSchedule(ScheduleRequest request) {
scheduleService.addSchedule(buildApiTestSchedule(request)); scheduleService.addSchedule(buildApiTestSchedule(request));
addOrUpdateApiTestCronJob(request); addOrUpdateApiTestCronJob(request);
} }
private Schedule buildApiTestSchedule(Schedule request) { private Schedule buildApiTestSchedule(ScheduleRequest request) {
Schedule schedule = scheduleService.buildApiTestSchedule(request); Schedule schedule = scheduleService.buildApiTestSchedule(request);
schedule.setJob(ApiTestJob.class.getName()); schedule.setJob(ApiTestJob.class.getName());
schedule.setGroup(ScheduleGroup.API_TEST.name()); schedule.setGroup(ScheduleGroup.API_TEST.name());

View File

@ -31,6 +31,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.ApiScenarioTestJob; import io.metersphere.job.sechedule.ApiScenarioTestJob;
import io.metersphere.job.sechedule.TestPlanTestJob; import io.metersphere.job.sechedule.TestPlanTestJob;
@ -717,7 +718,7 @@ public class ApiAutomationService {
return apiScenarioMapper.selectByExampleWithBLOBs(example); return apiScenarioMapper.selectByExampleWithBLOBs(example);
} }
public void createSchedule(Schedule request) { public void createSchedule(ScheduleRequest request) {
Schedule schedule = scheduleService.buildApiTestSchedule(request); Schedule schedule = scheduleService.buildApiTestSchedule(request);
schedule.setJob(ApiScenarioTestJob.class.getName()); schedule.setJob(ApiScenarioTestJob.class.getName());
schedule.setGroup(ScheduleGroup.API_SCENARIO_TEST.name()); schedule.setGroup(ScheduleGroup.API_SCENARIO_TEST.name());

View File

@ -28,6 +28,7 @@ import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.SwaggerUrlImportJob; import io.metersphere.job.sechedule.SwaggerUrlImportJob;
import io.metersphere.service.FileService; import io.metersphere.service.FileService;
@ -702,7 +703,7 @@ public class ApiDefinitionService {
} }
/*swagger定时导入*/ /*swagger定时导入*/
public void createSchedule(Schedule request) { public void createSchedule(ScheduleRequest request) {
/*保存swaggerUrl*/ /*保存swaggerUrl*/
SwaggerUrlProject swaggerUrlProject = new SwaggerUrlProject(); SwaggerUrlProject swaggerUrlProject = new SwaggerUrlProject();
swaggerUrlProject.setId(UUID.randomUUID().toString()); swaggerUrlProject.setId(UUID.randomUUID().toString());

View File

@ -126,8 +126,14 @@ public class ApiTestCaseService {
if (!CollectionUtils.isEmpty(userIds)) { if (!CollectionUtils.isEmpty(userIds)) {
Map<String, User> userMap = userService.queryNameByIds(userIds); Map<String, User> userMap = userService.queryNameByIds(userIds);
apiTestCases.forEach(caseResult -> { apiTestCases.forEach(caseResult -> {
caseResult.setCreateUser(userMap.get(caseResult.getCreateUserId()).getName()); User createUser = userMap.get(caseResult.getCreateUserId());
caseResult.setUpdateUser(userMap.get(caseResult.getUpdateUserId()).getName()); if (createUser != null) {
caseResult.setCreateUser(createUser.getName());
}
User updateUser = userMap.get(caseResult.getUpdateUserId());
if (updateUser != null) {
caseResult.setUpdateUser(updateUser.getName());
}
}); });
} }
} }

View File

@ -33,15 +33,4 @@ public class Schedule implements Serializable {
private String customData; private String customData;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
//定时任务来源 测试计划/测试场景
private String scheduleFrom;
private String projectId;
private String moduleId;
private String modulePath;
private String modeId;
} }

View File

@ -0,0 +1,16 @@
package io.metersphere.commons.utils;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class RsaKey {
//公钥
private String publicKey;
//私钥
private String privateKey;
}

View File

@ -0,0 +1,224 @@
package io.metersphere.commons.utils;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RsaUtil {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
/**
* 创建RSA 公钥-私钥
*/
public static RsaKey createKeys() throws NoSuchAlgorithmException {
return createKeys(1024);
}
/**
* 创建RSA 公钥-私钥
*/
public static RsaKey createKeys(int keySize) throws NoSuchAlgorithmException {
//为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
//初始化KeyPairGenerator对象,密钥长度
kpg.initialize(keySize);
//生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
//得到公钥
Key publicKey = keyPair.getPublic();
String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
//得到私钥
Key privateKey = keyPair.getPrivate();
String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
RsaKey rsaKey = new RsaKey();
rsaKey.setPublicKey(publicKeyStr);
rsaKey.setPrivateKey(privateKeyStr);
return rsaKey;
}
/**
* 公钥加密
*
* @param originalText 原文
* @param publicKey 公钥
*/
public static String publicEncrypt(String originalText, String publicKey) throws NoSuchAlgorithmException {
RSAPublicKey rsaPublicKey = getPublicKey(publicKey);
return publicEncrypt(originalText, rsaPublicKey);
}
/**
* 公钥解密
*
* @param cipherText 密文
* @param publicKey 公钥
*/
public static String publicDecrypt(String cipherText, String publicKey) throws NoSuchAlgorithmException {
RSAPublicKey rsaPublicKey = getPublicKey(publicKey);
return publicDecrypt(cipherText, rsaPublicKey);
}
/**
* 私钥加密
*
* @param originalText 原文
* @param privateKey 私钥
*/
public static String privateEncrypt(String originalText, String privateKey) throws NoSuchAlgorithmException {
RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);
return privateEncrypt(originalText, rsaPrivateKey);
}
/**
* 私钥解密
*
* @param cipherText 密文
* @param privateKey 私钥
*/
public static String privateDecrypt(String cipherText, String privateKey) throws NoSuchAlgorithmException {
RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);
return privateDecrypt(cipherText, rsaPrivateKey);
}
/**
* 得到公钥
*
* @param publicKey 密钥字符串经过base64编码
*/
private static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = null;
try {
key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return key;
}
/**
* 公钥加密
*
* @param originalText 原文
* @param publicKey 公钥
*/
private static String publicEncrypt(String originalText, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, originalText.getBytes(CHARSET), publicKey.getModulus().bitLength()));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + originalText + "]时遇到异常", e);
}
}
/**
* 得到私钥
*
* @param privateKey 密钥字符串经过base64编码
*/
private static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException {
//通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = null;
try {
key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return key;
}
/**
* 私钥解密
*
* @param cipherText 密文
* @param privateKey 私钥
*/
private static String privateDecrypt(String cipherText, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(cipherText), privateKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + cipherText + "]时遇到异常", e);
}
}
private static String privateEncrypt(String originalText, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, originalText.getBytes(CHARSET), privateKey.getModulus().bitLength()));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + originalText + "]时遇到异常", e);
}
}
private static String publicDecrypt(String cipherText, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(cipherText), publicKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + cipherText + "]时遇到异常", e);
}
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock;
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
int offSet = 0;
byte[] buff;
int i = 0;
try (
ByteArrayOutputStream out = new ByteArrayOutputStream()
) {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
return out.toByteArray();
} catch (Exception e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
}
}
}

View File

@ -46,6 +46,7 @@ public class ShiroUtils {
public static void ignoreCsrfFilter(Map<String, String> filterChainDefinitionMap) { public static void ignoreCsrfFilter(Map<String, String> filterChainDefinitionMap) {
filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf
filterChainDefinitionMap.put("/document", "apikey, authc"); // 跳转到 /document 不用校验 csrf
} }
public static Cookie getSessionIdCookie(){ public static Cookie getSessionIdCookie(){

View File

@ -0,0 +1,16 @@
package io.metersphere.config;
import io.metersphere.commons.utils.RsaKey;
import io.metersphere.commons.utils.RsaUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.security.NoSuchAlgorithmException;
@Configuration
public class RsaConfig {
@Bean
public RsaKey rsaKey() throws NoSuchAlgorithmException {
return RsaUtil.createKeys();
}
}

View File

@ -2,6 +2,8 @@ package io.metersphere.controller;
import io.metersphere.commons.constants.UserSource; import io.metersphere.commons.constants.UserSource;
import io.metersphere.commons.user.SessionUser; import io.metersphere.commons.user.SessionUser;
import io.metersphere.commons.utils.RsaKey;
import io.metersphere.commons.utils.RsaUtil;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.LoginRequest; import io.metersphere.controller.request.LoginRequest;
import io.metersphere.service.BaseDisplayService; import io.metersphere.service.BaseDisplayService;
@ -23,6 +25,8 @@ public class LoginController {
private UserService userService; private UserService userService;
@Resource @Resource
private BaseDisplayService baseDisplayService; private BaseDisplayService baseDisplayService;
@Resource
private RsaKey rsaKey;
@GetMapping(value = "/isLogin") @GetMapping(value = "/isLogin")
public ResultHolder isLogin() { public ResultHolder isLogin() {
@ -33,7 +37,7 @@ public class LoginController {
} }
return ResultHolder.success(user); return ResultHolder.success(user);
} }
return ResultHolder.error(""); return ResultHolder.error(rsaKey.getPublicKey());
} }
@PostMapping(value = "/signin") @PostMapping(value = "/signin")

View File

@ -5,6 +5,7 @@ import com.github.pagehelper.PageHelper;
import io.metersphere.api.service.ApiAutomationService; import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.base.domain.Schedule; import io.metersphere.base.domain.Schedule;
import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
import io.metersphere.service.ScheduleService; import io.metersphere.service.ScheduleService;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -38,7 +39,7 @@ public class ScheduleController {
} }
@PostMapping(value = "/create") @PostMapping(value = "/create")
public void createSchedule(@RequestBody Schedule request) { public void createSchedule(@RequestBody ScheduleRequest request) {
scheduleService.createSchedule(request); scheduleService.createSchedule(request);
} }

View File

@ -1,12 +1,36 @@
package io.metersphere.controller.request; package io.metersphere.controller.request;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.RsaKey;
import io.metersphere.commons.utils.RsaUtil;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.security.NoSuchAlgorithmException;
@Getter @Getter
@Setter @Setter
public class LoginRequest { public class LoginRequest {
private String username; private String username;
private String password; private String password;
private String authenticate; private String authenticate;
public String getUsername() {
try {
RsaKey rsaKey = CommonBeanFactory.getBean(RsaKey.class);
return RsaUtil.privateDecrypt(username, rsaKey.getPrivateKey());
} catch (NoSuchAlgorithmException e) {
return username;
}
}
public String getPassword() {
try {
RsaKey rsaKey = CommonBeanFactory.getBean(RsaKey.class);
return RsaUtil.privateDecrypt(password, rsaKey.getPrivateKey());
} catch (NoSuchAlgorithmException e) {
return password;
}
}
} }

View File

@ -0,0 +1,27 @@
package io.metersphere.controller.request;
import io.metersphere.base.domain.Schedule;
import lombok.Getter;
import lombok.Setter;
/**
* @author song.tianyang
* @Date 2021/3/12 12:57 下午
* @Description
*/
@Getter
@Setter
public class ScheduleRequest extends Schedule {
//定时任务来源 测试计划/测试场景
private String scheduleFrom;
private String projectId;
private String moduleId;
private String modulePath;
private String modeId;
}

View File

@ -10,6 +10,7 @@ import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.dto.DashboardTestDTO; import io.metersphere.dto.DashboardTestDTO;
import io.metersphere.dto.LoadTestDTO; import io.metersphere.dto.LoadTestDTO;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
@ -175,7 +176,7 @@ public class PerformanceTestController {
} }
@PostMapping(value = "/schedule/create") @PostMapping(value = "/schedule/create")
public void createSchedule(@RequestBody Schedule request) { public void createSchedule(@RequestBody ScheduleRequest request) {
performanceTestService.createSchedule(request); performanceTestService.createSchedule(request);
} }

View File

@ -103,6 +103,7 @@ public class DockerTestEngine extends AbstractEngine {
startTestRequest.setEnv(env); startTestRequest.setEnv(env);
String uri = String.format(BASE_URL + "/jmeter/container/start", nodeIp, port); String uri = String.format(BASE_URL + "/jmeter/container/start", nodeIp, port);
try {
ResultHolder result = restTemplate.postForObject(uri, startTestRequest, ResultHolder.class); ResultHolder result = restTemplate.postForObject(uri, startTestRequest, ResultHolder.class);
if (result == null) { if (result == null) {
MSException.throwException(Translator.get("start_engine_fail")); MSException.throwException(Translator.get("start_engine_fail"));
@ -110,6 +111,11 @@ public class DockerTestEngine extends AbstractEngine {
if (!result.isSuccess()) { if (!result.isSuccess()) {
MSException.throwException(result.getMessage()); MSException.throwException(result.getMessage());
} }
} catch (MSException e) {
throw e;
} catch (Exception e) {
MSException.throwException("Please check node-controller status.");
}
} }
@Override @Override

View File

@ -14,6 +14,7 @@ import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.config.KafkaProperties; import io.metersphere.config.KafkaProperties;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.dto.DashboardTestDTO; import io.metersphere.dto.DashboardTestDTO;
import io.metersphere.dto.LoadTestDTO; import io.metersphere.dto.LoadTestDTO;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
@ -465,12 +466,12 @@ public class PerformanceTestService {
addOrUpdatePerformanceTestCronJob(request); addOrUpdatePerformanceTestCronJob(request);
} }
public void createSchedule(Schedule request) { public void createSchedule(ScheduleRequest request) {
scheduleService.addSchedule(buildPerformanceTestSchedule(request)); scheduleService.addSchedule(buildPerformanceTestSchedule(request));
addOrUpdatePerformanceTestCronJob(request); addOrUpdatePerformanceTestCronJob(request);
} }
private Schedule buildPerformanceTestSchedule(Schedule request) { private Schedule buildPerformanceTestSchedule(ScheduleRequest request) {
Schedule schedule = scheduleService.buildApiTestSchedule(request); Schedule schedule = scheduleService.buildApiTestSchedule(request);
schedule.setJob(PerformanceTestJob.class.getName()); schedule.setJob(PerformanceTestJob.class.getName());
schedule.setGroup(ScheduleGroup.PERFORMANCE_TEST.name()); schedule.setGroup(ScheduleGroup.PERFORMANCE_TEST.name());

View File

@ -17,6 +17,7 @@ import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
import io.metersphere.job.sechedule.*; import io.metersphere.job.sechedule.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -143,7 +144,7 @@ public class ScheduleService {
}); });
} }
public Schedule buildApiTestSchedule(Schedule request) { public Schedule buildApiTestSchedule(ScheduleRequest request) {
Schedule schedule = new Schedule(); Schedule schedule = new Schedule();
schedule.setResourceId(request.getResourceId()); schedule.setResourceId(request.getResourceId());
schedule.setEnable(true); schedule.setEnable(true);
@ -218,7 +219,7 @@ public class ScheduleService {
return runningTaskInfoList; return runningTaskInfoList;
} }
public void createSchedule(Schedule request) { public void createSchedule(ScheduleRequest request) {
Schedule schedule = this.buildApiTestSchedule(request); Schedule schedule = this.buildApiTestSchedule(request);
schedule.setJob(ApiScenarioTestJob.class.getName()); schedule.setJob(ApiScenarioTestJob.class.getName());

View File

@ -78,14 +78,19 @@ alter table test_case
alter table test_case alter table test_case
add demand_name varchar(999) null; add demand_name varchar(999) null;
alter table test_case
add follow_people varchar(100) null;
-- test_case_review add column -- test_case_review add column
ALTER TABLE test_case_review ADD tags VARCHAR(2000) NULL; ALTER TABLE test_case_review
ADD tags VARCHAR(2000) NULL;
-- alter test_plan_api_scenario -- alter test_plan_api_scenario
alter table test_plan_api_scenario change environment_id environment longtext null comment 'Relevance environment'; alter table test_plan_api_scenario
change environment_id environment longtext null comment 'Relevance environment';
-- file add sort column -- file add sort column
alter table file_metadata add sort int default 0; alter table file_metadata
add sort int default 0;
-- add Original state -- add Original state
alter table api_definition add original_state varchar(64); alter table api_definition add original_state varchar(64);

View File

@ -49,7 +49,8 @@
"xml-js": "^1.6.11", "xml-js": "^1.6.11",
"yan-progress": "^1.0.3", "yan-progress": "^1.0.3",
"jsonpath": "^1.1.0", "jsonpath": "^1.1.0",
"vue-minder-editor-plus": "^1.0.14" "vue-minder-editor-plus": "^1.0.16",
"jsencrypt": "^3.1.0"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-babel": "^4.1.0",

View File

@ -0,0 +1,65 @@
<template>
<ms-module-minder
:tree-nodes="treeNodes"/>
</template>
<script>
import MsModuleMinder from "@/business/components/common/components/MsModuleMinder";
export default {
name: "TestCaseMinder",
components: {MsModuleMinder},
data() {
return{
testCase: [],
dataMap: new Map()
}
},
props: {
treeNodes: {
type: Array,
default() {
return []
}
},
condition: Object,
projectId: String
},
mounted() {
// this.getTestCases();
},
methods: {
getTestCases() {
if (this.projectId) {
this.result = this.$get('/test/case/list/detail/' + this.projectId,response => {
this.testCase = response.data;
console.log(this.testCase)
this.parse();
});
}
},
parse() {
this.testCase.forEach(item => {
let mapItem = this.dataMap.get(item.moduleId);
let nodeItem = {
id: item.id,
name: item.name,
}
if (mapItem) {
mapItem.push(item);
} else {
mapItem = [];
mapItem.push(item);
}
if (item.tags && item.tags.length > 0) {
item.tags = JSON.parse(item.tags);
}
})
}
},
}
</script>
<style scoped>
</style>

View File

@ -1,25 +0,0 @@
<template>
<ms-module-minder
:tree-nodes="treeNodes"/>
</template>
<script>
import MsModuleMinder from "@/business/components/common/components/MsModuleMinder";
export default {
name: "TestcaseMinder",
components: {MsModuleMinder},
props: {
treeNodes: {
type: Array,
default() {
return []
}
}
},
}
</script>
<style scoped>
</style>

View File

@ -1,6 +1,9 @@
import { import {
COUNT_NUMBER, COUNT_NUMBER_SHALLOW, COUNT_NUMBER,
LicenseKey, ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW, COUNT_NUMBER_SHALLOW,
LicenseKey,
ORIGIN_COLOR,
ORIGIN_COLOR_SHALLOW,
PROJECT_ID, PROJECT_ID,
REFRESH_SESSION_USER_URL, REFRESH_SESSION_USER_URL,
ROLE_ADMIN, ROLE_ADMIN,
@ -12,6 +15,7 @@ import {
} from "./constants"; } from "./constants";
import axios from "axios"; import axios from "axios";
import {jsPDF} from "jspdf"; import {jsPDF} from "jspdf";
import JSEncrypt from 'jsencrypt';
export function hasRole(role) { export function hasRole(role) {
let user = getCurrentUser(); let user = getCurrentUser();
@ -364,3 +368,11 @@ export function setColor(a, b, c, d) {
export function setOriginColor() { export function setOriginColor() {
setColor(ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW, COUNT_NUMBER, COUNT_NUMBER_SHALLOW); setColor(ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW, COUNT_NUMBER, COUNT_NUMBER_SHALLOW);
} }
export function publicKeyEncrypt(input, publicKey) {
let jsencrypt = new JSEncrypt({default_key_size: 1024});
jsencrypt.setPublicKey(publicKey);
return jsencrypt.encrypt(input);
}

View File

@ -55,7 +55,7 @@
</template> </template>
<script> <script>
import {saveLocalStorage} from '@/common/js/utils'; import {publicKeyEncrypt, saveLocalStorage} from '@/common/js/utils';
import {DEFAULT_LANGUAGE} from "@/common/js/constants"; import {DEFAULT_LANGUAGE} from "@/common/js/constants";
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/); const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
@ -103,6 +103,8 @@ export default {
if (!response.data.success) { if (!response.data.success) {
this.ready = true; this.ready = true;
//
localStorage.setItem("publicKey", response.data.message);
} else { } else {
let user = response.data.data; let user = response.data.data;
saveLocalStorage(response.data); saveLocalStorage(response.data);
@ -159,7 +161,15 @@ export default {
}); });
}, },
doLogin() { doLogin() {
this.result = this.$post(this.loginUrl, this.form, response => { let publicKey = localStorage.getItem("publicKey");
let form = {
username: publicKeyEncrypt(this.form.username, publicKey),
password: publicKeyEncrypt(this.form.password, publicKey),
authenticate: this.form.authenticate
};
this.result = this.$post(this.loginUrl, form, response => {
saveLocalStorage(response); saveLocalStorage(response);
sessionStorage.setItem('loginSuccess', 'true'); sessionStorage.setItem('loginSuccess', 'true');
this.getLanguage(response.data.language); this.getLanguage(response.data.language);