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

Merge pull request #4251 from weseek/imprv/refactor-controller-of-Post('interactions')

Imprv:refactor
Sizma yosimaz 4 лет назад
Родитель
Сommit
ab49361936

+ 18 - 41
packages/slackbot-proxy/src/controllers/slack.ts

@@ -36,7 +36,7 @@ import { JoinToConversationMiddleware } from '~/middlewares/slack-to-growi/join-
 
 
 const logger = loggerFactory('slackbot-proxy:controllers:slack');
 const logger = loggerFactory('slackbot-proxy:controllers:slack');
 
 
-const postNotAllowedMessage = async(client:WebClient, body:any, disallowedGrowiUrls:Set<string>, commandName:string):Promise<void> => {
+const postNotAllowedMessage = async(client:WebClient, channelId:string, userId:string, disallowedGrowiUrls:Set<string>, commandName:string):Promise<void> => {
 
 
   const linkUrlList = Array.from(disallowedGrowiUrls).map((growiUrl) => {
   const linkUrlList = Array.from(disallowedGrowiUrls).map((growiUrl) => {
     return '\n'
     return '\n'
@@ -45,10 +45,11 @@ const postNotAllowedMessage = async(client:WebClient, body:any, disallowedGrowiU
 
 
   const growiDocsLink = 'https://docs.growi.org/en/admin-guide/upgrading/43x.html';
   const growiDocsLink = 'https://docs.growi.org/en/admin-guide/upgrading/43x.html';
 
 
+
   await client.chat.postEphemeral({
   await client.chat.postEphemeral({
     text: 'Error occured.',
     text: 'Error occured.',
-    channel: body.channel_id,
-    user: body.user_id,
+    channel: channelId,
+    user: userId,
     blocks: [
     blocks: [
       markdownSectionBlock('*None of GROWI permitted the command.*'),
       markdownSectionBlock('*None of GROWI permitted the command.*'),
       markdownSectionBlock(`*'${commandName}'* command was not allowed.`),
       markdownSectionBlock(`*'${commandName}'* command was not allowed.`),
@@ -239,7 +240,7 @@ export class SlackCtrl {
     if (relations.length === disallowedGrowiUrls.size) {
     if (relations.length === disallowedGrowiUrls.size) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       const client = generateWebClient(authorizeResult.botToken!);
       const client = generateWebClient(authorizeResult.botToken!);
-      return postNotAllowedMessage(client, body, disallowedGrowiUrls, growiCommand.growiCommandType);
+      return postNotAllowedMessage(client, body.channel_id, body.user_id, disallowedGrowiUrls, growiCommand.growiCommandType);
     }
     }
 
 
     // select GROWI
     // select GROWI
@@ -330,53 +331,29 @@ export class SlackCtrl {
       });
       });
     }
     }
 
 
-
-    const allowedRelations:Relation[] = [];
-    const disallowedGrowiUrls: Set<string> = new Set();
-    let notAllowedCommandName!:string;
     const actionId:string = payload?.actions?.[0].action_id;
     const actionId:string = payload?.actions?.[0].action_id;
+    const permission = await this.relationsService.checkPermissionForInteractions(relations, actionId, callbackId, channelName);
+    const {
+      allowedRelations, disallowedGrowiUrls, commandName, rejectedResults,
+    } = permission;
 
 
-    await Promise.all(relations.map(async(relation) => {
-      const permission = await this.relationsService.checkPermissionForInteractions(relation, channelName, callbackId, actionId);
-      const { isPermittedForInteractions, commandName } = permission;
-
-      if (!isPermittedForInteractions) {
-        disallowedGrowiUrls.add(relation.growiUri);
-        notAllowedCommandName = commandName;
-      }
-
-      allowedRelations.push(relation);
-    }));
+    try {
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      await postEphemeralErrors(rejectedResults, payload.channel.id, payload.user.id, authorizeResult.botToken!);
+    }
+    catch (err) {
+      logger.error(err);
+    }
 
 
     if (relations.length === disallowedGrowiUrls.size) {
     if (relations.length === disallowedGrowiUrls.size) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       const client = generateWebClient(authorizeResult.botToken!);
       const client = generateWebClient(authorizeResult.botToken!);
-      const linkUrlList = Array.from(disallowedGrowiUrls).map((growiUrl) => {
-        return '\n'
-      + `• ${new URL('/admin/slack-integration', growiUrl).toString()}`;
-      });
-      const growiDocsLink = 'https://docs.growi.org/en/admin-guide/upgrading/43x.html';
-      return client.chat.postEphemeral({
-        text: 'Error occured.',
-        channel: body.channel_id,
-        user: body.user_id,
-        blocks: [
-          markdownSectionBlock('*None of GROWI permitted the command.*'),
-          markdownSectionBlock(`*'${notAllowedCommandName}'* command was not allowed.`),
-          markdownSectionBlock(
-            `To use this command, modify settings from following pages: ${linkUrlList}`,
-          ),
-          markdownSectionBlock(
-            `Or, if your GROWI version is 4.3.0 or below, upgrade GROWI to use commands and permission settings: ${growiDocsLink}`,
-          ),
-        ],
-      });
+      return postNotAllowedMessage(client, payload.channel.id, payload.user.id, disallowedGrowiUrls, commandName);
     }
     }
 
 
     /*
     /*
      * forward to GROWI server
      * forward to GROWI server
      */
      */
-
     allowedRelations.map(async(relation) => {
     allowedRelations.map(async(relation) => {
       try {
       try {
         // generate API URL
         // generate API URL
@@ -392,8 +369,8 @@ export class SlackCtrl {
       catch (err) {
       catch (err) {
         logger.error(err);
         logger.error(err);
       }
       }
-    });
 
 
+    });
   }
   }
 
 
   @Post('/events')
   @Post('/events')

+ 54 - 34
packages/slackbot-proxy/src/services/RelationsService.ts

@@ -11,6 +11,13 @@ import loggerFactory from '~/utils/logger';
 
 
 const logger = loggerFactory('slackbot-proxy:services:RelationsService');
 const logger = loggerFactory('slackbot-proxy:services:RelationsService');
 
 
+type checkPermissionForInteractionsResults = {
+  allowedRelations:Relation[],
+  disallowedGrowiUrls:Set<string>,
+  commandName:string,
+  rejectedResults:PromiseRejectedResult[]
+}
+
 @Service()
 @Service()
 export class RelationsService {
 export class RelationsService {
 
 
@@ -107,49 +114,62 @@ export class RelationsService {
     return permission;
     return permission;
   }
   }
 
 
-
   async checkPermissionForInteractions(
   async checkPermissionForInteractions(
-      // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
-      relation:Relation, channelName:string, callbackId:string, actionId:string,
-  ):Promise<{isPermittedForInteractions:boolean, commandName:string}> {
+      relations:Relation[], actionId:string, callbackId:string, channelName:string,
+  ):Promise<checkPermissionForInteractionsResults> {
+    return this.relationsResult(relations, actionId, callbackId, channelName);
+  }
 
 
-    let isPermittedForInteractions = false;
-    let permissionForInteractions:boolean|string[];
+  async relationsResult(
+      relations:Relation[], actionId:string, callbackId:string, channelName:string,
+  ):Promise<checkPermissionForInteractionsResults> {
 
 
-    const singleUse = Object.keys(relation.permissionsForSingleUseCommands);
-    const broadCastUse = Object.keys(relation.permissionsForBroadcastUseCommands);
-    let commandName!:string;
+    const allowedRelations:Relation[] = [];
+    const disallowedGrowiUrls:Set<string> = new Set();
+    let commandName = '';
 
 
-    [...singleUse, ...broadCastUse].forEach(async(tempCommandName) => {
+    const results = await Promise.allSettled(relations.map(async(relation) => {
+      let permissionForInteractions:boolean|string[];
+      const singleUse = Object.keys(relation.permissionsForSingleUseCommands);
+      const broadCastUse = Object.keys(relation.permissionsForBroadcastUseCommands);
 
 
-      // ex. search OR search:handlerName
-      const commandRegExp = new RegExp(`(^${tempCommandName}$)|(^${tempCommandName}:\\w+)`);
-      // skip this forEach loop if the requested command is not in permissionsForBroadcastUseCommands and permissionsForSingleUseCommands
-      if (!commandRegExp.test(actionId) && !commandRegExp.test(callbackId)) {
-        return;
-      }
+      [...singleUse, ...broadCastUse].forEach(async(tempCommandName) => {
 
 
-      commandName = tempCommandName;
+        // ex. search OR search:handlerName
+        const commandRegExp = new RegExp(`(^${tempCommandName}$)|(^${tempCommandName}:\\w+)`);
+        // skip this forEach loop if the requested command is not in permissionsForBroadcastUseCommands and permissionsForSingleUseCommands
+        if (!commandRegExp.test(actionId) && !commandRegExp.test(callbackId)) {
+          return;
+        }
 
 
-      // case: singleUse
-      permissionForInteractions = relation.permissionsForSingleUseCommands[tempCommandName];
-      // case: broadcastUse
-      if (permissionForInteractions == null) {
-        permissionForInteractions = relation.permissionsForBroadcastUseCommands[tempCommandName];
-      }
-      if (permissionForInteractions === true) {
-        isPermittedForInteractions = true;
-        return;
-      }
-      // check permission at channel level
-      if (Array.isArray(permissionForInteractions) && permissionForInteractions.includes(channelName)) {
-        isPermittedForInteractions = true;
-        return;
-      }
-    });
+        commandName = tempCommandName;
+
+        // case: singleUse
+        permissionForInteractions = relation.permissionsForSingleUseCommands[tempCommandName];
+        // case: broadcastUse
+        if (permissionForInteractions == null) {
+          permissionForInteractions = relation.permissionsForBroadcastUseCommands[tempCommandName];
+        }
+
+        if (permissionForInteractions === true) {
+          return allowedRelations.push(relation);
+        }
+
+        // check permission at channel level
+        if (Array.isArray(permissionForInteractions) && permissionForInteractions.includes(channelName)) {
+          return allowedRelations.push(relation);
+        }
+
+        disallowedGrowiUrls.add(relation.growiUri);
+      });
+    }));
+
+    const rejectedResults: PromiseRejectedResult[] = results.filter((result): result is PromiseRejectedResult => result.status === 'rejected');
 
 
 
 
-    return { isPermittedForInteractions, commandName };
+    return {
+      allowedRelations, disallowedGrowiUrls, commandName, rejectedResults,
+    };
   }
   }
 
 
 }
 }