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

Add support to validate uploaded avatars

Tobias Wolf 2 лет назад
Родитель
Сommit
c64a221453

+ 3 - 0
.devcontainer/Dockerfile

@@ -33,6 +33,9 @@ ENV \
     ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM="" \
     ATTACHMENTS_UPLOAD_MIME_TYPES="" \
     ATTACHMENTS_UPLOAD_MAX_SIZE=0 \
+    AVATARS_UPLOAD_EXTERNAL_PROGRAM="" \
+    AVATARS_UPLOAD_MIME_TYPES="" \
+    AVATARS_UPLOAD_MAX_SIZE=0 \
     MAX_IMAGE_PIXEL="" \
     IMAGE_COMPRESS_RATIO="" \
     NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="" \

+ 3 - 0
Dockerfile

@@ -36,6 +36,9 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
     ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM="" \
     ATTACHMENTS_UPLOAD_MIME_TYPES="" \
     ATTACHMENTS_UPLOAD_MAX_SIZE=0 \
+    AVATARS_UPLOAD_EXTERNAL_PROGRAM="" \
+    AVATARS_UPLOAD_MIME_TYPES="" \
+    AVATARS_UPLOAD_MAX_SIZE=0 \
     RICHER_CARD_COMMENT_EDITOR=false \
     CARD_OPENED_WEBHOOK_ENABLED=false \
     MAX_IMAGE_PIXEL="" \

+ 0 - 8
client/components/users/userAvatar.js

@@ -3,7 +3,6 @@ import Avatars from '/models/avatars';
 import Users from '/models/users';
 import Org from '/models/org';
 import Team from '/models/team';
-import { formatFleURL } from 'meteor/ostrio:files/lib';
 
 Template.userAvatar.helpers({
   userData() {
@@ -218,13 +217,6 @@ BlazeComponent.extendComponent({
               },
               false,
             );
-            uploader.on('uploaded', (error, fileRef) => {
-              if (!error) {
-                self.setAvatar(
-                  `${formatFleURL(fileRef)}?auth=false&brokenIsFine=true`,
-                );
-              }
-            });
             uploader.on('error', (error, fileData) => {
               self.setError(error.reason);
             });

+ 5 - 0
docker-compose.yml

@@ -271,6 +271,11 @@ services:
       #-ATTACHMENTS_UPLOAD_MIME_TYPES=image/*,text/*
       #-ATTACHMENTS_UPLOAD_MAX_SIZE=5000000
       #---------------------------------------------------------------
+      # ==== Allow configuration to validate uploaded avatars ====
+      #-AVATARS_UPLOAD_EXTERNAL_PROGRAM=/usr/local/bin/avscan {file}
+      #-AVATARS_UPLOAD_MIME_TYPES=image/*
+      #-AVATARS_UPLOAD_MAX_SIZE=500000
+      #---------------------------------------------------------------
       # ==== Allow to shrink attached/pasted image ====
       # https://github.com/wekan/wekan/pull/2544
       #-MAX_IMAGE_PIXEL=1024

+ 42 - 4
models/avatars.js

@@ -1,13 +1,40 @@
 import { Meteor } from 'meteor/meteor';
 import { FilesCollection } from 'meteor/ostrio:files';
+import { formatFleURL } from 'meteor/ostrio:files/lib';
+import { isFileValid } from './fileValidation';
 import { createBucket } from './lib/grid/createBucket';
 import fs from 'fs';
 import path from 'path';
-import FileStoreStrategyFactory, { FileStoreStrategyFilesystem, FileStoreStrategyGridFs} from '/models/lib/fileStoreStrategy';
+import FileStoreStrategyFactory, { FileStoreStrategyFilesystem, FileStoreStrategyGridFs, STORAGE_NAME_FILESYSTEM } from '/models/lib/fileStoreStrategy';
 
+let avatarsUploadExternalProgram;
+let avatarsUploadMimeTypes = [];
+let avatarsUploadSize = 72000;
 let avatarsBucket;
 let storagePath;
+
 if (Meteor.isServer) {
+  if (process.env.AVATARS_UPLOAD_MIME_TYPES) {
+    avatarsUploadMimeTypes = process.env.AVATARS_UPLOAD_MIME_TYPES.split(',');
+    avatarsUploadMimeTypes = avatarsUploadMimeTypes.map(value => value.trim());
+  }
+
+  if (process.env.AVATARS_UPLOAD_MAX_SIZE) {
+    avatarsUploadSize = parseInt(process.env.AVATARS_UPLOAD_MAX_SIZE);
+
+    if (isNaN(avatarsUploadSize)) {
+      avatarsUploadSize = 0
+    }
+  }
+
+  if (process.env.AVATARS_UPLOAD_EXTERNAL_PROGRAM) {
+    avatarsUploadExternalProgram = process.env.AVATARS_UPLOAD_EXTERNAL_PROGRAM;
+
+    if (!avatarsUploadExternalProgram.includes("{file}")) {
+      avatarsUploadExternalProgram = undefined;
+    }
+  }
+
   avatarsBucket = createBucket('avatars');
   storagePath = path.join(process.env.WRITABLE_PATH, 'avatars');
 }
@@ -23,7 +50,7 @@ Avatars = new FilesCollection({
     return ret;
   },
   onBeforeUpload(file) {
-    if (file.size <= 72000 && file.type.startsWith('image/')) {
+    if (file.size <= avatarsUploadSize && file.type.startsWith('image/')) {
       return true;
     }
     return 'avatar-too-big';
@@ -31,9 +58,20 @@ Avatars = new FilesCollection({
   onAfterUpload(fileObj) {
     // current storage is the filesystem, update object and database
     Object.keys(fileObj.versions).forEach(versionName => {
-      fileObj.versions[versionName].storage = "fs";
+      fileObj.versions[versionName].storage = STORAGE_NAME_FILESYSTEM;
     });
-    Avatars.update({ _id: fileObj._id }, { $set: { "versions" : fileObj.versions } });
+
+    Avatars.update({ _id: fileObj._id }, { $set: { "versions": fileObj.versions } });
+
+    const isValid = Promise.await(isFileValid(fileObj, avatarsUploadMimeTypes, avatarsUploadSize, avatarsUploadExternalProgram));
+    const user = Users.findOne(fileObj.userId);
+
+    if (isValid) {
+      user.setAvatarUrl(`${formatFleURL(fileObj)}?auth=false&brokenIsFine=true`);
+    } else {
+      user.setAvatarUrl('');
+      Avatars.remove(fileObj._id);
+    }
   },
   interceptDownload(http, fileObj, versionName) {
     const ret = fileStoreStrategyFactory.getFileStrategy(fileObj, versionName).interceptDownload(http, this.cacheControl);

+ 5 - 0
releases/virtualbox/start-wekan.sh

@@ -53,6 +53,11 @@
       #export ATTACHMENTS_UPLOAD_MIME_TYPES="image/*,text/*"
       #export ATTACHMENTS_UPLOAD_MAX_SIZE=5000000
       #---------------------------------------------------------------
+      # ==== Allow configuration to validate uploaded avatars ====
+      #export AVATARS_UPLOAD_EXTERNAL_PROGRAM="/usr/local/bin/avscan {file}"
+      #export AVATARS_UPLOAD_MIME_TYPES="image/*"
+      #export AVATARS_UPLOAD_MAX_SIZE=500000
+      #---------------------------------------------------------------
       # ==== RICH TEXT EDITOR IN CARD COMMENTS ====
       # https://github.com/wekan/wekan/pull/2560
       export RICHER_CARD_COMMENT_EDITOR=false

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
snap-src/bin/config


+ 6 - 0
start-wekan.bat

@@ -55,9 +55,15 @@ REM # ==== ACCOUNT OPTIONS ====
 REM SET ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90
 
 REM # ==== Allow configuration to validate uploaded attachments ====
+REM SET ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM="avscan {file}"
 REM SET ATTACHMENTS_UPLOAD_MIME_TYPES="image/*,text/*"
 REM SET ATTACHMENTS_UPLOAD_MAX_SIZE=5000000
 
+REM # ==== Allow configuration to validate uploaded avatars ====
+REM SET AVATARS_UPLOAD_EXTERNAL_PROGRAM="avscan {file}"
+REM SET AVATARS_UPLOAD_MIME_TYPES="image/*"
+REM SET AVATARS_UPLOAD_MAX_SIZE=500000
+
 REM # ==== NOTIFICATION TRAY AFTER READ DAYS BEFORE REMOVE =====
 REM # Number of days after a notification is read before we remove it.
 REM # Default: 2

+ 5 - 0
start-wekan.sh

@@ -58,6 +58,11 @@
       #export ATTACHMENTS_UPLOAD_MIME_TYPES="image/*,text/*"
       #export ATTACHMENTS_UPLOAD_MAX_SIZE=5000000
       #---------------------------------------------------------------
+      # ==== Allow configuration to validate uploaded avatars ====
+      #export AVATARS_UPLOAD_EXTERNAL_PROGRAM="/usr/local/bin/avscan {file}"
+      #export AVATARS_UPLOAD_MIME_TYPES="image/*"
+      #export AVATARS_UPLOAD_MAX_SIZE=500000
+      #---------------------------------------------------------------
       # ==== RICH TEXT EDITOR IN CARD COMMENTS ====
       # https://github.com/wekan/wekan/pull/2560
       export RICHER_CARD_COMMENT_EDITOR=false

+ 5 - 0
torodb-postgresql/docker-compose.yml

@@ -281,6 +281,11 @@ services:
       #-ATTACHMENTS_UPLOAD_MIME_TYPES=image/*,text/*
       #-ATTACHMENTS_UPLOAD_MAX_SIZE=5000000
       #---------------------------------------------------------------
+      # ==== Allow configuration to validate uploaded avatars ====
+      #-AVATARS_UPLOAD_EXTERNAL_PROGRAM=/usr/local/bin/avscan {file}
+      #-AVATARS_UPLOAD_MIME_TYPES=image/*
+      #-AVATARS_UPLOAD_MAX_SIZE=500000
+      #---------------------------------------------------------------
       # ==== Allow to shrink attached/pasted image ====
       # https://github.com/wekan/wekan/pull/2544
       #-MAX_IMAGE_PIXEL=1024

Некоторые файлы не были показаны из-за большого количества измененных файлов