Explorar el Código

Merge pull request #1056 from weseek/imprv/abolish-old-config-api-app-fileupload

Imprv/abolish old config api app fileupload
Sou Mizobuchi hace 6 años
padre
commit
8812cbc105

+ 11 - 0
src/server/crowi/index.js

@@ -42,6 +42,7 @@ function Crowi(rootdir) {
   this.xssService = null;
   this.aclService = null;
   this.appService = null;
+  this.fileUploadService = null;
   this.restQiitaAPIService = null;
   this.cdnResourcesService = new CdnResourcesService();
   this.interceptorManager = new InterceptorManager();
@@ -95,6 +96,7 @@ Crowi.prototype.init = async function() {
     this.setupCsrf(),
     this.setUpGlobalNotification(),
     this.setUpSlacklNotification(),
+    this.setUpFileUpload(),
     this.setUpAcl(),
     this.setUpCustomize(),
     this.setUpRestQiitaAPI(),
@@ -500,6 +502,15 @@ Crowi.prototype.setUpApp = function() {
   }
 };
 
+/**
+ * setup FileUploadService
+ */
+Crowi.prototype.setUpFileUpload = function() {
+  if (this.fileUploadService == null) {
+    this.fileUploadService = require('../service/file-uploader')(this);
+  }
+};
+
 /**
  * setup RestQiitaAPIService
  */

+ 2 - 2
src/server/models/attachment.js

@@ -11,8 +11,6 @@ const mongoose = require('mongoose');
 const ObjectId = mongoose.Schema.Types.ObjectId;
 
 module.exports = function(crowi) {
-  const fileUploader = require('../service/file-uploader')(crowi);
-
   function generateFileHash(fileName) {
     const hash = require('crypto').createHash('md5');
     hash.update(`${fileName}_${Date.now()}`);
@@ -44,6 +42,7 @@ module.exports = function(crowi) {
 
 
   attachmentSchema.statics.create = async function(pageId, user, fileStream, originalName, fileFormat, fileSize) {
+    const fileUploader = require('../service/file-uploader')(crowi);
     const Attachment = this;
 
     const extname = path.extname(originalName);
@@ -94,6 +93,7 @@ module.exports = function(crowi) {
   };
 
   attachmentSchema.statics.removeWithSubstanceById = async function(id) {
+    const fileUploader = require('../service/file-uploader')(crowi);
     // retrieve data from DB to get a completely populated instance
     const attachment = await this.findById(id);
     await fileUploader.deleteFile(attachment);

+ 4 - 50
src/server/models/config.js

@@ -144,16 +144,6 @@ module.exports = function(crowi) {
     };
   }
 
-  function getValueForCrowiNS(config, key) {
-    crowi.configManager.getConfig('crowi', key);
-    // // return the default value if undefined
-    // if (undefined === config.crowi || undefined === config.crowi[key]) {
-    //   return getDefaultCrowiConfigs()[key];
-    // }
-
-    // return config.crowi[key];
-  }
-
   function getValueForMarkdownNS(config, key) {
     crowi.configManager.getConfig('markdown', key);
     // // return the default value if undefined
@@ -165,7 +155,7 @@ module.exports = function(crowi) {
   }
 
   /**
-   * It is deprecated to use this for anything other than ConfigManager#isDBInitialized.
+   * It is deprecated to use this for anything other than AppService#isDBInitialized.
    */
   configSchema.statics.getConfigsObjectForInstalling = function() {
     return getConfigsForInstalling();
@@ -302,30 +292,6 @@ module.exports = function(crowi) {
   //     });
   // };
 
-  configSchema.statics.appTitle = function() {
-    const key = 'app:title';
-    return getValueForCrowiNS(null, key) || 'GROWI';
-  };
-
-  configSchema.statics.globalLang = function(config) {
-    const key = 'app:globalLang';
-    return getValueForCrowiNS(config, key);
-  };
-
-  configSchema.statics.isUploadable = function(config) {
-    const method = process.env.FILE_UPLOAD || 'aws';
-
-    if (method === 'aws' && (
-      !config.crowi['aws:accessKeyId']
-        || !config.crowi['aws:secretAccessKey']
-        || !config.crowi['aws:region']
-        || !config.crowi['aws:bucket'])) {
-      return false;
-    }
-
-    return method !== 'none';
-  };
-
   configSchema.statics.isGuestAllowedToRead = function(config) {
     // return true if puclic wiki mode
     if (crowi.aclService.getIsPublicWikiOnly()) {
@@ -424,17 +390,6 @@ module.exports = function(crowi) {
     }
   };
 
-  configSchema.statics.fileUploadEnabled = function(config) {
-    const Config = this;
-
-    if (!Config.isUploadable(config)) {
-      return false;
-    }
-
-    // convert to boolean
-    return !!config.crowi['app:fileUpload'];
-  };
-
   configSchema.statics.hasSlackConfig = function(config) {
     return Config.hasSlackToken(config) || Config.hasSlackIwhUrl(config);
   };
@@ -465,17 +420,16 @@ module.exports = function(crowi) {
   };
 
   configSchema.statics.getLocalconfig = function() { // CONF.RF: これも別のメソッドにする
-    const Config = this;
     const env = process.env;
 
     const localConfig = {
       crowi: {
-        title: Config.appTitle(crowi),
+        title: crowi.appService.getAppTitle(),
         url: crowi.appService.getSiteUrl(),
       },
       upload: {
-        image: crowi.configManager.getIsUploadable(),
-        file: crowi.configManager.getConfig('crowi', 'app:fileUpload'),
+        image: crowi.fileUploadService.getIsUploadable(),
+        file: crowi.fileUploadService.getFileUploadEnabled(),
       },
       behaviorType: crowi.configManager.getConfig('crowi', 'customize:behavior'),
       layoutType: crowi.configManager.getConfig('crowi', 'customize:layout'),

+ 2 - 2
src/server/routes/installer.js

@@ -4,7 +4,7 @@ module.exports = function(crowi, app) {
   const fs = require('graceful-fs');
 
   const models = crowi.models;
-  const configManager = crowi.configManager;
+  const { appService } = crowi;
 
   const User = models.User;
   const Page = models.Page;
@@ -67,7 +67,7 @@ module.exports = function(crowi, app) {
     const password = registerForm.password;
     const language = registerForm['app:globalLang'] || 'en-US';
 
-    await configManager.initDB(language);
+    await appService.initDB(language);
 
     // create first admin user
     let adminUser;

+ 14 - 0
src/server/service/app.js

@@ -35,6 +35,20 @@ class AppService {
   }
   /* eslint-enable no-else-return */
 
+  /**
+   * Execute only once for installing application
+   */
+  async initDB(globalLang) {
+    const initialConfig = this.configManager.configModel.getConfigsObjectForInstalling();
+    initialConfig['app:globalLang'] = globalLang;
+    await this.configManager.updateConfigsInTheSameNamespace('crowi', initialConfig);
+  }
+
+  async isDBInitialized() {
+    const appInstalled = await this.configManager.getConfigFromDB('crowi', 'app:installed');
+    return appInstalled;
+  }
+
 }
 
 module.exports = AppService;

+ 0 - 30
src/server/service/config-manager.js

@@ -134,22 +134,6 @@ class ConfigManager {
     return this.searchOnlyFromEnvVarConfigs(namespace, key);
   }
 
-  // CONF.RF refactor file-uploader
-  // create parent class and each uploader inherits from it.
-  getIsUploadable() {
-    const method = process.env.FILE_UPLOAD || 'aws';
-
-    if (method === 'aws' && (
-      !this.getConfig('crowi', 'aws:accessKeyId')
-        || !this.getConfig('crowi', 'aws:secretAccessKey')
-        || !this.getConfig('crowi', 'aws:region')
-        || !this.getConfig('crowi', 'aws:bucket'))) {
-      return false;
-    }
-
-    return method !== 'none';
-  }
-
   /**
    * update configs in the same namespace
    *
@@ -185,20 +169,6 @@ class ConfigManager {
     this.reloadConfigKeys();
   }
 
-  /**
-   * Execute only once for installing application
-   */
-  async initDB(globalLang) {
-    const initialConfig = this.configModel.getConfigsObjectForInstalling();
-    initialConfig['app:globalLang'] = globalLang;
-    await this.updateConfigsInTheSameNamespace('crowi', initialConfig);
-  }
-
-  async isDBInitialized() {
-    const appInstalled = await this.getConfigFromDB('crowi', 'app:installed');
-    return appInstalled;
-  }
-
   /*
    * All of the methods below are private APIs.
    */

+ 6 - 7
src/server/service/file-uploader/aws.js

@@ -5,7 +5,8 @@ const urljoin = require('url-join');
 const aws = require('aws-sdk');
 
 module.exports = function(crowi) {
-  const lib = {};
+  const Uploader = require('./uploader');
+  const lib = new Uploader(crowi.configManager);
 
   function getAwsConfig() {
     const config = crowi.getConfig();
@@ -17,12 +18,10 @@ module.exports = function(crowi) {
     };
   }
 
-  function S3Factory() {
+  function S3Factory(isUploadable) {
     const awsConfig = getAwsConfig();
-    const Config = crowi.model('Config');
-    const config = crowi.getConfig();
 
-    if (!Config.isUploadable(config)) {
+    if (!isUploadable) {
       throw new Error('AWS is not configured.');
     }
 
@@ -54,7 +53,7 @@ module.exports = function(crowi) {
   };
 
   lib.deleteFileByFilePath = async function(filePath) {
-    const s3 = S3Factory();
+    const s3 = S3Factory(this.getIsUploadable());
     const awsConfig = getAwsConfig();
 
     const params = {
@@ -68,7 +67,7 @@ module.exports = function(crowi) {
   lib.uploadFile = function(fileStream, attachment) {
     logger.debug(`File uploading: fileName=${attachment.fileName}`);
 
-    const s3 = S3Factory();
+    const s3 = S3Factory(this.getIsUploadable());
     const awsConfig = getAwsConfig();
 
     const filePath = getFilePathOnStorage(attachment);

+ 2 - 1
src/server/service/file-uploader/gridfs.js

@@ -3,7 +3,8 @@ const mongoose = require('mongoose');
 const util = require('util');
 
 module.exports = function(crowi) {
-  const lib = {};
+  const Uploader = require('./uploader');
+  const lib = new Uploader(crowi.configManager);
   const COLLECTION_NAME = 'attachmentFiles';
   const CHUNK_COLLECTION_NAME = `${COLLECTION_NAME}.chunks`;
 

+ 1 - 0
src/server/service/file-uploader/index.js

@@ -22,6 +22,7 @@ class FileUploaderFactory {
 }
 
 const factory = new FileUploaderFactory();
+
 module.exports = (crowi) => {
   return factory.getUploader(crowi);
 };

+ 2 - 1
src/server/service/file-uploader/local.js

@@ -6,7 +6,8 @@ const mkdir = require('mkdirp');
 const streamToPromise = require('stream-to-promise');
 
 module.exports = function(crowi) {
-  const lib = {};
+  const Uploader = require('./uploader');
+  const lib = new Uploader(crowi.configManager);
   const basePath = path.posix.join(crowi.publicDir, 'uploads');
 
   function getFilePathOnStorage(attachment) {

+ 2 - 2
src/server/service/file-uploader/none.js

@@ -2,8 +2,8 @@
 
 module.exports = function(crowi) {
   const debug = require('debug')('growi:service:fileUploaderNone');
-
-  const lib = {};
+  const Uploader = require('./uploader');
+  const lib = new Uploader(crowi.configManager);
 
   lib.deleteFile = function(filePath) {
     debug(`File deletion: ${filePath}`);

+ 34 - 0
src/server/service/file-uploader/uploader.js

@@ -0,0 +1,34 @@
+// file uploader virtual class
+// 各アップローダーで共通のメソッドはここで定義する
+
+class Uploader {
+
+  constructor(configManager) {
+    this.configManager = configManager;
+  }
+
+  getIsUploadable() {
+    const method = process.env.FILE_UPLOAD || 'aws';
+
+    if (method === 'aws' && (
+      !this.configManager.getConfig('crowi', 'aws:accessKeyId')
+        || !this.configManager.getConfig('crowi', 'aws:secretAccessKey')
+        || !this.configManager.getConfig('crowi', 'aws:region')
+        || !this.configManager.getConfig('crowi', 'aws:bucket'))) {
+      return false;
+    }
+
+    return method !== 'none';
+  }
+
+  getFileUploadEnabled() {
+    if (!this.getIsUploadable()) {
+      return false;
+    }
+
+    return !!this.configManager.getConfig('crowi', 'app:fileUpload');
+  }
+
+}
+
+module.exports = Uploader;

+ 1 - 3
src/server/service/global-notification.js

@@ -7,12 +7,10 @@ class GlobalNotificationService {
 
   constructor(crowi) {
     this.crowi = crowi;
-    this.config = crowi.getConfig();
     this.mailer = crowi.getMailer();
     this.GlobalNotification = crowi.model('GlobalNotificationSetting');
     this.User = crowi.model('User');
-    this.Config = crowi.model('Config');
-    this.appTitle = this.Config.appTitle(this.config);
+    this.appTitle = crowi.appService.getAppTitle();
   }
 
   notifyByMail(notification, mailOption) {

+ 2 - 3
src/server/util/mailer.js

@@ -7,8 +7,7 @@ module.exports = function(crowi) {
   const nodemailer = require('nodemailer');
   const swig = require('swig-templates');
 
-  const Config = crowi.model('Config');
-  const configManager = crowi.configManager;
+  const { configManager, appService } = crowi;
 
   const mailConfig = {};
   let mailer = {};
@@ -74,7 +73,7 @@ module.exports = function(crowi) {
     }
 
     mailConfig.from = configManager.getConfig('crowi', 'mail:from');
-    mailConfig.subject = `${Config.appTitle()}からのメール`;
+    mailConfig.subject = `${appService.getAppTitle()}からのメール`;
 
     debug('mailer initialized');
   }

+ 3 - 2
src/server/util/middlewares.js

@@ -5,6 +5,7 @@ const md5 = require('md5');
 const entities = require('entities');
 
 module.exports = (crowi, app) => {
+  const { appService } = crowi;
 
   const middlewares = {};
 
@@ -274,7 +275,7 @@ module.exports = (crowi, app) => {
 
   // this is for Installer
   middlewares.applicationNotInstalled = async function(req, res, next) {
-    const isInstalled = await crowi.configManager.isDBInitialized();
+    const isInstalled = await appService.isDBInitialized();
 
     if (isInstalled) {
       req.flash('errorMessage', 'Application already installed.');
@@ -285,7 +286,7 @@ module.exports = (crowi, app) => {
   };
 
   middlewares.applicationInstalled = async function(req, res, next) {
-    const isInstalled = await crowi.configManager.isDBInitialized();
+    const isInstalled = await appService.isDBInitialized();
 
     if (!isInstalled) {
       return res.redirect('/installer');

+ 10 - 19
src/server/util/swigFunctions.js

@@ -4,7 +4,13 @@ module.exports = function(crowi, app, req, locals) {
   const Page = crowi.model('Page');
   const Config = crowi.model('Config');
   const User = crowi.model('User');
-  const { passportService, cdnResourcesService, configManager } = crowi;
+  const {
+    configManager,
+    cdnResourcesService,
+    passportService,
+    appService,
+    fileUploadService,
+  } = crowi;
   debug('initializing swigFunctions');
 
   locals.nodeVersion = function() {
@@ -55,20 +61,10 @@ module.exports = function(crowi, app, req, locals) {
   locals.getConfigFromEnvVars = configManager.getConfigFromEnvVars.bind(configManager);
 
   /**
-   * return app title
+   * pass service class to swig
    */
-  locals.appTitle = function() {
-    const config = crowi.getConfig();
-    return crowi.xss.process(Config.appTitle(config));
-  };
-
-  /**
-   * return app-global language
-   */
-  locals.appGlobalLang = function() {
-    const config = crowi.getConfig();
-    return Config.globalLang(config);
-  };
+  locals.appService = appService;
+  locals.fileUploadService = fileUploadService;
 
   locals.noCdn = function() {
     return !!process.env.NO_CDN;
@@ -218,11 +214,6 @@ module.exports = function(crowi, app, req, locals) {
     return configManager.getConfig('crowi', 'customize:isEnabledTimeline');
   };
 
-  locals.isUploadable = function() {
-    const config = crowi.getConfig();
-    return Config.isUploadable(config);
-  };
-
   locals.parentPath = function(path) {
     if (path === '/') {
       return path;

+ 3 - 3
src/server/views/admin/app.html

@@ -72,7 +72,7 @@
                        id="radioLangEn"
                        name="settingForm[app:globalLang]"
                        value="{{ consts.language.LANG_EN_US }}"
-                       {% if appGlobalLang() == consts.language.LANG_EN_US %}checked="checked"{% endif %}>
+                       {% if getConfig('crowi', 'app:globalLang') == consts.language.LANG_EN_US %}checked="checked"{% endif %}>
                 <label for="radioLangEn">{{ t('English') }}</label>
             </div>
             <div class="radio radio-primary radio-inline">
@@ -80,7 +80,7 @@
                        id="radioLangJa"
                        name="settingForm[app:globalLang]"
                        value="{{ consts.language.LANG_JA }}"
-                       {% if appGlobalLang() == consts.language.LANG_JA %}checked="checked"{% endif %}>
+                       {% if getConfig('crowi', 'app:globalLang') == consts.language.LANG_JA %}checked="checked"{% endif %}>
                 <label for="radioLangJa">{{ t('Japanese') }}</label>
             </div>
           </div>
@@ -95,7 +95,7 @@
                      name="settingForm[app:fileUpload]"
                      value="1"
                      {% if settingForm['app:fileUpload'] %}checked{% endif %}
-                     {% if not isUploadable() %}disabled="disabled"{% endif %}>
+                     {% if not fileUploadService.getIsUploadable() %}disabled="disabled"{% endif %}>
               <label for="cbFileUpload">
                 {{ t("app_setting.enable_files_except_image") }}
               </label>

+ 1 - 1
src/server/views/installer.html

@@ -10,7 +10,7 @@
 
   <meta name="viewport" content="width=device-width,initial-scale=1">
 
-  <meta name="apple-mobile-web-app-title" content="{{ appTitle() }}">
+  <meta name="apple-mobile-web-app-title" content="{{ appService.appTitle() }}">
 
   {% include './widget/headers/favicon.html' %}
   {% include './widget/headers/ie11-polyfills.html' %}

+ 2 - 2
src/server/views/layout/layout.html

@@ -10,7 +10,7 @@
 
   <meta name="viewport" content="width=device-width,initial-scale=1">
 
-  <meta name="apple-mobile-web-app-title" content="{{ appTitle() }}">
+  <meta name="apple-mobile-web-app-title" content="{{ appService.appTitle() }}">
 
   {{ customHeader() }}
 
@@ -86,7 +86,7 @@
             <div class="logo-mark">{% include '../widget/logo.html' %}</div>
           </b>
           <span class="hidden-xs" style="color: black">
-            {% set appTitle = appTitle() %}
+            {% set appTitle = appService.appTitle() %}
             {% set appTitleFontSize = getAppTitleFontSize(appTitle) %}
             <span class="logo-text">
               <svg xmlns="http://www.w3.org/2000/svg">

+ 1 - 1
src/server/views/login.html

@@ -27,7 +27,7 @@
   <div class="row">
     <div class="login-header col-sm-offset-4 col-sm-4">
       <div class="logo">{% include 'widget/logo.html' %}</div>
-      <h1>{{ appTitle() }}</h1>
+      <h1>{{ appService.appTitle() }}</h1>
 
       <div class="login-form-errors">
         {% if isLdapSetupFailed() %}

+ 1 - 1
src/server/views/me/index.html

@@ -172,7 +172,7 @@
             {{ t('Upload new image') }}
           </label>
           <div class="col-sm-8">
-            {% if isUploadable() %}
+            {% if fileUploadService.getIsUploadable() %}
             <form action="/_api/attachments.uploadProfileImage" id="pictureUploadForm" method="post" class="form-horizontal" role="form">
               <input type="hidden" name="_csrf" value="{{ csrf() }}">
               <input type="file" name="profileImage" accept="image/*">