소스 검색

feat: check storage before g2g

- check if file upload is enabled
- check total file size is enough for all files being transferred

https://redmine.weseek.co.jp/issues/106571
mizozobu 3 년 전
부모
커밋
38a58e3506
2개의 변경된 파일49개의 추가작업 그리고 15개의 파일을 삭제
  1. 18 9
      packages/app/src/server/service/file-uploader/uploader.js
  2. 31 6
      packages/app/src/server/service/g2g-transfer.ts

+ 18 - 9
packages/app/src/server/service/file-uploader/uploader.js

@@ -33,6 +33,23 @@ class Uploader {
     throw new Error('Implemnt this');
     throw new Error('Implemnt this');
   }
   }
 
 
+  /**
+   * Get total file size
+   * @returns Total file size
+   */
+  async getTotalFileSize() {
+    const Attachment = this.crowi.model('Attachment');
+
+    // Get attachment total file size
+    const res = await Attachment.aggregate().group({
+      _id: null,
+      total: { $sum: '$fileSize' },
+    });
+
+    // res is [] if not using
+    return res.length === 0 ? 0 : res[0].total;
+  }
+
   /**
   /**
    * Check files size limits for all uploaders
    * Check files size limits for all uploaders
    *
    *
@@ -46,21 +63,13 @@ class Uploader {
     if (uploadFileSize > maxFileSize) {
     if (uploadFileSize > maxFileSize) {
       return { isUploadable: false, errorMessage: 'File size exceeds the size limit per file' };
       return { isUploadable: false, errorMessage: 'File size exceeds the size limit per file' };
     }
     }
-    const Attachment = this.crowi.model('Attachment');
-    // Get attachment total file size
-    const res = await Attachment.aggregate().group({
-      _id: null,
-      total: { $sum: '$fileSize' },
-    });
-    // Return res is [] if not using
-    const usingFilesSize = res.length === 0 ? 0 : res[0].total;
 
 
+    const usingFilesSize = await this.getTotalFileSize();
     if (usingFilesSize + uploadFileSize > totalLimit) {
     if (usingFilesSize + uploadFileSize > totalLimit) {
       return { isUploadable: false, errorMessage: 'Uploading files reaches limit' };
       return { isUploadable: false, errorMessage: 'Uploading files reaches limit' };
     }
     }
 
 
     return { isUploadable: true };
     return { isUploadable: true };
-
   }
   }
 
 
   /**
   /**

+ 31 - 6
packages/app/src/server/service/g2g-transfer.ts

@@ -37,6 +37,8 @@ export const uploadConfigKeys = [
 export type IDataGROWIInfo = {
 export type IDataGROWIInfo = {
   version: string
   version: string
   userUpperLimit: number | null // Handle null as Infinity
   userUpperLimit: number | null // Handle null as Infinity
+  fileUploadDisabled: boolean;
+  fileUploadTotalLimit: number | null // Handle null as Infinity
   attachmentInfo: {
   attachmentInfo: {
     type: string,
     type: string,
     bucket?: string,
     bucket?: string,
@@ -148,9 +150,13 @@ const getWritePermission = async(crowi: any): Promise<boolean> => {
  * @returns
  * @returns
  */
  */
 const generateGROWIInfo = async(crowi: any): Promise<IDataGROWIInfo> => {
 const generateGROWIInfo = async(crowi: any): Promise<IDataGROWIInfo> => {
-  // TODO: add attachment file limit, storage total limit
+  // TODO: add attachment file limit
   const { configManager } = crowi;
   const { configManager } = crowi;
   const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
   const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
+  const fileUploadDisabled = configManager.getConfig('crowi', 'app:fileUploadDisabled');
+  const fileUploadTotalLimit = configManager.getConfig('crowi', 'app:fileUploadType') === 'mongodb'
+    ? configManager.getConfig('crowi', 'gridfs:totalLimit') ?? configManager.getConfig('crowi', 'app:fileUploadTotalLimit')
+    : configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
   const version = crowi.version;
   const version = crowi.version;
   const writable = await getWritePermission(crowi);
   const writable = await getWritePermission(crowi);
 
 
@@ -175,7 +181,13 @@ const generateGROWIInfo = async(crowi: any): Promise<IDataGROWIInfo> => {
     default:
     default:
   }
   }
 
 
-  return { userUpperLimit, version, attachmentInfo };
+  return {
+    userUpperLimit,
+    fileUploadDisabled,
+    fileUploadTotalLimit,
+    version,
+    attachmentInfo,
+  };
 };
 };
 
 
 export class G2GTransferPusherService implements Pusher {
 export class G2GTransferPusherService implements Pusher {
@@ -202,20 +214,33 @@ export class G2GTransferPusherService implements Pusher {
     return toGROWIInfo;
     return toGROWIInfo;
   }
   }
 
 
+  /**
+   * Returns whether g2g transfer is possible
+   * @param toGROWIInfo to-growi info
+   * @returns Whether g2g transfer is possible
+   */
   public async canTransfer(toGROWIInfo: IDataGROWIInfo): Promise<boolean> {
   public async canTransfer(toGROWIInfo: IDataGROWIInfo): Promise<boolean> {
-    // TODO: check FILE_UPLOAD_TOTAL_LIMIT, FILE_UPLOAD_DISABLED
-    const configManager = this.crowi.configManager;
-    const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
-    const version = this.crowi.version;
+    const { configManager, fileUploadService } = this.crowi;
 
 
+    const version = this.crowi.version;
     if (version !== toGROWIInfo.version) {
     if (version !== toGROWIInfo.version) {
       return false;
       return false;
     }
     }
 
 
+    const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
     if ((userUpperLimit ?? Infinity) < (toGROWIInfo.userUpperLimit ?? 0)) {
     if ((userUpperLimit ?? Infinity) < (toGROWIInfo.userUpperLimit ?? 0)) {
       return false;
       return false;
     }
     }
 
 
+    if (toGROWIInfo.fileUploadDisabled) {
+      return false;
+    }
+
+    const totalFileSize = await fileUploadService.getTotalFileSize();
+    if ((toGROWIInfo.fileUploadTotalLimit ?? Infinity) < totalFileSize) {
+      return false;
+    }
+
     return true;
     return true;
   }
   }