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

Merge branch 'reactify-admin/security' into call-api-security-general-setting

# Conflicts:
#	src/server/routes/apiv3/security-setting.js
WESEEK Kaito 6 лет назад
Родитель
Сommit
3549f6e306

+ 2 - 1
resource/locales/en-US/translation.json

@@ -544,7 +544,8 @@
       "enable_basic":"enable Basic",
       "name": "Basic Authentication",
       "desc_1": "Login with <code>username</code> in Authorization header.",
-      "desc_2": "User will be automatically generated if not exist."
+      "desc_2": "User will be automatically generated if not exist.",
+      "updated_basic": "Succeeded to update Basic setting"
     },
     "OAuth": {
       "enable_oidc": "enable OIDC",

+ 2 - 1
resource/locales/ja/translation.json

@@ -539,7 +539,8 @@
       "enable_basic":"Basic を有効にする",
       "name": "Basic 認証",
       "desc_1": "Authorization ヘッダに格納されている <code>username</code> でログインします。",
-      "desc_2": "ユーザーが存在しなかった場合は自動生成します。"
+      "desc_2": "ユーザーが存在しなかった場合は自動生成します。",
+      "updated_basic": "Basic認証 を更新しました"
     },
     "OAuth": {
       "enable_oidc": "OIDC を有効にする",

+ 52 - 0
src/client/js/components/Admin/Security/BasicSecuritySetting.jsx

@@ -2,15 +2,55 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
+import loggerFactory from '@alias/logger';
 
 import { createSubscribedElement } from '../../UnstatedUtils';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
 import AdminGeneralSecurityContainer from '../../../services/AdminGeneralSecurityContainer';
 import AdminBasicSecurityContainer from '../../../services/AdminBasicSecurityContainer';
 
+const logger = loggerFactory('growi:security:AdminTwitterSecurityContainer');
+
 class BasicSecurityManagement extends React.Component {
 
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      retrieveError: null,
+    };
+
+    this.onClickSubmit = this.onClickSubmit.bind(this);
+  }
+
+  async componentDidMount() {
+    const { adminBasicSecurityContainer } = this.props;
+
+    try {
+      await adminBasicSecurityContainer.retrieveSecurityData();
+    }
+    catch (err) {
+      toastError(err);
+      this.setState({ retrieveError: err });
+      logger.error(err);
+    }
+  }
+
+  async onClickSubmit() {
+    const { t, adminBasicSecurityContainer } = this.props;
+
+    try {
+      await adminBasicSecurityContainer.updateBasicSetting();
+      toastSuccess(t('security_setting.Basic.updated_basic'));
+    }
+    catch (err) {
+      toastError(err);
+      logger.error(err);
+    }
+  }
+
   render() {
     const { t, adminGeneralSecurityContainer, adminBasicSecurityContainer } = this.props;
 
@@ -21,6 +61,12 @@ class BasicSecurityManagement extends React.Component {
           { t('security_setting.Basic.name') } { t('security_setting.configuration') }
         </h2>
 
+        {this.state.retrieveError != null && (
+        <div className="alert alert-danger">
+          <p>{t('Error occurred')} : {this.state.err}</p>
+        </div>
+        )}
+
         <div className="row mb-5">
           <strong className="col-xs-3 text-right">{ t('security_setting.Basic.name') }</strong>
           <div className="col-xs-6 text-left">
@@ -68,6 +114,12 @@ class BasicSecurityManagement extends React.Component {
         </React.Fragment>
         )}
 
+        <div className="row my-3">
+          <div className="col-xs-offset-4 col-xs-5">
+            <button type="button" className="btn btn-primary" disabled={this.state.retrieveError != null} onClick={this.onClickSubmit}>{ t('Update') }</button>
+          </div>
+        </div>
+
       </React.Fragment>
     );
   }

+ 27 - 7
src/client/js/services/AdminBasicSecurityContainer.js

@@ -17,19 +17,22 @@ export default class AdminBasicSecurityContainer extends Container {
     this.appContainer = appContainer;
 
     this.state = {
-      // TODO GW-583 set value
-      isSameUsernameTreatedAsIdenticalUser: 'hoge',
+      isSameUsernameTreatedAsIdenticalUser: false,
     };
 
-    this.init();
-
   }
 
-  init() {
-    // TODO GW-583 fetch config value with api
+  /**
+   * retrieve security data
+   */
+  async retrieveSecurityData() {
+    const response = await this.appContainer.apiv3.get('/security-setting/');
+    const { basicAuth } = response.data.securityParams;
+    this.setState({
+      isSameUsernameTreatedAsIdenticalUser: basicAuth.isSameUsernameTreatedAsIdenticalUser || false,
+    });
   }
 
-
   /**
    * Workaround for the mangling in production build to break constructor.name
    */
@@ -44,4 +47,21 @@ export default class AdminBasicSecurityContainer extends Container {
     this.setState({ isSameUsernameTreatedAsIdenticalUser: !this.state.isSameUsernameTreatedAsIdenticalUser });
   }
 
+  /**
+   * Update basicSetting
+   */
+  async updateBasicSetting() {
+
+    const response = await this.appContainer.apiv3.put('/security-setting/basic', {
+      isSameUsernameTreatedAsIdenticalUser: this.state.isSameUsernameTreatedAsIdenticalUser,
+    });
+
+    const { securitySettingParams } = response.data;
+
+    this.setState({
+      isSameUsernameTreatedAsIdenticalUser: securitySettingParams.isSameUsernameTreatedAsIdenticalUser,
+    });
+    return response;
+  }
+
 }

+ 72 - 10
src/server/routes/apiv3/security-setting.js

@@ -19,6 +19,9 @@ const validator = {
     body('hideRestrictedByOwner').isBoolean(),
     body('hideRestrictedByGroup').isBoolean(),
   ],
+  basicAuth: [
+    body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
+  ],
   googleOAuth: [
     body('googleClientId').isString(),
     body('googleClientSecret').isString(),
@@ -52,21 +55,36 @@ const validator = {
  *        type: object
  *          GeneralSetting:
  *            type:object
- *              restrictGuestMode:
- *                type: string
- *                description: type of restrictGuestMode
- *              pageCompleteDeletionAuthority:
- *                type: string
- *                description: type of pageDeletionAuthority
- *              wikiMode:
- *                type: string
- *                description: type of wikiMode
- *              hideRestrictedByOwner:
+ *              GuestModeParams:
+ *                type: object
+ *                properties:
+ *                  restrictGuestMode:
+ *                    type: string
+ *                    description: type of restrictGuestMode
+ *              PageDeletionParams:
+ *                type: object
+ *                properties:
+ *                  pageCompleteDeletionAuthority:
+ *                    type: string
+ *                    description: type of pageDeletionAuthority
+ *              Function:
+ *                type: object
+ *                properties:
+ *                  hideRestrictedByOwner:
+ *                    type: boolean
+ *                    description: enable hide by owner
+ *                  hideRestrictedByGroup:
+ *                    type: boolean
+ *                    description: enable hide by group
+ *          BasicAuthSetting:
+ *            type:object
+ *              isSameUsernameTreatedAsIdenticalUser
  *                type: boolean
  *                description: enable hide by owner
  *              hideRestrictedByGroup:
  *                type: boolean
  *                description: enable hide by group
+ *                description: local account automatically linked the email matched
  *          GitHubOAuthSetting:
  *            type:object
  *              githubClientId:
@@ -136,10 +154,14 @@ module.exports = (crowi) => {
         wikiMode: await crowi.configManager.getConfig('crowi', 'security:wikiMode'),
       },
       generalAuth: {
+        isBasicEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-basic:isEnabled'),
         isGoogleOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-google:isEnabled'),
         isGithubOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-github:isEnabled'),
         isTwitterOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:isEnabled'),
       },
+      basicAuth: {
+        isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-basic:isSameUsernameTreatedAsIdenticalUser'),
+      },
       googleOAuth: {
         googleClientId: await crowi.configManager.getConfig('crowi', 'security:passport-google:clientId'),
         googleClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-google:clientSecret'),
@@ -224,6 +246,46 @@ module.exports = (crowi) => {
     }
   });
 
+  /**
+   * @swagger
+   *
+   *    /security-setting/google-oauth:
+   *      put:
+   *        tags: [SecuritySetting]
+   *        description: Update google OAuth
+   *        requestBody:
+   *          required: true
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/SecurityParams/BasicAuthSetting'
+   *        responses:
+   *          200:
+   *            description: Succeeded to google OAuth
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/SecurityParams/BasicAuthSetting'
+   */
+  router.put('/basic', loginRequiredStrictly, adminRequired, csrf, validator.basicAuth, ApiV3FormValidator, async(req, res) => {
+    const requestParams = {
+      'security:passport-basic:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
+    };
+
+    try {
+      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
+      const securitySettingParams = {
+        isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-basic:isSameUsernameTreatedAsIdenticalUser'),
+      };
+      return res.apiv3({ securitySettingParams });
+    }
+    catch (err) {
+      const msg = 'Error occurred in updating basicAuth';
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(msg, 'update-basicOAuth-failed'));
+    }
+  });
+
   /**
    * @swagger
    *