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

Merge branch 'feat/7015-cache-CRUD' into feat/6450-insurance-branch

zahmis 4 лет назад
Родитель
Сommit
287017b750

+ 57 - 38
packages/app/src/server/routes/apiv3/slack-integration-settings.js

@@ -378,26 +378,19 @@ module.exports = (crowi) => {
    *          200:
    *            description: Succeeded to create slack app integration
    */
-  router.post('/slack-app-integrations', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
-    const { tokenGtoP, tokenPtoG } = await SlackAppIntegration.generateUniqueAccessTokens();
-    try {
-      const count = await SlackAppIntegration.countDocuments();
-      if (count >= 10) {
-        const msg = 'Not be able to create more than 10 slack workspace integration settings';
-        logger.error('Error', msg);
-        return res.apiv3Err(new ErrorV3(msg, 'create-slackAppIntegeration-failed'), 500);
-      }
+  router.put('/slack-app-integrations', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
+    const SlackAppIntegrationMock = mongoose.model('SlackAppIntegrationMock');
+    const SlackAppIntegrationMockRecordsNum = await SlackAppIntegrationMock.countDocuments();
+    if (SlackAppIntegrationMockRecordsNum >= 10) {
+      const msg = 'Not be able to create more than 10 slack workspace integration settings';
+      logger.error('Error', msg);
+      return res.apiv3Err(new ErrorV3(msg, 'create-slackAppIntegeration-failed'), 500);
+    }
 
-      const slackAppTokens = await SlackAppIntegration.create({
-        tokenGtoP,
-        tokenPtoG,
-        isPrimary: count === 0 ? true : undefined,
-        supportedCommandsForBroadcastUse: defaultSupportedCommandsNameForBroadcastUse,
-        supportedCommandsForSingleUse: defaultSupportedCommandsNameForSingleUse,
-      });
+    const { tokenGtoP, tokenPtoG } = await SlackAppIntegrationMock.generateUniqueAccessTokens();
+    try {
       // MOCK DATA DELETE THIS GW-6972 ---------------
       /* This code represents the creation of the new SlackAppIntegration model instance. */
-      const SlackAppIntegrationMock = mongoose.model('SlackAppIntegrationMock');
       const initialSupportedCommandsForBroadcastUse = new Map();
       const initialSupportedCommandsForSingleUse = new Map();
       defaultSupportedCommandsNameForBroadcastUse.forEach((commandName) => {
@@ -406,14 +399,14 @@ module.exports = (crowi) => {
       defaultSupportedCommandsNameForSingleUse.forEach((commandName) => {
         initialSupportedCommandsForSingleUse.set(commandName, true);
       });
-      const MOCK = await SlackAppIntegrationMock.create({
+      const slackAppTokensMOCK = await SlackAppIntegrationMock.create({
         tokenGtoP,
         tokenPtoG,
         permissionsForBroadcastUseCommands: initialSupportedCommandsForBroadcastUse,
         permissionsForSingleUseCommands: initialSupportedCommandsForSingleUse,
       });
       // MOCK DATA DELETE THIS GW-6972 ---------------
-      return res.apiv3(slackAppTokens, 200);
+      return res.apiv3(slackAppTokensMOCK, 200);
     }
     catch (error) {
       const msg = 'Error occurred during creating slack integration settings procedure';
@@ -570,26 +563,49 @@ module.exports = (crowi) => {
     const { id } = req.params;
 
     try {
+      // NOT MOCK DATA BUT REFER THIS GW-7006
       const slackAppIntegration = await SlackAppIntegration.findByIdAndUpdate(
         id,
         { supportedCommandsForBroadcastUse, supportedCommandsForSingleUse },
         { new: true },
       );
 
-      const proxyUri = crowi.configManager.getConfig('crowi', 'slackbot:proxyUri');
-      if (proxyUri != null) {
-        await requestToProxyServer(
-          slackAppIntegration.tokenGtoP,
-          'put',
-          '/g2s/supported-commands',
-          {
-            supportedCommandsForBroadcastUse: slackAppIntegration.supportedCommandsForBroadcastUse,
-            supportedCommandsForSingleUse: slackAppIntegration.supportedCommandsForSingleUse,
-          },
-        );
-      }
+      // MOCK DATA MODIFY THIS GW-6972 ---------------
+      /**
+       * this code represents the update operation using request from client (slackapp integration settings page)
+       * , then send request to proxy to update cache
+       * permittedChannelsForEachCommandFromClient represents the data sent from client
+       */
+      const SlackAppIntegrationMock = mongoose.model('SlackAppIntegrationMock');
+      // MOCK DATA FROM CLIENT assume that these data were sent from client
+      const permissionsForBroadcastUseCommandsFromClient = {
+        search: false,
+      };
+      const permissionsForSingleUseCommandsFromClient = {
+        create: ['random'],
+      };
+      const slackAppIntegrationMock = await SlackAppIntegrationMock.findOneAndUpdate(
+        // MOCK DATA USE id IN req.params LIKE ABOVE
+        { tokenPtoG: slackAppIntegration.tokenPtoG },
+        {
+          permissionsForBroadcastUseCommands: permissionsForBroadcastUseCommandsFromClient,
+          permissionsForSingleUseCommands: permissionsForSingleUseCommandsFromClient,
+        },
+        { new: true },
+      );
+
+      await requestToProxyServer(
+        slackAppIntegrationMock.tokenGtoP,
+        'put',
+        '/g2s/supported-commands',
+        {
+          permissionsForBroadcastUseCommands: slackAppIntegrationMock.permissionsForBroadcastUseCommands,
+          permissionsForSingleUseCommands: slackAppIntegrationMock.permissionsForSingleUseCommands,
+        },
+      );
+      // MOCK DATA MODIFY THIS GW-6972 ---------------
 
-      return res.apiv3({ slackAppIntegration });
+      return res.apiv3({ slackAppIntegrationMock });
     }
     catch (error) {
       const msg = `Error occured in updating settings. Cause: ${error.message}`;
@@ -627,20 +643,23 @@ module.exports = (crowi) => {
     const { id } = req.params;
     let slackBotToken;
     try {
-      const slackAppIntegration = await SlackAppIntegrationMock.findOne({ _id: id });
-      // const slackAppIntegration = await SlackAppIntegration.findOne({ _id: id });
-      if (slackAppIntegration == null) {
+      // MOCK DATA DELETE THIS GW-6972 ---------------
+      const SlackAppIntegrationMock = mongoose.model('SlackAppIntegrationMock');
+      const slackAppIntegrationMock = await SlackAppIntegrationMock.findOne({ _id: id });
+      // MOCK DATA DELETE THIS GW-6972 ---------------
+      if (slackAppIntegrationMock == null) {
         const msg = 'Could not find SlackAppIntegration by id';
         return res.apiv3Err(new ErrorV3(msg, 'find-slackAppIntegration-failed'), 400);
       }
 
+      // USE MOCK DATA HERE FOR cache creation at /relation-test GW-7021
       const result = await requestToProxyServer(
-        slackAppIntegration.tokenGtoP,
+        slackAppIntegrationMock.tokenGtoP,
         'post',
         '/g2s/relation-test',
         {
-          permissionsForBroadcastUseCommands: slackAppIntegration.permissionsForBroadcastUseCommands,
-          permissionsForSingleUseCommands: slackAppIntegration.permissionsForSingleUseCommands,
+          permissionsForBroadcastUseCommands: slackAppIntegrationMock.permissionsForBroadcastUseCommands,
+          permissionsForSingleUseCommands: slackAppIntegrationMock.permissionsForSingleUseCommands,
         },
       );
 

+ 18 - 7
packages/app/src/server/routes/apiv3/slack-integration.js

@@ -8,7 +8,7 @@ const { verifySlackRequest, generateWebClient, getSupportedGrowiActionsRegExps }
 
 const logger = loggerFactory('growi:routes:apiv3:slack-integration');
 const router = express.Router();
-const SlackAppIntegration = mongoose.model('SlackAppIntegration');
+const SlackAppIntegration = mongoose.model('SlackAppIntegrationMock');
 const SlackAppIntegrationMock = mongoose.model('SlackAppIntegrationMock');
 const { respondIfSlackbotError } = require('../../service/slack-command-handler/respond-if-slackbot-error');
 
@@ -27,14 +27,16 @@ module.exports = (crowi) => {
       return res.status(400).send({ message });
     }
 
-    const slackAppIntegrationCount = await SlackAppIntegrationMock.countDocuments({ tokenPtoG });
+    // const slackAppIntegrationCount = await SlackAppIntegrationMock.countDocuments({ tokenPtoG });
+    // MOCK DATA MODIFY THIS WITH SlackAppIntegration GW-7006 --------------
+    const slackAppIntegrationMockCount = await SlackAppIntegrationMock.countDocuments({ tokenPtoG });
 
     logger.debug('verifyAccessTokenFromProxy', {
       tokenPtoG,
-      slackAppIntegrationCount,
+      slackAppIntegrationMockCount,
     });
 
-    if (slackAppIntegrationCount === 0) {
+    if (slackAppIntegrationMockCount === 0) {
       return res.status(403).send({
         message: 'The access token that identifies the request source is slackbot-proxy is invalid. Did you setup with `/growi register`.\n'
         + 'Or did you delete registration for GROWI ? if so, the link with GROWI has been disconnected. '
@@ -69,19 +71,22 @@ module.exports = (crowi) => {
     let command = '';
     let actionId = '';
     let callbackId = '';
+    let fromChannel = '';
 
     if (!payload) { // when request is to /commands
       command = req.body.text.split(' ')[0];
+      fromChannel = req.body.channel_name;
     }
     else if (payload.actions) { // when request is to /interactions && block_actions
       actionId = payload.actions[0].action_id;
+      fromChannel = payload.channel.name;
     }
     else { // when request is to /interactions && view_submission
       callbackId = payload.view.callback_id;
+      fromChannel = JSON.parse(payload.view.private_metadata).channelName;
     }
 
     // code below checks permission at channel level
-    const fromChannel = req.body.channel_name || payload.channel.name;
     let isPermitted = false;
     [...permissionsForBroadcastUseCommands.keys(), ...permissionsForSingleUseCommands.keys()].forEach((commandName) => {
       // boolean or string[]
@@ -219,9 +224,15 @@ module.exports = (crowi) => {
 
   router.get('/supported-commands', verifyAccessTokenFromProxy, async(req, res) => {
     const tokenPtoG = req.headers['x-growi-ptog-tokens'];
-    const slackAppIntegration = await SlackAppIntegration.findOne({ tokenPtoG });
+    // MOCK DATA DELETE THIS GW-6972 ---------
+    const SlackAppIntegrationMock = mongoose.model('SlackAppIntegrationMock');
+    const slackAppIntegrationMock = await SlackAppIntegrationMock.findOne({ tokenPtoG });
+    const { permissionsForBroadcastUseCommands, permissionsForSingleUseCommands } = slackAppIntegrationMock;
+    return res.apiv3({ permissionsForBroadcastUseCommands, permissionsForSingleUseCommands });
+    // MOCK DATA DELETE THIS GW-6972 ---------
 
-    return res.send(slackAppIntegration);
+    // const slackAppIntegration = await SlackAppIntegration.findOne({ tokenPtoG });
+    // return res.send(slackAppIntegration);
   });
 
   return router;

+ 1 - 1
packages/slack/src/middlewares/verify-growi-to-slack-request.ts

@@ -4,7 +4,7 @@ import createError from 'http-errors';
 import loggerFactory from '../utils/logger';
 import { RequestFromGrowi } from '../interfaces/request-between-growi-and-proxy';
 
-const logger = loggerFactory('@growi/slack:middlewares:verify-slack-request');
+const logger = loggerFactory('@growi/slack:middlewares:verify-growi-to-slack-request');
 
 /**
  * Verify if the request came from slack

+ 19 - 5
packages/slackbot-proxy/src/controllers/growi-to-slack.ts

@@ -15,7 +15,7 @@ import { WebclientRes, AddWebclientResponseToRes } from '~/middlewares/growi-to-
 
 import { GrowiReq } from '~/interfaces/growi-to-slack/growi-req';
 import { InstallationRepository } from '~/repositories/installation';
-// import { RelationRepository } from '~/repositories/relation';
+import { RelationRepository } from '~/repositories/relation';
 import { RelationMockRepository } from '~/repositories/relation-mock';
 import { OrderRepository } from '~/repositories/order';
 
@@ -102,14 +102,22 @@ export class GrowiToSlackCtrl {
   async putSupportedCommands(@Req() req: GrowiReq, @Res() res: Res): Promise<void|string|Res|WebAPICallResult> {
     // asserted (tokenGtoPs.length > 0) by verifyGrowiToSlackRequest
     const { tokenGtoPs } = req;
+
+    // MOCK DATA SO FAR BUT THIS CAN BE USED AS AN ACTUAL CODE AS WELL GW 6972 -----------
     const { permissionsForBroadcastUseCommands, permissionsForSingleUseCommands } = req.body;
+    // MOCK DATA SO FAR BUT THIS CAN BE USED AS AN ACTUAL CODE AS WELL GW 6972 -----------
 
     if (tokenGtoPs.length !== 1) {
       throw createError(400, 'installation is invalid');
     }
 
     const tokenGtoP = tokenGtoPs[0];
-    const relation = await this.relationMockRepository.update({ tokenGtoP }, { permissionsForBroadcastUseCommands, permissionsForSingleUseCommands });
+
+    // MOCK DATA MODIFY THIS GW 6972 -----------
+    const relation = await this.relationMockRepository.update(
+      { tokenGtoP }, { permissionsForBroadcastUseCommands, permissionsForSingleUseCommands },
+    );
+    // MOCK DATA MODIFY THIS GW 6972 -----------
 
     return res.send({ relation });
   }
@@ -193,7 +201,11 @@ export class GrowiToSlackCtrl {
     // temporary cache for 48 hours
     const expiredAtCommands = addHours(new Date(), 48);
 
-    // Transaction is not considered because it is used infrequently,
+    // MOCK DATA DELETE THIS GW-6972 7004 ---------------
+    /**
+     * this code represents the creation of cache (Relation schema) using request from GROWI
+     */
+    // Transaction is not considered because it is used infrequently
     const response = await this.relationMockRepository.createQueryBuilder('relation')
       .insert()
       .values({
@@ -211,11 +223,13 @@ export class GrowiToSlackCtrl {
         overwrite: ['tokenGtoP', 'tokenPtoG', 'permissionsForBroadcastUseCommands', 'permissionsForSingleUseCommands'],
       })
       .execute();
+    // MOCK DATA DELETE THIS GW-6972 7004 ---------------
 
     // Find the generated relation
-    const generatedRelation = await this.relationMockRepository.findOne({ id: response.identifiers[0].id });
+    // const generatedRelation = await this.relationMockRepository.findOne({ id: response.identifiers[0].id });
+    const generatedRelationMock = await this.relationMockRepository.findOne({ id: response.identifiers[0].id });
 
-    return res.send({ relation: generatedRelation, slackBotToken: token });
+    return res.send({ relation: generatedRelationMock, slackBotToken: token });
   }
 
   injectGrowiUri(req: GrowiReq, growiUri: string): void {

+ 1 - 0
packages/slackbot-proxy/src/controllers/slack.ts

@@ -106,6 +106,7 @@ export class SlackCtrl {
     if (relations.length === 0) {
       throw new Error('relations must be set');
     }
+
     const botToken = relations[0].installation?.data.bot?.token; // relations[0] should be exist
     const promises = relations.map((relation: RelationMock) => {
       // generate API URL

+ 2 - 7
packages/slackbot-proxy/src/entities/relation-mock.ts

@@ -1,7 +1,7 @@
+import { differenceInMilliseconds } from 'date-fns';
 import {
   Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, ManyToOne, Index,
 } from 'typeorm';
-import { differenceInMilliseconds } from 'date-fns';
 import { Installation } from './installation';
 
 interface PermissionSettingsInterface {
@@ -41,14 +41,9 @@ export class RelationMock {
   @Column({ type: 'json' })
   permissionsForSingleUseCommands: PermissionSettingsInterface;
 
-  @CreateDateColumn()
+  @Column({ type: 'timestamp' })
   expiredAtCommands: Date;
 
-  isExpiredCommands():boolean {
-    const now = Date.now();
-    return this.expiredAtCommands.getTime() < now;
-  }
-
   getDistanceInMillisecondsToExpiredAt(baseDate:Date):number {
     return differenceInMilliseconds(this.expiredAtCommands, baseDate);
   }

+ 3 - 7
packages/slackbot-proxy/src/entities/relation.ts

@@ -1,7 +1,7 @@
+import { differenceInMilliseconds } from 'date-fns';
 import {
   Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, ManyToOne, Index,
 } from 'typeorm';
-import { differenceInMilliseconds } from 'date-fns';
 import { Installation } from './installation';
 
 @Entity()
@@ -37,15 +37,11 @@ export class Relation {
   @Column('simple-array')
   supportedCommandsForSingleUse: string[];
 
-  @CreateDateColumn()
+  @Column({ type: 'timestamp' })
   expiredAtCommands: Date;
 
-  isExpiredCommands():boolean {
-    const now = Date.now();
-    return this.expiredAtCommands.getTime() < now;
-  }
-
   getDistanceInMillisecondsToExpiredAt(baseDate:Date):number {
+    // differenceInMilliseconds uses Date.prototype.getTime() internally
     return differenceInMilliseconds(this.expiredAtCommands, baseDate);
   }
 

+ 17 - 6
packages/slackbot-proxy/src/services/RelationsService.ts

@@ -34,15 +34,26 @@ export class RelationsService {
 
   async syncSupportedGrowiCommands(relation:RelationMock): Promise<RelationMock> {
     const res = await this.getSupportedGrowiCommands(relation);
-    const { permissionsForBroadcastUseCommands, permissionsForSingleUseCommands } = res.data;
-    relation.permissionsForBroadcastUseCommands = permissionsForBroadcastUseCommands;
-    relation.permissionsForSingleUseCommands = permissionsForSingleUseCommands;
-    relation.expiredAtCommands = addHours(new Date(), 48);
 
-    return this.relationMockRepository.save(relation);
+    // MOCK DATA MODIFY THIS GW-6972 ---------------
+    /**
+     * this code represents the update of cache (Relation schema) using request from GROWI
+     */
+    const { permissionsForBroadcastUseCommands, permissionsForSingleUseCommands } = res.data.data;
+    if (relation !== null) {
+      relation.permissionsForBroadcastUseCommands = permissionsForBroadcastUseCommands;
+      relation.permissionsForSingleUseCommands = permissionsForSingleUseCommands;
+      relation.expiredAtCommands = addHours(new Date(), 48);
+      return this.relationMockRepository.save(relation);
+    }
+    throw Error('No relation exists.');
+    // MOCK DATA MODIFY THIS GW-6972 ---------------
   }
 
+  // MODIFY THIS METHOD USING ORIGINAL RELATION MODEL GW-6972
   async syncRelation(relation:RelationMock, baseDate:Date):Promise<RelationMock|null> {
+    if (relation == null) return null;
+
     const distanceMillisecondsToExpiredAt = relation.getDistanceInMillisecondsToExpiredAt(baseDate);
 
     if (distanceMillisecondsToExpiredAt < 0) {
@@ -56,7 +67,7 @@ export class RelationsService {
     }
 
     // 24 hours
-    if (distanceMillisecondsToExpiredAt < 1000 * 60 * 60 * 24) {
+    if (distanceMillisecondsToExpiredAt < 24 * 60 * 60 * 1000) {
       try {
         this.syncSupportedGrowiCommands(relation);
       }