Просмотр исходного кода

Merge branch 'feat/growi-bot' into imprv/5878-make-component-for-with-proxy-accordion

kaori 4 лет назад
Родитель
Сommit
78e54b1820

+ 3 - 3
.github/workflows/ci.yml

@@ -12,9 +12,9 @@ on:
       - .eslint*
       - .prettier*
       - .stylelint*
-      - config
-      - resource
-      - src
+      - config/**
+      - resource/**
+      - src/**
       - package.json
       - yarn.lock
 

+ 1 - 0
resource/locales/en_US/admin/admin.json

@@ -274,6 +274,7 @@
       "impossible": "Impossible"
     },
     "bot_reset_successful": "Bot settings have been reset.",
+    "bot_all_reset_successful": "All Bot settings have been reset.",
     "copied_to_clipboard": "Copied to clipboard",
     "set_scope": "Please set up Bot Token Scopes from Slack settings",
     "modal": {

+ 1 - 0
resource/locales/ja_JP/admin/admin.json

@@ -272,6 +272,7 @@
       "impossible": "不可"
     },
     "bot_reset_successful": "Botの設定を消去しました。",
+    "bot_all_reset_successful": "全ての Bot の設定を消去しました。",
     "copied_to_clipboard": "クリップボードにコピーされました。",
     "set_scope": "Slackの設定画面からBot Token Scopeを設定してください",
     "modal": {

+ 1 - 0
resource/locales/zh_CN/admin/admin.json

@@ -282,6 +282,7 @@
       "impossible": "不可能"
     },
     "bot_reset_successful": "删除了BOT设置。",
+    "bot_all_reset_successful": "所有的 Bot 设置都被清除了。",
     "copied_to_clipboard": "它已复制到剪贴板。",
     "set_scope": "在Slack设置页面中配置Bot Token Scope。",
     "modal": {

+ 2 - 4
src/client/js/components/Admin/SlackIntegration/CustomBotWithProxySettings.jsx

@@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next';
 import PropTypes from 'prop-types';
 import loggerFactory from '@alias/logger';
 import AppContainer from '../../../services/AppContainer';
-import AdminAppContainer from '../../../services/AdminAppContainer';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { toastSuccess, toastError } from '../../../util/apiNotification';
 import CustomBotWithProxyIntegrationCard from './CustomBotWithProxyIntegrationCard';
@@ -15,7 +14,7 @@ const logger = loggerFactory('growi:SlackBotSettings');
 
 const CustomBotWithProxySettings = (props) => {
   // eslint-disable-next-line no-unused-vars
-  const { appContainer, adminAppContainer } = props;
+  const { appContainer } = props;
   const [isDeleteConfirmModalShown, setIsDeleteConfirmModalShown] = useState(false);
   const [proxyUri, setProxyUri] = useState(null);
 
@@ -140,11 +139,10 @@ const CustomBotWithProxySettings = (props) => {
   );
 };
 
-const CustomBotWithProxySettingsWrapper = withUnstatedContainers(CustomBotWithProxySettings, [AppContainer, AdminAppContainer]);
+const CustomBotWithProxySettingsWrapper = withUnstatedContainers(CustomBotWithProxySettings, [AppContainer]);
 
 CustomBotWithProxySettings.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
 };
 
 export default CustomBotWithProxySettingsWrapper;

+ 13 - 1
src/client/js/components/Admin/SlackIntegration/SlackIntegration.jsx

@@ -28,6 +28,7 @@ const SlackIntegration = (props) => {
   const [slackWSNameInWithoutProxy, setSlackWSNameInWithoutProxy] = useState(null);
   const [isDeleteConfirmModalShown, setIsDeleteConfirmModalShown] = useState(false);
 
+
   const fetchSlackIntegrationData = useCallback(async() => {
     try {
       const { data } = await appContainer.apiv3.get('/slack-integration-settings');
@@ -51,6 +52,17 @@ const SlackIntegration = (props) => {
     }
   }, [appContainer.apiv3]);
 
+  const resetAllSettings = async() => {
+    try {
+      await appContainer.apiv3.delete('/slack-integration-settings/bot-type');
+      fetchSlackIntegrationData();
+      toastSuccess(t('admin:slack_integration.bot_all_reset_successful'));
+    }
+    catch (error) {
+      toastError(error);
+    }
+  };
+
   const resetWithOutSettings = async() => {
     try {
       await appContainer.apiv3.put('/slack-integration-settings/bot-type', { currentBotType: 'customBotWithoutProxy' });
@@ -137,11 +149,11 @@ const SlackIntegration = (props) => {
         onCancelClick={cancelBotChangeHandler}
       />
 
-      {/* TODO add onClickDeleteButton */}
       <DeleteSlackBotSettingsModal
         isResetAll
         isOpen={isDeleteConfirmModalShown}
         onClose={() => setIsDeleteConfirmModalShown(false)}
+        onClickDeleteButton={resetAllSettings}
       />
 
       <div className="selecting-bot-type mb-5">

+ 120 - 95
src/server/routes/apiv3/slack-integration-settings.js

@@ -2,6 +2,7 @@ const mongoose = require('mongoose');
 const express = require('express');
 const { body } = require('express-validator');
 const axios = require('axios');
+const urljoin = require('url-join');
 const loggerFactory = require('@alias/logger');
 
 const { getConnectionStatuses } = require('@growi/slack');
@@ -15,7 +16,7 @@ const router = express.Router();
 /**
  * @swagger
  *  tags:
- *    name: SlackIntegration
+ *    name: SlackIntegrationSettings
  */
 
 /**
@@ -23,14 +24,9 @@ const router = express.Router();
  *
  *  components:
  *    schemas:
- *      CustomBotWithoutProxy:
- *        description: CustomBotWithoutProxy
- *        type: object
+ *      BotType:
+ *        description: BotType
  *        properties:
- *          slackSigningSecret:
- *            type: string
- *          slackBotToken:
- *            type: string
  *          currentBotType:
  *            type: string
  *      SlackIntegration:
@@ -49,6 +45,8 @@ module.exports = (crowi) => {
   const csrf = require('../../middlewares/csrf')(crowi);
   const apiV3FormValidator = require('../../middlewares/apiv3-form-validator')(crowi);
 
+  const SlackAppIntegration = mongoose.model('SlackAppIntegration');
+
   const validator = {
     BotType: [
       body('currentBotType').isString(),
@@ -82,9 +80,9 @@ module.exports = (crowi) => {
 
   async function getConnectionStatusesFromProxy(tokens) {
     const csv = tokens.join(',');
+    const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:serverUri');
 
-    // TODO: retrieve proxy url from configManager
-    const result = await axios.get('http://localhost:8080/g2s/connection-status', {
+    const result = await axios.get(urljoin(proxyUri, '/g2s/connection-status'), {
       headers: {
         'x-growi-gtop-tokens': csv,
       },
@@ -96,7 +94,7 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /slack-integration/:
+   *    /slack-integration-settings/:
    *      get:
    *        tags: [SlackBotSettingParams]
    *        operationId: getSlackBotSettingParams
@@ -107,6 +105,7 @@ module.exports = (crowi) => {
    *            description: Succeeded to get info.
    */
   router.get('/', accessTokenParser, loginRequiredStrictly, adminRequired, async(req, res) => {
+
     const { configManager } = crowi;
     const currentBotType = configManager.getConfig('crowi', 'slackbot:currentBotType');
 
@@ -119,14 +118,10 @@ module.exports = (crowi) => {
       settings.slackBotToken = configManager.getConfig('crowi', 'slackbot:token');
     }
     else {
-      // settings.proxyUriEnvVars = ;
-      // settings.proxyUri = ;
-      // settings.tokenPtoG = ;
-      // settings.tokenGtoP = ;
+      settings.proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:serverUri');
+      settings.proxyUriEnvVars = configManager.getConfigFromEnvVars('crowi', 'slackbot:serverUri');
     }
 
-    // TODO: try-catch
-
     // retrieve connection statuses
     let connectionStatuses;
     if (currentBotType == null) {
@@ -136,13 +131,35 @@ module.exports = (crowi) => {
       const token = settings.slackBotToken;
       // check the token is not null
       if (token != null) {
-        connectionStatuses = await getConnectionStatuses([token]);
+        try {
+          connectionStatuses = await getConnectionStatuses([token]);
+        }
+        catch (error) {
+          const msg = 'Error occured in getting connection statuses';
+          logger.error('Error', error);
+          return res.apiv3Err(new ErrorV3(msg, 'get-connection-failed'), 500);
+        }
       }
     }
     else {
-      // TODO: retrieve tokenGtoPs from DB
-      const tokenGtoPs = ['gtop1'];
-      connectionStatuses = (await getConnectionStatusesFromProxy(tokenGtoPs)).connectionStatuses;
+      const proxyUri = settings.proxyUri;
+
+      if (proxyUri != null) {
+        try {
+          const slackAppIntegrations = await SlackAppIntegration.find();
+          settings.slackAppIntegrations = slackAppIntegrations;
+
+          if (slackAppIntegrations.length > 0) {
+            const tokenGtoPs = slackAppIntegrations.map(slackAppIntegration => slackAppIntegration.tokenGtoP);
+            connectionStatuses = (await getConnectionStatusesFromProxy(tokenGtoPs)).connectionStatuses;
+          }
+        }
+        catch (error) {
+          const msg = 'Error occured in getting connection statuses';
+          logger.error('Error', error);
+          return res.apiv3Err(new ErrorV3(msg, 'get-connection-failed'), 500);
+        }
+      }
     }
 
     return res.apiv3({ currentBotType, settings, connectionStatuses });
@@ -151,7 +168,7 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /slack-integration/:
+   *    /slack-integration-settings/:
    *      put:
    *        tags: [SlackIntegration]
    *        operationId: putSlackIntegration
@@ -167,101 +184,112 @@ module.exports = (crowi) => {
    *           200:
    *             description: Succeeded to put Slack Integration setting.
    */
-  router.put('/',
-    accessTokenParser, loginRequiredStrictly, adminRequired, csrf, validator.SlackIntegration, apiV3FormValidator, async(req, res) => {
-      const { currentBotType } = req.body;
+  router.put('/', accessTokenParser, loginRequiredStrictly, adminRequired, csrf, validator.SlackIntegration, apiV3FormValidator, async(req, res) => {
+    const { currentBotType } = req.body;
 
-      const requestParams = {
-        'slackbot:currentBotType': currentBotType,
-      };
+    const requestParams = {
+      'slackbot:currentBotType': currentBotType,
+    };
 
-      try {
-        await updateSlackBotSettings(requestParams);
-        crowi.slackBotService.publishUpdatedMessage();
+    try {
+      await updateSlackBotSettings(requestParams);
+      crowi.slackBotService.publishUpdatedMessage();
 
-        const slackIntegrationSettingsParams = {
-          currentBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType'),
-        };
-        return res.apiv3({ slackIntegrationSettingsParams });
-      }
-      catch (error) {
-        const msg = 'Error occured in updating Slack bot setting';
-        logger.error('Error', error);
-        return res.apiv3Err(new ErrorV3(msg, 'update-SlackIntegrationSetting-failed'), 500);
-      }
-    });
+      const slackIntegrationSettingsParams = {
+        currentBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType'),
+      };
+      return res.apiv3({ slackIntegrationSettingsParams });
+    }
+    catch (error) {
+      const msg = 'Error occured in updating Slack bot setting';
+      logger.error('Error', error);
+      return res.apiv3Err(new ErrorV3(msg, 'update-SlackIntegrationSetting-failed'), 500);
+    }
+  });
 
 
   /**
    * @swagger
    *
-   *    /slack-integration/custom-bot-without-proxy/:
+   *    /slack-integration-settings/bot-type/:
    *      put:
-   *        tags: [CustomBotWithoutProxy]
-   *        operationId: putCustomBotWithoutProxy
-   *        summary: /slack-integration/custom-bot-without-proxy
-   *        description: Put customBotWithoutProxy setting.
+   *        tags: [botType]
+   *        operationId: putBotType
+   *        summary: /slack-integration/bot-type
+   *        description: Put botType setting.
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
    *              schema:
-   *                $ref: '#/components/schemas/CustomBotWithoutProxy'
+   *                $ref: '#/components/schemas/BotType'
    *        responses:
    *           200:
-   *             description: Succeeded to put CustomBotWithoutProxy setting.
+   *             description: Succeeded to put botType setting.
    */
-  router.put('/bot-type',
-    accessTokenParser, loginRequiredStrictly, adminRequired, csrf, validator.BotType, apiV3FormValidator, async(req, res) => {
-      const { currentBotType } = req.body;
-
-      await resetAllBotSettings();
-      const requestParams = { 'slackbot:currentBotType': currentBotType };
+  router.put('/bot-type', accessTokenParser, loginRequiredStrictly, adminRequired, csrf, validator.BotType, apiV3FormValidator, async(req, res) => {
+    const { currentBotType } = req.body;
 
-      try {
-        await updateSlackBotSettings(requestParams);
-        crowi.slackBotService.publishUpdatedMessage();
+    await resetAllBotSettings();
+    const requestParams = { 'slackbot:currentBotType': currentBotType };
 
-        // TODO Impl to delete AccessToken both of Proxy and GROWI when botType changes.
-        const slackBotTypeParam = { slackBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType') };
-        return res.apiv3({ slackBotTypeParam });
-      }
-      catch (error) {
-        const msg = 'Error occured in updating Custom bot setting';
-        logger.error('Error', error);
-        return res.apiv3Err(new ErrorV3(msg, 'update-CustomBotSetting-failed'), 500);
-      }
-    });
+    try {
+      await updateSlackBotSettings(requestParams);
+      crowi.slackBotService.publishUpdatedMessage();
 
-  /*
-    TODO: add swagger by GW-5930
-  */
+      // TODO Impl to delete AccessToken both of Proxy and GROWI when botType changes.
+      const slackBotTypeParam = { slackBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType') };
+      return res.apiv3({ slackBotTypeParam });
+    }
+    catch (error) {
+      const msg = 'Error occured in updating Custom bot setting';
+      logger.error('Error', error);
+      return res.apiv3Err(new ErrorV3(msg, 'update-CustomBotSetting-failed'), 500);
+    }
+  });
 
-  router.delete('/bot-type',
-    accessTokenParser, loginRequiredStrictly, adminRequired, csrf, apiV3FormValidator, async(req, res) => {
+  /**
+   * @swagger
+   *
+   *    /slack-integration/bot-type/:
+   *      delete:
+   *        tags: [botType]
+   *        operationId: deleteBotType
+   *        summary: /slack-integration/bot-type
+   *        description: Delete botType setting.
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/BotType'
+   *        responses:
+   *           200:
+   *             description: Succeeded to delete botType setting.
+   */
+  router.delete('/bot-type', accessTokenParser, loginRequiredStrictly, adminRequired, csrf, apiV3FormValidator, async(req, res) => {
 
-      await resetAllBotSettings();
-      const params = { 'slackbot:currentBotType': null };
+    await resetAllBotSettings();
+    const params = { 'slackbot:currentBotType': null };
 
-      try {
-        await updateSlackBotSettings(params);
-        crowi.slackBotService.publishUpdatedMessage();
+    try {
+      await updateSlackBotSettings(params);
+      crowi.slackBotService.publishUpdatedMessage();
 
-        // TODO Impl to delete AccessToken both of Proxy and GROWI when botType changes.
-        const slackBotTypeParam = { slackBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType') };
-        return res.apiv3({ slackBotTypeParam });
-      }
-      catch (error) {
-        const msg = 'Error occured in updating Custom bot setting';
-        logger.error('Error', error);
-        return res.apiv3Err(new ErrorV3(msg, 'update-CustomBotSetting-failed'), 500);
-      }
-    });
+      // TODO Impl to delete AccessToken both of Proxy and GROWI when botType changes.
+      const slackBotTypeParam = { slackBotType: crowi.configManager.getConfig('crowi', 'slackbot:currentBotType') };
+      return res.apiv3({ slackBotTypeParam });
+    }
+    catch (error) {
+      const msg = 'Error occured in updating Custom bot setting';
+      logger.error('Error', error);
+      return res.apiv3Err(new ErrorV3(msg, 'update-CustomBotSetting-failed'), 500);
+    }
+  });
 
   /**
    * @swagger
    *
-   *    /slack-integration/without-proxy/update-settings/:
+   *    /slack-integration-settings/without-proxy/update-settings/:
    *      put:
    *        tags: [UpdateWithoutProxySettings]
    *        operationId: putWithoutProxySettings
@@ -271,12 +299,13 @@ module.exports = (crowi) => {
    *           200:
    *             description: Succeeded to put CustomBotWithoutProxy setting.
    */
-  router.put('/without-proxy/update-settings', async(req, res) => {
+  router.put('/without-proxy/update-settings', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
     const currentBotType = crowi.configManager.getConfig('crowi', 'slackbot:currentBotType');
     if (currentBotType !== 'customBotWithoutProxy') {
       const msg = 'Not CustomBotWithoutProxy';
       return res.apiv3Err(new ErrorV3(msg, 'not-customBotWithoutProxy'), 400);
     }
+
     const { slackSigningSecret, slackBotToken } = req.body;
     const requestParams = {
       'slackbot:signingSecret': slackSigningSecret,
@@ -297,15 +326,13 @@ module.exports = (crowi) => {
       logger.error('Error', error);
       return res.apiv3Err(new ErrorV3(msg, 'update-CustomBotSetting-failed'), 500);
     }
-
-
   });
 
 
   /**
    * @swagger
    *
-   *    /slack-integration/access-tokens:
+   *    /slack-integration-settings/access-tokens:
    *      put:
    *        tags: [SlackIntegration]
    *        operationId: putAccessTokens
@@ -316,7 +343,6 @@ module.exports = (crowi) => {
    *            description: Succeeded to update access tokens for slack
    */
   router.put('/access-tokens', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
-    const SlackAppIntegration = mongoose.model('SlackAppIntegration');
     let checkTokens;
     let tokenGtoP;
     let tokenPtoG;
@@ -341,7 +367,6 @@ module.exports = (crowi) => {
 
   router.put('/proxy-uri', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
     const { proxyUri } = req.body;
-    console.log('proxyUri', proxyUri);
 
     const requestParams = { 'slackbot:serverUri': proxyUri };