From 4acc706021bd716f47817abc9a0fb9f028ec1df7 Mon Sep 17 00:00:00 2001 From: youys <1272586223@qq.com> Date: Thu, 21 Apr 2022 10:04:34 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E7=94=A8b=E7=AB=AF=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AD=BE=E5=90=8D=20=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CallbackController.java | 27 +++++++++-- .../schedule/EvaCheckWarningTask.java | 26 +++++++++- .../java/net/educoder/util/SignatureUtil.java | 47 +++++++++++++++++++ src/main/resources/application-dev.yml | 2 + src/main/resources/application-prod.yml | 2 + src/main/resources/logback.xml | 2 +- 6 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/main/java/net/educoder/util/SignatureUtil.java diff --git a/src/main/java/net/educoder/controller/CallbackController.java b/src/main/java/net/educoder/controller/CallbackController.java index 7f29be1..071c052 100644 --- a/src/main/java/net/educoder/controller/CallbackController.java +++ b/src/main/java/net/educoder/controller/CallbackController.java @@ -32,6 +32,9 @@ public class CallbackController { @Autowired private RedisUtil redisUtil; + private final Object LOCK = new Object(); + + private static final String RESULT = "success"; private static List ERROR_MSG_LIST = null; @@ -64,7 +67,7 @@ public class CallbackController { // 通知之后清空 redisUtil.remove(incrKey); return RESULT; - } else if(incr == 0L){ + } else if (incr == 0L) { log.info("tpiID:{},评测通过", tpiID); } @@ -78,14 +81,28 @@ public class CallbackController { * @return */ private boolean matchOutPut(String output) { - if (ERROR_MSG_LIST == null) { - ERROR_MSG_LIST = Arrays.asList(propertiesConfig.getErrorOutPuts().split("\n")); - } - for (String s : ERROR_MSG_LIST) { + for (String s : getErrorOutputList()) { if (output.contains(s)) { return true; } } return false; } + + /** + * 获取错误输出配置列表. + * + * @return list + */ + private List getErrorOutputList() { + if (ERROR_MSG_LIST == null) { + synchronized (LOCK) { + if (ERROR_MSG_LIST == null) { + ERROR_MSG_LIST = Arrays.asList(propertiesConfig.getErrorOutPuts().split("\n")); + } + } + } + return ERROR_MSG_LIST; + } + } diff --git a/src/main/java/net/educoder/schedule/EvaCheckWarningTask.java b/src/main/java/net/educoder/schedule/EvaCheckWarningTask.java index 164109d..c1d25da 100644 --- a/src/main/java/net/educoder/schedule/EvaCheckWarningTask.java +++ b/src/main/java/net/educoder/schedule/EvaCheckWarningTask.java @@ -1,11 +1,13 @@ package net.educoder.schedule; +import cn.hutool.core.util.RandomUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import net.educoder.config.PropertiesConfig; import net.educoder.model.AutoEvaParamConfig; import net.educoder.service.AutoEvaParamConfigService; +import net.educoder.util.SignatureUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; @@ -35,6 +37,10 @@ public class EvaCheckWarningTask { @Autowired private AutoEvaParamConfigService autoEvaParamConfigService; + @Value("${bridge.sign.accessKeySecret}") + private String accessKeySecret; + + @Async @Scheduled(cron = "${task.cron.evalCheck}") public void check() { @@ -75,7 +81,7 @@ public class EvaCheckWarningTask { private void postEvaluation(AutoEvaParamConfig autoEvaParamConfig) { JSONObject extrasObject = JSONObject.parseObject(autoEvaParamConfig.getExtras()); - Map param = new HashMap<>(); + Map param = new HashMap<>(32); param.put("isPublished", extrasObject.getInteger("isPublished")); param.put("trimBlank", extrasObject.getInteger("trimBlank")); param.put("containers", extrasObject.getString("containers")); @@ -92,6 +98,14 @@ public class EvaCheckWarningTask { param.put("buildID", autoEvaParamConfig.getBuildId()); param.put("sec_key", UUID.randomUUID().toString()); param.put("callBackUrl", propertiesConfig.getCallbackUrl()); + param.put("ak", RandomUtil.randomString(16)); + param.put("nonce", RandomUtil.randomString(16)); + + String sign = SignatureUtil.genSignature(accessKeySecret, param); + log.info("postEvaluation---------签名值sign:{}", sign); + + param.put("sign", sign); + String result = HttpUtil.post(propertiesConfig.getGameEvaluationUrl(), param); JSONObject jsonResult = JSONObject.parseObject(result); log.info("实训评测接口返回:{},tpiId:{}", jsonResult, autoEvaParamConfig.getTpiId()); @@ -103,12 +117,20 @@ public class EvaCheckWarningTask { * @param autoEvaParamConfig 配置 */ private void postOjEvaluation(AutoEvaParamConfig autoEvaParamConfig) { - Map param = new HashMap<>(8); + Map param = new HashMap<>(16); param.put("tpiID", autoEvaParamConfig.getTpiId()); param.put("testCases", autoEvaParamConfig.getTestCases()); param.put("codeFileContent", autoEvaParamConfig.getCodeFileContent()); param.put("sec_key", UUID.randomUUID().toString()); param.put("callBackUrl", propertiesConfig.getCallbackUrl()); + param.put("ak", RandomUtil.randomString(16)); + param.put("nonce", RandomUtil.randomString(16)); + + String sign = SignatureUtil.genSignature(accessKeySecret, param); + log.info("postEvaluation---------签名值:{}", sign); + param.put("sign", sign); + + String result = HttpUtil.post(propertiesConfig.getOjEvaluationUrl(), param); JSONObject jsonResult = JSONObject.parseObject(result); log.info("Oj评测接口返回:{},tpiId:{}", jsonResult, autoEvaParamConfig.getTpiId()); diff --git a/src/main/java/net/educoder/util/SignatureUtil.java b/src/main/java/net/educoder/util/SignatureUtil.java new file mode 100644 index 0000000..19f2d80 --- /dev/null +++ b/src/main/java/net/educoder/util/SignatureUtil.java @@ -0,0 +1,47 @@ +package net.educoder.util; + +import org.springframework.util.DigestUtils; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.Map; + +/** + * @Author: youys + * @Date: 2022/4/20 + * @Description: + */ +public class SignatureUtil { + + /** + * 按字典排序签名. + * + * @param secretKey + * @param params + * @return + * @throws UnsupportedEncodingException + */ + public static String genSignature(String secretKey, Map params) { + if (secretKey == null || params == null || params.size() == 0) { + return ""; + } + // 1. 参数名按照ASCII码表升序排序 + String[] keys = params.keySet().toArray(new String[0]); + Arrays.sort(keys); + // 2. 按照排序拼接参数名与参数值 + StringBuffer paramBuffer = new StringBuffer(); + for (String key : keys) { + paramBuffer.append("&" + key).append(params.get(key) == null ? "" : "=" + params.get(key)); + } + // 3. 将secretKey拼接到最后 + paramBuffer = paramBuffer.append("&sk=" + secretKey); + String pa = paramBuffer.substring(1); + // 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。 + try { + return DigestUtils.md5DigestAsHex(pa.getBytes("UTF-8")).toUpperCase(); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 38faf66..3f64306 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -26,6 +26,8 @@ bridge: 当前实验环境正在更新中,请稍后重试或联系系统管理员! 当前网络较差,代码下载超时,请稍后重试! 评测脚本设置异常,建议您在实训的配置页面重新选择或修改评测脚本 + sign: + accessKeySecret: 9NMU8ushmFu8SN1EKHOhvo9jmv1qp0 # 定时任务cron表达式 task: cron: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 23a99e0..4a3c2ce 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -26,6 +26,8 @@ bridge: 当前实验环境正在更新中,请稍后重试或联系系统管理员! 当前网络较差,代码下载超时,请稍后重试! 评测脚本设置异常,建议您在实训的配置页面重新选择或修改评测脚本 + sign: + accessKeySecret: 9NMU8ushmFu8SN1EKHOhvo9jmv1qp0 # 定时任务cron表达式 task: cron: diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index bec1abf..38ee493 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - +