Browse Source

Merge branch 'reactify-admin/security' into reactify-admin/setup-twitter-auth

# Conflicts:
#	src/server/routes/apiv3/security-setting.js
itizawa 6 years ago
parent
commit
e2aad22b86

+ 73 - 0
src/client/js/components/Admin/Security/LdapAuthTestModal.jsx

@@ -0,0 +1,73 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withTranslation } from 'react-i18next';
+
+import Modal from 'react-bootstrap/es/Modal';
+
+import { createSubscribedElement } from '../../UnstatedUtils';
+
+import AdminLdapSecurityContainer from '../../../services/AdminLdapSecurityContainer';
+
+class LdapAuthTestModal extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.testLdapCredentials = this.testLdapCredentials.bind(this);
+  }
+
+  testLdapCredentials() {
+    // TODO GW-770 implement auth test
+  }
+
+  render() {
+    const { t } = this.props;
+
+    return (
+      <Modal show={this.props.isOpen} onHide={this.props.onClose}>
+        <Modal.Header className="modal-header" closeButton>
+          <Modal.Title>
+            {t('Test LDAP Account')}
+          </Modal.Title>
+        </Modal.Header>
+        <Modal.Body>
+          <div className="row p-3">
+            <label htmlFor="username" className="col-xs-3 text-right">{t('username')}</label>
+            <div className="col-xs-6">
+              <input className="form-control" name="username" />
+            </div>
+          </div>
+          <div className="row p-3">
+            <label htmlFor="password" className="col-xs-3 text-right">{t('Password')}</label>
+            <div className="col-xs-6">
+              <input className="form-control" type="password" name="password" />
+            </div>
+          </div>
+          <div>
+            <h5>Logs</h5>
+            <textarea id="taLogs" className="col-xs-12" rows="4" readOnly />
+          </div>
+        </Modal.Body>
+        <Modal.Footer>
+          <button type="button" className="btn btn-default mt-3 col-xs-offset-5 col-xs-2" onClick={this.testLdapCredentials}>{t('Test')}</button>
+        </Modal.Footer>
+      </Modal>
+    );
+  }
+
+}
+
+
+LdapAuthTestModal.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  adminLdapSecurityContainer: PropTypes.instanceOf(AdminLdapSecurityContainer).isRequired,
+
+  isOpen: PropTypes.bool.isRequired,
+  onClose: PropTypes.func.isRequired,
+};
+
+const LdapAuthTestModalWrapper = (props) => {
+  return createSubscribedElement(LdapAuthTestModal, props, [AdminLdapSecurityContainer]);
+};
+
+export default withTranslation()(LdapAuthTestModalWrapper);

+ 17 - 0
src/client/js/components/Admin/Security/LdapSecuritySetting.jsx

@@ -9,6 +9,7 @@ import { toastSuccess, toastError } from '../../../util/apiNotification';
 import AppContainer from '../../../services/AppContainer';
 import AdminGeneralSecurityContainer from '../../../services/AdminGeneralSecurityContainer';
 import AdminLdapSecurityContainer from '../../../services/AdminLdapSecurityContainer';
+import LdapAuthTestModal from './LdapAuthTestModal';
 
 const logger = loggerFactory('growi:security:AdminLdapSecurityContainer');
 
@@ -19,9 +20,12 @@ class LdapSecuritySetting extends React.Component {
 
     this.state = {
       retrieveError: null,
+      isLdapAuthTestModalShown: false,
     };
 
     this.onClickSubmit = this.onClickSubmit.bind(this);
+    this.openLdapAuthTestModal = this.openLdapAuthTestModal.bind(this);
+    this.closeLdapAuthTestModal = this.closeLdapAuthTestModal.bind(this);
   }
 
   async componentDidMount() {
@@ -50,6 +54,14 @@ class LdapSecuritySetting extends React.Component {
     }
   }
 
+  openLdapAuthTestModal() {
+    this.setState({ isLdapAuthTestModalShown: true });
+  }
+
+  closeLdapAuthTestModal() {
+    this.setState({ isLdapAuthTestModalShown: false });
+  }
+
   render() {
     const { t, adminGeneralSecurityContainer, adminLdapSecurityContainer } = this.props;
     const { isLdapEnabled } = adminGeneralSecurityContainer.state;
@@ -378,9 +390,14 @@ class LdapSecuritySetting extends React.Component {
         <div className="row my-3">
           <div className="col-xs-offset-3 col-xs-5">
             <button type="button" className="btn btn-primary" disabled={this.state.retrieveError != null} onClick={this.onClickSubmit}>{t('Update')}</button>
+            {adminGeneralSecurityContainer.state.isLdapEnabled
+              && <button type="button" className="btn btn-default ml-2" onClick={this.openLdapAuthTestModal}>{t('security_setting.ldap.test_config')}</button>
+            }
           </div>
         </div>
 
+        <LdapAuthTestModal isOpen={this.state.isLdapAuthTestModalShown} onClose={this.closeLdapAuthTestModal} />
+
       </React.Fragment>
     );
   }

+ 4 - 2
src/client/js/components/Admin/Security/SamlSecuritySetting.jsx

@@ -139,8 +139,10 @@ class SamlSecurityManagement extends React.Component {
               <div className="alert alert-danger">
                 {t('security_setting.missing mandatory configs')}
                 <ul>
-                  {/* TODO GW-750 show li after fetch data */}
-                  {/* <li>{ t('security_setting.form_item_name.key') }</li> */}
+                  {adminSamlSecurityContainer.state.missingMandatoryConfigKeys.map((configKey) => {
+                    const key = configKey.replace('security:passport-saml:', '');
+                    return <li key={configKey}>{t(`security_setting.form_item_name.${key}`)}</li>;
+                  })}
                 </ul>
               </div>
             )}

+ 2 - 2
src/client/js/components/Admin/Security/TwitterSecuritySetting.jsx

@@ -39,10 +39,10 @@ class TwitterSecurityManagement extends React.Component {
   }
 
   async onClickSubmit() {
-    const { t, adminGeneralSecurityContainer, adminTwitterSecurityContainer } = this.props;
+    const { t, adminTwitterSecurityContainer } = this.props;
 
     try {
-      await adminTwitterSecurityContainer.updateTwitterSetting(adminGeneralSecurityContainer.state.isTwitterOAuthEnabled);
+      await adminTwitterSecurityContainer.updateTwitterSetting();
       toastSuccess(t('security_setting.OAuth.Twitter.updated_twitter'));
     }
     catch (err) {

+ 2 - 0
src/client/js/services/AdminSamlSecurityContainer.js

@@ -44,6 +44,7 @@ export default class AdminSamlSecurityContainer extends Container {
     const response = await this.appContainer.apiv3.get('/security-setting/');
     const { samlAuth } = response.data.securityParams;
     this.setState({
+      missingMandatoryConfigKeys: samlAuth.missingMandatoryConfigKeys,
       samlEntryPoint: samlAuth.samlEntryPoint || '',
       samlIssuer: samlAuth.samlIssuer || '',
       samlCert: samlAuth.samlCert || '',
@@ -156,6 +157,7 @@ export default class AdminSamlSecurityContainer extends Container {
     const { securitySettingParams } = response.data;
 
     this.setState({
+      missingMandatoryConfigKeys: securitySettingParams.missingMandatoryConfigKeys,
       samlEntryPoint: securitySettingParams.samlEntryPoint || '',
       samlIssuer: securitySettingParams.samlIssuer || '',
       samlCert: securitySettingParams.samlCert || '',

+ 1 - 2
src/client/js/services/AdminTwitterSecurityContainer.js

@@ -72,10 +72,9 @@ export default class AdminTwitterSecurityContainer extends Container {
   /**
    * Update twitterSetting
    */
-  async updateTwitterSetting(isTwitterOAuthEnabled) {
+  async updateTwitterSetting() {
 
     const response = await this.appContainer.apiv3.put('/security-setting/twitter-oauth', {
-      isTwitterOAuthEnabled,
       twitterConsumerKey: this.state.twitterConsumerKey,
       twitterConsumerSecret: this.state.twitterConsumerSecret,
       isSameUsernameTreatedAsIdenticalUser: this.state.isSameUsernameTreatedAsIdenticalUser,

+ 5 - 4
src/server/routes/apiv3/security-setting.js

@@ -70,7 +70,6 @@ const validator = {
     body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
   ],
   twitterOAuth: [
-    body('isTwitterOAuthEnabled').isBoolean(),
     body('twitterConsumerKey').isString(),
     body('twitterConsumerSecret').isString(),
     body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
@@ -309,6 +308,7 @@ module.exports = (crowi) => {
         ldapGroupDnProperty: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupDnProperty'),
       },
       samlAuth: {
+        missingMandatoryConfigKeys: await crowi.passportService.getSamlMissingMandatoryConfigKeys(),
         samlEntryPoint: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:entryPoint'),
         samlEnvVarEntryPoint: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:entryPoint'),
         samlIssuer: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:issuer'),
@@ -509,6 +509,7 @@ module.exports = (crowi) => {
     try {
       await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
       const securitySettingParams = {
+        missingMandatoryConfigKeys: await crowi.passportService.getSamlMissingMandatoryConfigKeys(),
         samlEntryPoint: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:entryPoint'),
         samlIssuer: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:issuer'),
         samlCert: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:cert'),
@@ -738,7 +739,6 @@ module.exports = (crowi) => {
    */
   router.put('/twitter-oauth', loginRequiredStrictly, adminRequired, csrf, validator.twitterOAuth, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
-      'security:passport-twitter:isEnabled': req.body.isTwitterOAuthEnabled,
       'security:passport-twitter:consumerKey': req.body.twitterConsumerKey,
       'security:passport-twitter:consumerSecret': req.body.twitterConsumerSecret,
       'security:passport-twitter:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
@@ -751,17 +751,18 @@ module.exports = (crowi) => {
         twitterConsumerSecret: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:consumerSecret'),
         isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:isSameUsernameTreatedAsIdenticalUser'),
       };
+<<<<<<< HEAD
       // reset strategy
       await crowi.passportService.resetTwitterStrategy();
       // setup strategy
       if (crowi.configManager.getConfig('crowi', 'security:passport-twitter:isEnabled')) {
         await crowi.passportService.setupTwitterStrategy(true);
       }
+=======
+>>>>>>> reactify-admin/security
       return res.apiv3({ securitySettingParams });
     }
     catch (err) {
-      // reset
-      await crowi.passportService.resetTwitterStrategy();
       const msg = 'Error occurred in updating twitterOAuth';
       logger.error('Error', err);
       return res.apiv3Err(new ErrorV3(msg, 'update-twitterOAuth-failed'));