This is an automated email from the ASF dual-hosted git repository.

caishunfeng pushed a commit to branch 2.0.3-prepare
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/2.0.3-prepare by this push:
     new 7b1744b  cherry-pick DingTalk alert plugin adds signature. #7805 
(#7959)
7b1744b is described below

commit 7b1744baf505e4b1a8f5737f0a4cd1fa6286c10c
Author: Kerwin <[email protected]>
AuthorDate: Wed Jan 12 18:13:55 2022 +0800

    cherry-pick DingTalk alert plugin adds signature. #7805 (#7959)
---
 .../dingtalk/DingTalkAlertChannelFactory.java      | 68 +++++++++++++---------
 .../alert/dingtalk/DingTalkParamsConstants.java    |  8 ++-
 .../plugin/alert/dingtalk/DingTalkSender.java      | 57 +++++++++++++++---
 .../dingtalk/DingTalkAlertChannelFactoryTest.java  |  2 +-
 .../src/js/module/i18n/locale/en_US.js             |  1 +
 .../src/js/module/i18n/locale/zh_CN.js             |  3 +-
 6 files changed, 102 insertions(+), 37 deletions(-)

diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
index 2050eaa..01b9060 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactory.java
@@ -50,46 +50,62 @@ public final class DingTalkAlertChannelFactory implements 
AlertChannelFactory {
 
     @Override
     public List<PluginParams> params() {
-        InputParam webHookParam = 
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, 
DingTalkParamsConstants.DING_TALK_WEB_HOOK)
+
+        InputParam webHookParam = InputParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK, 
DingTalkParamsConstants.DING_TALK_WEB_HOOK)
                 .addValidate(Validate.newBuilder()
                         .setRequired(true)
                         .build())
                 .build();
-        InputParam keywordParam = 
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, 
DingTalkParamsConstants.DING_TALK_KEYWORD)
+
+        InputParam keywordParam = InputParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD, 
DingTalkParamsConstants.DING_TALK_KEYWORD)
                 .addValidate(Validate.newBuilder()
-                        .setRequired(true)
+                        .setRequired(false)
                         .build())
                 .build();
-        RadioParam isEnableProxy =
-                
RadioParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, 
DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE)
-                        .addParamsOptions(new ParamsOptions(STRING_YES, 
STRING_TRUE, false))
-                        .addParamsOptions(new ParamsOptions(STRING_NO, 
STRING_FALSE, false))
-                        .setValue(STRING_TRUE)
-                        .addValidate(Validate.newBuilder()
-                                .setRequired(false)
-                                .build())
-                        .build();
-        InputParam proxyParam =
-                
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY, 
DingTalkParamsConstants.DING_TALK_PROXY)
-                        .addValidate(Validate.newBuilder()
-                                .setRequired(false).build())
-                        .build();
 
-        InputParam portParam = 
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PORT, 
DingTalkParamsConstants.DING_TALK_PORT)
+        InputParam secretParam = InputParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_SECRET, 
DingTalkParamsConstants.DING_TALK_SECRET)
                 .addValidate(Validate.newBuilder()
-                        .setRequired(false).build())
+                        .setRequired(false)
+                        .build())
+                .build();
+        RadioParam isEnableProxy = RadioParam
+                
.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE, 
DingTalkParamsConstants.DING_TALK_PROXY_ENABLE)
+                .addParamsOptions(new ParamsOptions(STRING_YES, STRING_TRUE, 
false))
+                .addParamsOptions(new ParamsOptions(STRING_NO, STRING_FALSE, 
false))
+                .setValue(STRING_FALSE)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+        InputParam proxyParam = InputParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PROXY, 
DingTalkParamsConstants.DING_TALK_PROXY)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+
+        InputParam portParam = InputParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PORT, 
DingTalkParamsConstants.DING_TALK_PORT)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
                 .build();
 
-        InputParam userParam =
-                
InputParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_USER, 
DingTalkParamsConstants.DING_TALK_USER)
-                        .addValidate(Validate.newBuilder()
-                                .setRequired(false).build())
-                        .build();
-        PasswordParam passwordParam = 
PasswordParam.newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, 
DingTalkParamsConstants.DING_TALK_PASSWORD)
+        InputParam userParam = InputParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_USER, 
DingTalkParamsConstants.DING_TALK_USER)
+                .addValidate(Validate.newBuilder()
+                        .setRequired(false)
+                        .build())
+                .build();
+        PasswordParam passwordParam = PasswordParam
+                .newBuilder(DingTalkParamsConstants.NAME_DING_TALK_PASSWORD, 
DingTalkParamsConstants.DING_TALK_PASSWORD)
                 .setPlaceholder("if enable use authentication, you need input 
password")
                 .build();
 
-        return Arrays.asList(webHookParam, keywordParam, isEnableProxy, 
proxyParam, portParam, userParam, passwordParam);
+        return Arrays.asList(webHookParam, keywordParam, secretParam, 
isEnableProxy, proxyParam, portParam, userParam, passwordParam);
     }
 
 }
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
index 3042db6..fa47b0c 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
@@ -18,12 +18,18 @@
 package org.apache.dolphinscheduler.plugin.alert.dingtalk;
 
 public final class DingTalkParamsConstants {
+
     static final String DING_TALK_PROXY_ENABLE = "isEnableProxy";
+    static final String NAME_DING_TALK_PROXY_ENABLE = "IsEnableProxy";
+
     static final String DING_TALK_WEB_HOOK = "webhook";
     static final String NAME_DING_TALK_WEB_HOOK = "WebHook";
     static final String DING_TALK_KEYWORD = "keyword";
     static final String NAME_DING_TALK_KEYWORD = "Keyword";
-    static final String NAME_DING_TALK_PROXY_ENABLE = "IsEnableProxy";
+
+    static final String DING_TALK_SECRET = "secret";
+    static final String NAME_DING_TALK_SECRET = "Secret";
+
     static final String DING_TALK_PROXY = "proxy";
     static final String NAME_DING_TALK_PROXY = "Proxy";
     static final String DING_TALK_PORT = "port";
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
index f5d5f14..eeca8c0 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
@@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.plugin.alert.dingtalk;
 import org.apache.dolphinscheduler.alert.api.AlertResult;
 import org.apache.dolphinscheduler.spi.utils.JSONUtils;
 
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.binary.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpHost;
@@ -36,16 +37,30 @@ import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 
 import java.io.IOException;
+import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+/**
+ * <p>
+ *     https://open.dingtalk.com/document/robots/custom-robot-access
+ *     
https://open.dingtalk.com/document/robots/customize-robot-security-settings
+ * </p>
+ */
 public final class DingTalkSender {
-    private static final Logger log = 
org.slf4j.LoggerFactory.getLogger(DingTalkSender.class);
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DingTalkSender.class);
+
     private final String url;
     private final String keyword;
+    private final String secret;
     private final Boolean enableProxy;
 
     private String proxy;
@@ -59,6 +74,7 @@ public final class DingTalkSender {
     DingTalkSender(Map<String, String> config) {
         url = config.get(DingTalkParamsConstants.NAME_DING_TALK_WEB_HOOK);
         keyword = config.get(DingTalkParamsConstants.NAME_DING_TALK_KEYWORD);
+        secret = config.get(DingTalkParamsConstants.NAME_DING_TALK_SECRET);
         enableProxy = 
Boolean.valueOf(config.get(DingTalkParamsConstants.NAME_DING_TALK_PROXY_ENABLE));
         if (Boolean.TRUE.equals(enableProxy)) {
             port = 
Integer.parseInt(config.get(DingTalkParamsConstants.NAME_DING_TALK_PORT));
@@ -109,13 +125,13 @@ public final class DingTalkSender {
 
         if (null == result) {
             alertResult.setMessage("send ding talk msg error");
-            log.info("send ding talk msg error,ding talk server resp is null");
+            logger.info("send ding talk msg error,ding talk server resp is 
null");
             return alertResult;
         }
         DingTalkSendMsgResponse sendMsgResponse = 
JSONUtils.parseObject(result, DingTalkSendMsgResponse.class);
         if (null == sendMsgResponse) {
             alertResult.setMessage("send ding talk msg fail");
-            log.info("send ding talk msg error,resp error");
+            logger.info("send ding talk msg error,resp error");
             return alertResult;
         }
         if (sendMsgResponse.errcode == 0) {
@@ -124,7 +140,7 @@ public final class DingTalkSender {
             return alertResult;
         }
         alertResult.setMessage(String.format("alert send ding talk msg error : 
%s", sendMsgResponse.getErrmsg()));
-        log.info("alert send ding talk msg error : {}", 
sendMsgResponse.getErrmsg());
+        logger.info("alert send ding talk msg error : {}", 
sendMsgResponse.getErrmsg());
         return alertResult;
     }
 
@@ -134,7 +150,7 @@ public final class DingTalkSender {
             String resp = sendMsg(title, content);
             return checkSendDingTalkSendMsgResult(resp);
         } catch (Exception e) {
-            log.info("send ding talk alert msg  exception : {}", 
e.getMessage());
+            logger.info("send ding talk alert msg  exception : {}", 
e.getMessage());
             alertResult = new AlertResult();
             alertResult.setStatus("false");
             alertResult.setMessage("send ding talk alert fail.");
@@ -144,8 +160,18 @@ public final class DingTalkSender {
 
     private String sendMsg(String title, String content) throws IOException {
 
-        String msgToJson = textToJsonString(title + content + "#" + keyword);
-        HttpPost httpPost = constructHttpPost(url, msgToJson);
+        StringBuilder text = new StringBuilder();
+        if 
(org.apache.dolphinscheduler.spi.utils.StringUtils.isNotBlank(keyword)) {
+            text.append(keyword);
+            text.append(":");
+        }
+        text.append(title);
+        text.append("\n");
+        text.append(content);
+
+        String msgToJson = textToJsonString(text.toString());
+
+        HttpPost httpPost = 
constructHttpPost(org.apache.dolphinscheduler.spi.utils.StringUtils.isBlank(secret)
 ? url : generateSignedUrl(), msgToJson);
 
         CloseableHttpClient httpClient;
         if (Boolean.TRUE.equals(enableProxy)) {
@@ -166,13 +192,28 @@ public final class DingTalkSender {
             } finally {
                 response.close();
             }
-            log.info("Ding Talk send title :{},content : {}, resp: {}", title, 
content, resp);
+            logger.info("Ding Talk send title :{},content : {}, resp: {}", 
title, content, resp);
             return resp;
         } finally {
             httpClient.close();
         }
     }
 
+    private String generateSignedUrl() {
+        Long timestamp = System.currentTimeMillis();
+        String stringToSign = timestamp + "\n" + secret;
+        String sign = org.apache.dolphinscheduler.spi.utils.StringUtils.EMPTY;
+        try {
+            Mac mac = Mac.getInstance("HmacSHA256");
+            mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), 
"HmacSHA256"));
+            byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
+            sign = URLEncoder.encode(new 
String(Base64.encodeBase64(signData)),"UTF-8");
+        } catch (Exception e) {
+            logger.error("generate sign error, message:{}", e);
+        }
+        return url + "&timestamp=" + timestamp + "&sign=" + sign;
+    }
+
     static final class DingTalkSendMsgResponse {
         private Integer errcode;
         private String errmsg;
diff --git 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
index 8b78042..9905195 100644
--- 
a/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
+++ 
b/dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-dingtalk/src/test/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkAlertChannelFactoryTest.java
@@ -32,7 +32,7 @@ public class DingTalkAlertChannelFactoryTest {
         DingTalkAlertChannelFactory dingTalkAlertChannelFactory = new 
DingTalkAlertChannelFactory();
         List<PluginParams> params = dingTalkAlertChannelFactory.params();
         JSONUtils.toJsonString(params);
-        Assert.assertEquals(7, params.size());
+        Assert.assertEquals(8, params.size());
     }
 
     @Test
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js 
b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index e7abaf6..c749142 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
@@ -726,6 +726,7 @@ export default {
   WebHook: 'WebHook',
   webHook: 'WebHook',
   Keyword: 'Keyword',
+  Secret: 'Secret',
   Proxy: 'Proxy',
   receivers: 'Receivers',
   receiverCcs: 'ReceiverCcs',
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js 
b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index 70a71f1..4d62bb9 100644
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
@@ -724,7 +724,8 @@ export default {
   IsEnableProxy: '启用代理',
   WebHook: 'Web钩子',
   webHook: 'Web钩子',
-  Keyword: '密钥',
+  Keyword: '关键词',
+  Secret: '密钥',
   Proxy: '代理',
   receivers: '收件人',
   receiverCcs: '抄送人',

Reply via email to