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

Merge pull request #1812 from weseek/imprv/enhanced-env-vars

Imprv/enhanced env vars
Yuki Takei 6 лет назад
Родитель
Сommit
49e86e2131

+ 4 - 1
resource/locales/en-US/admin/admin.json

@@ -7,7 +7,10 @@
     "list_of_installed_plugins": "List of installed plugins",
     "package_name": "Package name",
     "specified_version": "Specified version",
-    "installed_version": "Installed version"
+    "installed_version": "Installed version",
+    "list_of_env_vars":"List of environment variables",
+    "env_var_priority": "For environment variables other than security, the value of the database is obtained preferentially.",
+    "about_security": "Check <a href='/admin/security'>Securtiy Management</a> for security environment variables."
   },
   "app_setting": {
     "site_name": "Site name",

+ 4 - 1
resource/locales/ja/admin/admin.json

@@ -7,7 +7,10 @@
     "list_of_installed_plugins": "インストールされているプラグイン一覧",
     "package_name": "パッケージ名",
     "specified_version": "指定バージョン",
-    "installed_version": "インストールされているバージョン"
+    "installed_version": "インストールされているバージョン",
+    "list_of_env_vars":"サーバー側で設定されている環境変数一覧",
+    "env_var_priority":"セキュリティに関する環境変数を除き、データベースの値が優先的に取得されます。",
+    "about_security":"セキュリティに関する環境変数は <a href='/admin/security'>セキュリティ設定画面</a> からご確認ください。"
   },
   "app_setting": {
     "site_name": "サイト名",

+ 12 - 1
src/client/js/components/Admin/AdminHome/AdminHome.jsx

@@ -10,6 +10,7 @@ import AppContainer from '../../../services/AppContainer';
 import AdminHomeContainer from '../../../services/AdminHomeContainer';
 import SystemInfomationTable from './SystemInfomationTable';
 import InstalledPluginTable from './InstalledPluginTable';
+import EnvVarsTable from './EnvVarsTable';
 
 const logger = loggerFactory('growi:admin');
 
@@ -29,7 +30,7 @@ class AdminHome extends React.Component {
   }
 
   render() {
-    const { t } = this.props;
+    const { t, adminHomeContainer } = this.props;
 
     return (
       <Fragment>
@@ -52,6 +53,16 @@ class AdminHome extends React.Component {
             <InstalledPluginTable />
           </div>
         </div>
+
+        <div className="row mb-5">
+          <div className="col-md-12">
+            <h2 className="admin-setting-header">{t('admin:admin_top.list_of_env_vars')}</h2>
+            <p>{t('admin:admin_top.env_var_priority')}</p>
+            {/* eslint-disable-next-line react/no-danger */}
+            <p dangerouslySetInnerHTML={{ __html: t('admin:admin_top.about_security') }} />
+            {adminHomeContainer.state.envVars && <EnvVarsTable envVars={adminHomeContainer.state.envVars} />}
+          </div>
+        </div>
       </Fragment>
     );
   }

+ 32 - 0
src/client/js/components/Admin/AdminHome/EnvVarsTable.jsx

@@ -0,0 +1,32 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const EnvVarsTable = (props) => {
+  const envVarRows = [];
+
+  for (const [key, value] of Object.entries(props.envVars)) {
+    if (value != null) {
+      envVarRows.push(
+        <tr key={key}>
+          <th className="col-sm-4">{key}</th>
+          <td>{value.toString()}</td>
+        </tr>,
+      );
+    }
+  }
+
+  return (
+    <table className="table table-bordered">
+      <tbody>
+        {envVarRows}
+      </tbody>
+    </table>
+  );
+
+};
+
+EnvVarsTable.propTypes = {
+  envVars: PropTypes.object.isRequired,
+};
+
+export default EnvVarsTable;

+ 1 - 0
src/client/js/services/AdminHomeContainer.js

@@ -50,6 +50,7 @@ export default class AdminHomeContainer extends Container {
         npmVersion: adminHomeParams.npmVersion,
         yarnVersion: adminHomeParams.yarnVersion,
         installedPlugins: adminHomeParams.installedPlugins,
+        envVars: adminHomeParams.envVars,
       });
     }
     catch (err) {

+ 12 - 0
src/lib/util/isSecurityEnv.js

@@ -0,0 +1,12 @@
+/**
+ * return whether env belongs to Security settings
+ * @param {string} key ex. 'security:passport-saml:isEnabled' is true
+ * @returns {boolean}
+ * @memberof envUtils
+ */
+const isSecurityEnv = (key) => {
+  const array = key.split(':');
+  return (array[0] === 'security');
+};
+
+module.exports = isSecurityEnv;

+ 2 - 0
src/server/routes/apiv3/admin-home.js

@@ -1,5 +1,6 @@
 const express = require('express');
 const PluginUtils = require('../../plugins/plugin-utils');
+const ConfigLoader = require('../../service/config-loader');
 
 const pluginUtils = new PluginUtils();
 
@@ -70,6 +71,7 @@ module.exports = (crowi) => {
       npmVersion: crowi.runtimeVersions.versions.npm ? crowi.runtimeVersions.versions.npm.version.version : '-',
       yarnVersion: crowi.runtimeVersions.versions.yarn ? crowi.runtimeVersions.versions.yarn.version.version : '-',
       installedPlugins: pluginUtils.listPlugins(crowi.rootDir),
+      envVars: await ConfigLoader.getEnvVarsForDisplay(true),
     };
 
     return res.apiv3({ adminHomeParams });

+ 24 - 1
src/server/service/config-loader.js

@@ -1,6 +1,7 @@
 const debug = require('debug')('growi:service:ConfigLoader');
-
 const { envUtils } = require('growi-commons');
+const isSecurityEnv = require('../../lib/util/isSecurityEnv');
+
 
 const TYPES = {
   NUMBER:  { parse: (v) => { return parseInt(v, 10) } },
@@ -349,6 +350,28 @@ class ConfigLoader {
     return config;
   }
 
+  /**
+   * get config from the environment variables for display admin page
+   *
+   * **use this only admin home page.**
+   */
+  static getEnvVarsForDisplay(avoidSecurity = false) {
+    const config = {};
+    for (const ENV_VAR_NAME of Object.keys(ENV_VAR_NAME_TO_CONFIG_INFO)) {
+      const configInfo = ENV_VAR_NAME_TO_CONFIG_INFO[ENV_VAR_NAME];
+      if (process.env[ENV_VAR_NAME] === undefined) {
+        continue;
+      }
+      if (isSecurityEnv(configInfo.key) && avoidSecurity) {
+        continue;
+      }
+      config[ENV_VAR_NAME] = configInfo.type.parse(process.env[ENV_VAR_NAME]);
+    }
+
+    debug('ConfigLoader#getEnvVarsForDisplay', config);
+    return config;
+  }
+
 }
 
 module.exports = ConfigLoader;

+ 4 - 1
src/server/service/export.js

@@ -6,6 +6,7 @@ const mongoose = require('mongoose');
 const { Transform } = require('stream');
 const streamToPromise = require('stream-to-promise');
 const archiver = require('archiver');
+const ConfigLoader = require('../service/config-loader');
 
 const toArrayIfNot = require('../../lib/util/toArrayIfNot');
 
@@ -76,12 +77,14 @@ class ExportService {
   async createMetaJson() {
     const metaJson = path.join(this.baseDir, this.growiBridgeService.getMetaFileName());
     const writeStream = fs.createWriteStream(metaJson, { encoding: this.growiBridgeService.getEncoding() });
+    const passwordSeed = this.crowi.env.PASSWORD_SEED || null;
 
     const metaData = {
       version: this.crowi.version,
       url: this.appService.getSiteUrl(),
-      passwordSeed: this.crowi.env.PASSWORD_SEED,
+      passwordSeed,
       exportedAt: new Date(),
+      envVars: ConfigLoader.getEnvVarsForDisplay(),
     };
 
     writeStream.write(JSON.stringify(metaData));