From 942616d5dfde2664649c164ca247b2efcc5759c1 Mon Sep 17 00:00:00 2001
From: frankfreedom <772598220@qq.com>
Date: Wed, 19 Aug 2020 00:18:12 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E8=B0=83=E5=BA=A6--=E6=9D=83?=
 =?UTF-8?q?=E9=99=90=E6=A0=A1=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/web/js/userparams-manager.js          |  3 +
 .../az-webank-system-manager-zh_CN.json       |  2 +-
 .../azkaban-web-server-en_US.json             |  4 +-
 .../azkaban-web-server-zh_CN.json             |  4 +-
 .../src/conf/azkaban.properties               |  2 +
 .../webapp/servlet/ExecutorServlet.java       |  7 +--
 .../webapp/servlet/HistoryServlet.java        |  1 -
 .../webapp/servlet/ProjectManagerServlet.java | 57 +++++++++++++++++++
 .../webapp/servlet/ScheduleServlet.java       |  2 +
 .../src/web/js/azkaban/util/schedule.js       | 50 ++++++++++++++++
 .../azkaban/view/schedule-flow-edit-dialog.js | 46 ++++++++-------
 11 files changed, 149 insertions(+), 29 deletions(-)

diff --git a/az-webank-user-params/src/web/js/userparams-manager.js b/az-webank-user-params/src/web/js/userparams-manager.js
index 4b21e24..3f54ee9 100644
--- a/az-webank-user-params/src/web/js/userparams-manager.js
+++ b/az-webank-user-params/src/web/js/userparams-manager.js
@@ -657,6 +657,9 @@ azkaban.UpdateDepartmentGroupView = Backbone.View.extend({
         };
         var model = this.model;
         var successHandler = function (data) {
+            if (data.status && data.status == 'error') {
+                return false
+            }
             if (data.error) {
                 $("#update-department-group-modal-error-msg").show();
                 $("#update-department-group-modal-error-msg").text(data.error);
diff --git a/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/az-webank-system-manager-zh_CN.json b/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/az-webank-system-manager-zh_CN.json
index 840650b..274b040 100755
--- a/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/az-webank-system-manager-zh_CN.json
+++ b/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/az-webank-system-manager-zh_CN.json
@@ -24,7 +24,7 @@
     "invalidAddRealNameUserProxy": "新增用户失败,实名用户仅可添加自己作为代理,请将代理用户选项置为空,或者将代理用户设置为:",
     "invalidUpdateRealNameUserProxy": "更新用户失败,实名用户仅可添加自己作为代理,请将代理用户选项置为空,或者将代理用户设置为:",
     "invalidUpdateSystemUserProxy": "更新用户失败,系统用户仅可添加自己作为代理,请将代理用户选项置为空,或者将代理用户设置为:",
-    "invalidName": "]输入不合法,合法用户名示例如下(大小写敏感):运维账号:WTSS_纯英文部门代码_编号(WTSS_DBDP_01); 普通系统账号:hduser编号(hduser01).",
+    "invalidName": "]输入不合法,合法用户名示例如下(大小写敏感):运维账号:WTSS_纯英文部门代码_编号(WTSS_DBDP_01); 普通系统账号:hduser编号(hduser01)",
     "existDep": "该部门已存在.",
     "noParentDep": "父部门不存在.",
     "plsInputDepId": "请输入部门ID.",
diff --git a/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-en_US.json b/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-en_US.json
index 400edde..f1a149f 100755
--- a/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-en_US.json
+++ b/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-en_US.json
@@ -734,7 +734,8 @@
     "haveHisReRun": "History Re-Run job have been existed.",
     "submitHisReRunSuccess": " submit history Re-Run job success.",
     "submitHisReRunFail": " submit history Re-Run job failed.",
-    "resolveSlaFailed": "Resolve Sla alert settings failed."
+    "resolveSlaFailed": "Resolve Sla alert settings failed.",
+    "permissionForAction": "You have no Execute or Schedule permission for project: "
   },
   "azkaban.webapp.servlet.ProjectManagerServlet": {
     "project": "Project[",
@@ -744,6 +745,7 @@
     "flow": "Flow[",
     "job": "Job[",
     "config": "Configuration[",
+    "permissionForAction": "You have no Execute or Schedule permission for project: ",
     "uploadJobCoverFieldError": "Upload job cover field error",
     "getLastRunFailed": "Get the last flow execution  Failed",
     "noPerAccessProject": "No permission access to this project: ",
diff --git a/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-zh_CN.json b/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-zh_CN.json
index 525a642..8b5d1c9 100755
--- a/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-zh_CN.json
+++ b/azkaban-common/src/main/resources/com.webank.wedatasphere.schedulis.i18n.conf/azkaban-web-server-zh_CN.json
@@ -734,7 +734,8 @@
     "haveHisReRun": "历史重跑任务已存在.",
     "submitHisReRunSuccess": " 提交历史重跑任务成功.",
     "submitHisReRunFail": " 提交历史重跑任务失败.",
-    "resolveSlaFailed": "解析sla告警设置失败."
+    "resolveSlaFailed": "解析sla告警设置失败.",
+    "permissionForAction": "你没有权限执行或者调度这个项目: "
   },
   "azkaban.webapp.servlet.ProjectManagerServlet": {
     "project": "项目  ",
@@ -744,6 +745,7 @@
     "flow": " 工作流 ",
     "job": "任务 ",
     "config": "配置 ",
+    "permissionForAction": "你没有权限执行或者调度这个项目: ",
     "uploadJobCoverFieldError": "上传任务覆盖属性错误.",
     "getLastRunFailed": "获取项目最后一次执行工作流失败.",
     "noPerAccessProject": "没有权限查看项目 ",
diff --git a/azkaban-web-server/src/conf/azkaban.properties b/azkaban-web-server/src/conf/azkaban.properties
index 06a8321..52bad7a 100644
--- a/azkaban-web-server/src/conf/azkaban.properties
+++ b/azkaban-web-server/src/conf/azkaban.properties
@@ -66,6 +66,8 @@ lockdown.create.projects=false
 
 wtss.project.privilege.check=false
 
+department.maintainer.check.switch=true
+
 cache.directory=cache
 
 # JMX stats
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ExecutorServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ExecutorServlet.java
index 5f317f3..d3a8e15 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ExecutorServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ExecutorServlet.java
@@ -458,8 +458,9 @@ private void ajaxUpdateQueueProcessor(final HttpServletRequest req, final HttpSe
     private void ajaxFetchscheduledflowgraphNew(final String projectName, final String flowName,
         final HashMap<String, Object> ret, final User user) throws ServletException {
         final Project project = getProjectAjaxByPermission(ret, projectName, user, Type.EXECUTE);
+        Map<String, String> stringStringMap = loadExecutorServletI18nData();
         if (project == null) {
-            ret.put("error", "Project '" + projectName + "' doesn't exist.");
+            ret.put("error", stringStringMap.get("permissionForAction") + projectName);
             return;
         }
         try {
@@ -2359,10 +2360,6 @@ private Map<String, Object> repeatDateCompute(final JsonObject jsonObject) {
         List<Long> runDateTimeList = GsonUtils.jsonToJavaObject(jsonObject.getAsJsonArray("runDateTimeList"), new TypeToken<List<Long>>() {}.getType());
         timeList.addAll(runDateTimeList);
         try {
-//      String month = getParam(req, "month");
-//      String day = getParam(req, "day");
-//      String hour = "0";//getParam(req, "hour");
-//      String min = "0";//getParam(req, "min");
             String recoverNum = jsonObject.get("recoverNum").getAsString();
             String recoverInterval = jsonObject.get("recoverInterval").getAsString();
 
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/HistoryServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/HistoryServlet.java
index 14d1632..67e1de3 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/HistoryServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/HistoryServlet.java
@@ -27,7 +27,6 @@
 import azkaban.utils.Utils;
 import azkaban.utils.WebUtils;
 import azkaban.webapp.AzkabanWebServer;
-
 import com.webank.wedatasphere.schedulis.common.i18nutils.LoadJsonUtils;
 import com.webank.wedatasphere.schedulis.common.jobExecutor.utils.SystemBuiltInParamJodeTimeUtils;
 import com.webank.wedatasphere.schedulis.common.system.SystemManager;
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 8447ceb..0c2cba7 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -420,6 +420,9 @@ private void handleAJAXAction(final HttpServletRequest req,
                 }else if (ajaxName.equals("checkRunningPageKillFlowPermission")) {
                     // 检查用户Kill运行中的工作流权限
                     ajaxCheckRunningPageKillFlowPermission(req, resp, ret, session);
+                } else if (ajaxName.equals("checkUserSwitchScheduleFlowPermission")) {
+                    // 检查用户开启或关闭定时调度权限
+                    ajaxcheckUserSwitchScheduleFlowPermission(req, resp, ret, session);
                 } else {
                     ret.put("error", "Cannot execute command " + ajaxName);
                 }
@@ -700,6 +703,7 @@ private void ajaxCheckUserDeleteScheduleFlowPermission(HttpServletRequest req, H
                 final User user = session.getUser();
                 if (wtss_project_privilege_check) {
                     int deleteScheduleFlowFlag = checkUserOperatorFlag(user);
+                    resultMap.put("deleteScheduleFlowFlag", deleteScheduleFlowFlag);
                     logger.info("current user delete schedule flow permission flag is deleteScheduleFlowFlag=" + deleteScheduleFlowFlag);
                 } else {
                     resultMap.put("deleteScheduleFlowFlag", 1);
@@ -892,6 +896,59 @@ private void ajaxCheckDeleteScheduleInDescriptionFlagPermission(HttpServletReque
     }
 
 
+    /**
+     * 检查用户开启或关闭定时调度权限
+     *
+     * @param req
+     * @param resp
+     * @param resultMap
+     * @param session   wtss_project_privilege_check
+     */
+    private void ajaxcheckUserSwitchScheduleFlowPermission(HttpServletRequest req, HttpServletResponse resp,
+        HashMap<String, Object> resultMap, Session session) {
+
+        try {
+            if (session != null) {
+                final String projectName = getParam(req, "project");
+                final User user = session.getUser();
+                final Project project = getProjectAjaxByPermission(resultMap, projectName, user, Type.SCHEDULE);
+                Map<String, String> stringStringMap = loadProjectManagerServletI18nData();
+                if (project == null) {
+                    resultMap.put("error", stringStringMap.get("permissionForAction") + projectName);
+                    resultMap.put("switchScheduleFlowFlag", 3);
+                    return;
+                }
+                if (wtss_project_privilege_check) {
+                    int switchScheduleFlowFlag = checkUserOperatorFlag(user);
+                    resultMap.put("switchScheduleFlowFlag", switchScheduleFlowFlag);
+                    logger.info("current user active schedule flow permission flag is switchScheduleFlowFlag=" + switchScheduleFlowFlag);
+                } else {
+                    resultMap.put("switchScheduleFlowFlag", 1);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Failed to find current user active schedule flow flow permission flag, caused by:{}", e);
+        }
+    }
+
+    protected Project getProjectAjaxByPermission(final Map<String, Object> ret, final String projectName,
+                                                 final User user, final Permission.Type type) {
+        final Project project = this.projectManager.getProject(projectName);
+
+        Map<String, String> dataMap = loadProjectManagerServletI18nData();
+
+        if (project == null) {
+            ret.put("error", dataMap.get("project") + projectName + dataMap.get("notExist"));
+        } else if (!hasPermission(project, user, type)) {
+            ret.put("error", "User " + user.getUserId() + " doesn't have " + project.getName() + " of " + type.name()
+                    + " permissions, please contact with the project creator.");
+        } else {
+            return project;
+        }
+
+        return null;
+    }
+
     /**
      * 检查用户KILL正在运行页面flow权限
      *
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ScheduleServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ScheduleServlet.java
index e4d2036..18d5ce8 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ScheduleServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ScheduleServlet.java
@@ -1022,6 +1022,8 @@ private boolean scheduleAllFlow(Project project, Flow flow, Map<String, Object>
       otherOptions.put("successAlertLevel", json.get("successAlertLevel").getAsString());
     }
 
+    otherOptions.put("activeFlag", true);
+
     try {
       //设置告警用户部门信息
       String userDep = transitionService.getUserDepartmentByUsername(user.getUserId());
diff --git a/azkaban-web-server/src/web/js/azkaban/util/schedule.js b/azkaban-web-server/src/web/js/azkaban/util/schedule.js
index 6d9d5d7..9b43513 100644
--- a/azkaban-web-server/src/web/js/azkaban/util/schedule.js
+++ b/azkaban-web-server/src/web/js/azkaban/util/schedule.js
@@ -105,6 +105,56 @@ function editScheduleClick(scheduleId, projectName, flowName, cronExpression) {
 
 }
 
+// 定时调度页面, 定时调度工作流列表, 对显示的调度任务点击调度开启关闭
+function switchScheduleClick (index, scheduleId, projectName, flowName, cronExpression) {
+
+  // 需要校验是否具有修改项目调度权限 1:允许, 2:不允许
+  var requestURL = "/manager?ajax=checkUserSwitchScheduleFlowPermission&project=" + projectName;
+  $.ajax({
+    url: requestURL,
+    type: "get",
+    async: false,
+    dataType: "json",
+    success: function (data) {
+      if (data["switchScheduleFlowFlag"] == 1) {
+        console.log("click switch schedule button.");
+        var currentActiveFlag = document.getElementById("schedules-tbody").rows[index].cells[8].innerHTML;
+        console.log("currentActiveFlag=" + currentActiveFlag);
+        var destActiveFlag = false;
+        if (currentActiveFlag == "false") {
+          destActiveFlag = true;
+        }
+
+        var scheduleActiveData = {
+          scheduleId: scheduleId,
+          ajax: "setScheduleActiveFlag",
+          activeFlag: destActiveFlag
+        };
+
+        var scheduleURL = "/schedule"
+        var successHandler = function (data) {
+          if (data.error) {
+            alert(data.error);
+          } else {
+            // 触发变更就行, 不是刷新所有页面
+            scheduleListView.handlePageChange();
+          }
+        };
+        $.post(scheduleURL, scheduleActiveData, successHandler, "json");
+      } else if (data["switchScheduleFlowFlag"] == 2) {
+          $('#user-operator-schedule-flow-permit-panel').modal();
+          $('#title-user-operator-schedule-flow-permit').text(wtssI18n.view.scheduleActivePermission);
+          $('#body-user-operator-schedule-flow-permit').html(wtssI18n.view.noScheSwitchConfigPermission);
+      } else if(data["switchScheduleFlowFlag"] == 3){
+          $('#user-operator-schedule-flow-permit-panel').modal();
+          $('#title-user-operator-schedule-flow-permit').text(wtssI18n.view.scheduleActivePermission);
+          $('#body-user-operator-schedule-flow-permit').html(data.error);
+      }
+    }
+  });
+
+}
+
 $(function () {
 
   scheduleView = new azkaban.ScheduleView({
diff --git a/azkaban-web-server/src/web/js/azkaban/view/schedule-flow-edit-dialog.js b/azkaban-web-server/src/web/js/azkaban/view/schedule-flow-edit-dialog.js
index 3582829..9f03006 100644
--- a/azkaban-web-server/src/web/js/azkaban/view/schedule-flow-edit-dialog.js
+++ b/azkaban-web-server/src/web/js/azkaban/view/schedule-flow-edit-dialog.js
@@ -302,29 +302,35 @@ azkaban.FlowScheduleDialogView = Backbone.View.extend({
     };
     var self = this;
     var successHandler = function (data) {
-      console.log("data fetched");
-      graphModel.addFlow(data);
+      if (data.error) {
+        $('#user-operator-schedule-flow-permit-panel').modal();
+        $('#title-user-operator-schedule-flow-permit').text(wtssI18n.view.scheduleConfigPermission);
+        $('#body-user-operator-schedule-flow-permit').html(data.error);
+      } else {
+        console.log("data fetched");
+        graphModel.addFlow(data);
 
-      if (exgraph) {
-        self.assignInitialStatus(data, exgraph);
-      }
+        if (exgraph) {
+          self.assignInitialStatus(data, exgraph);
+        }
 
-      // Auto disable jobs that are finished.
-      disableFinishedJobs(data);
-      executingSvgGraphView = new azkaban.SvgGraphView({
-        el: $('#schedule-flow-executing-graph'),
-        model: graphModel,
-        render: false,
-        rightClick: {
-          "node": expanelNodeClickCallback,
-          "edge": expanelEdgeClickCallback,
-          "graph": expanelGraphClickCallback
-        },
-        tooltipcontainer: "#schedule-svg-div-custom"
-      });
+        // Auto disable jobs that are finished.
+        disableFinishedJobs(data);
+        executingSvgGraphView = new azkaban.SvgGraphView({
+          el: $('#schedule-flow-executing-graph'),
+          model: graphModel,
+          render: false,
+          rightClick: {
+            "node": expanelNodeClickCallback,
+            "edge": expanelEdgeClickCallback,
+            "graph": expanelGraphClickCallback
+          },
+          tooltipcontainer: "#schedule-svg-div-custom"
+        });
 
-      if (callback) {
-        callback.call(this);
+        if (callback) {
+          callback.call(this);
+        }
       }
     };
     $.get(requestURL, requestData, successHandler, "json");