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

WIP: impl /me/external-account/associate

ensure that authentication with LdapStrategy process only LDAP authentication (now it doesn't process ExternalAccount.findOrRegister)
Yuki Takei 8 лет назад
Родитель
Сommit
7e8db171a7

+ 1 - 1
lib/form/index.js

@@ -7,7 +7,7 @@ module.exports = {
   me: {
     user: require('./me/user'),
     password: require('./me/password'),
-    associateExternalAccount: require('./me/associate-external-account'),
+    associateLdapAccount: require('./me/associate-ldap'),
     imagetype: require('./me/imagetype'),
     apiToken: require('./me/apiToken'),
   },

+ 0 - 0
lib/form/me/associate-external-account.js → lib/form/me/associate-ldap.js


+ 4 - 3
lib/routes/index.js

@@ -111,9 +111,10 @@ module.exports = function(crowi, app) {
   app.post('/me'                      , form.me.user              , loginRequired(crowi, app) , me.index);
   // external-accounts
   if (Config.isEnabledPassport(config)) {
-    app.get('/me/external-accounts'     , loginRequired(crowi, app) , me.externalAccounts.list);
-    app.post('/me/external-accounts/associate'    , form.me.associateExternalAccount , loginRequired(crowi, app) , me.externalAccounts.associate);
-    app.post('/me/external-accounts/disassociate' , loginRequired(crowi, app) , me.externalAccounts.disassociate);
+    app.get('/me/external-accounts'                         , loginRequired(crowi, app) , me.externalAccounts.list);
+    app.post('/me/external-accounts/disassociate'           , loginRequired(crowi, app) , me.externalAccounts.disassociate);
+    app.post('/me/external-accounts/associateLdap'          , loginRequired(crowi, app) , form.me.associateLdapAccount , me.externalAccounts.associateLdap);
+    app.post('/_api/me/external-accounts/testAssociateLdap' , loginRequired(crowi, app) , form.me.associateLdapAccount , me.api.externalAccounts.testAssociateLdap);
   }
   app.post('/me/password'             , form.me.password          , loginRequired(crowi, app) , me.password);
   app.post('/me/imagetype'            , form.me.imagetype         , loginRequired(crowi, app) , me.imagetype);

+ 28 - 24
lib/routes/me.js

@@ -177,47 +177,51 @@ module.exports = function(crowi, app) {
       });
   }
 
-  actions.externalAccounts.associate = function(req, res) {
+  actions.externalAccounts.disassociate = function(req, res) {
+    // TODO impl
+    // TODO check password is set
+  }
+
+  actions.externalAccounts.associateLdap = function(req, res) {
+
+  }
+
+  api.externalAccounts = {}
+  api.externalAccounts.testAssociateLdap = (req, res) => {
     const passport = require('passport');
     const passportService = crowi.passportService;
 
     if (!passportService.isLdapStrategySetup) {
       debug('LdapStrategy has not been set up');
-      req.flash('warningMessage', 'LdapStrategy has not been set up');
-      return res.redirect('/me/external-accounts');
+      return res.json({
+        status: 'warning',
+        message: 'LdapStrategy has not been set up',
+      });
     }
 
     const loginForm = req.body.loginForm;
 
-    if (!req.form.isValid) {
-      debug('invalid form');
-      req.flash('warningMessage', 'invalid form');
-      return res.redirect('/me/external-accounts');
-    }
-
-    console.log(loginForm);
-
     passport.authenticate('ldapauth', (err, user, info) => {
-      console.log(err);
-      console.log(info);
-      console.log(user);
-
       if (err) {  // DB Error
         console.log('LDAP Server Error: ', err);
-        req.flash('warningMessage', 'LDAP Server Error occured.');
+        return res.json({
+          status: 'warning',
+          message: 'LDAP Server Error occured.',
+        });
       }
       if (info && info.message) {
-        req.flash('warningMessage', info.message);
+        return res.json({
+          status: 'warning',
+          message: info.message,
+        });
       }
       if (user) {
-        req.flash('successMessage', 'Successfully added.');
+        return res.json({
+          status: 'success',
+          message: 'Successfully authenticated.',
+        });
       }
-    })(req, res, () => {res.redirect('/me/external-accounts')});
-  }
-
-  actions.externalAccounts.disassociate = function(req, res) {
-    // TODO impl
-    // TODO check password is set
+    })(req, res, () => {});
   }
 
   actions.password = function(req, res) {

+ 6 - 4
lib/service/passport.js

@@ -118,10 +118,8 @@ class PassportService {
     passport.use(new LdapStrategy(this.getLdapConfigurationFunc(config, {passReqToCallback: true}),
       (req, ldapAccountInfo, done) => {
         debug("LDAP authentication has succeeded", ldapAccountInfo);
-
-        // TODO impl test mode
-
-
+        done(null, ldapAccountInfo);
+        /*
         const ExternalAccount = this.crowi.model('ExternalAccount');
 
         // it is guaranteed that username that is input from form can be acquired
@@ -141,6 +139,7 @@ class PassportService {
           .catch((err) => {
             done(null, false, err);
           });
+        */
       }
     ));
 
@@ -196,6 +195,9 @@ class PassportService {
     debug(`LdapStrategy: searchFilter=${searchFilter}`);
 
     return (req, callback) => {
+      // TODO impl test mode
+
+
       // get credentials from form data
       const loginForm = req.body.loginForm;
       if (!req.form.isValid) {

+ 110 - 22
lib/views/me/external-accounts.html

@@ -115,36 +115,124 @@
 
         <div class="modal-body">
 
-          <div id="form-box">
-            <form action="/me/external-accounts/associate" method="post" class="form-horizontal" role="form">
-            <fieldset>
-              <div class="form-group">
-                <label for="username" class="col-xs-3 control-label">{{ t('Username') }}</label>
-                <div class="col-xs-6">
-                  <input class="form-control" name="loginForm[username]">
-                </div>
-              </div>
-              <div class="form-group">
-                <label for="password" class="col-xs-3 control-label">{{ t('Password') }}</label>
-                <div class="col-xs-6">
-                  <input class="form-control col-xs-4" type="password" name="loginForm[password]">
-                </div>
+          <ul class="nav nav-tabs passport-settings" role="tablist">
+            <li class="active">
+              <a href="#passport-ldap" data-toggle="tab" role="tab"><i class="fa fa-sitemap"></i> LDAP</a>
+            </li>
+            <li>
+              <a href="#passport-google-oauth" data-toggle="tab" role="tab"><i class="fa fa-google"></i> Google OAuth</a>
+            </li>
+            <li>
+              <a href="#passport-facebook" data-toggle="tab" role="tab"><i class="fa fa-facebook"></i> Facebook</a>
+            </li>
+            <li>
+              <a href="#passport-twitter" data-toggle="tab" role="tab"><i class="fa fa-twitter"></i> Twitter</a>
+            </li>
+            <li>
+              <a href="#passport-github" data-toggle="tab" role="tab"><i class="fa fa-github"></i> Github</a>
+            </li>
+          </ul>
+
+          <div class="tab-content passport-settings">
+            <div id="passport-ldap" class="tab-pane active" role="tabpanel" >
+              <div id="form-box">
+                <form id="formLdapAssociation" method="post" class="form-horizontal" role="form">
+                  <fieldset>
+                    <div class="form-group">
+                      <label for="username" class="col-xs-3 control-label">{{ t('Username') }}</label>
+                      <div class="col-xs-6">
+                        <input class="form-control" name="loginForm[username]">
+                      </div>
+                    </div>
+                    <div class="form-group">
+                      <label for="password" class="col-xs-3 control-label">{{ t('Password') }}</label>
+                      <div class="col-xs-6">
+                        <input class="form-control col-xs-4" type="password" name="loginForm[password]">
+                      </div>
+                    </div>
+
+                    <div class="form-group">
+                      <div class="col-xs-12 text-right">
+                        <button type="button" class="btn btn-default" onclick="testAssociateLdap()">{{ t('Test') }}</button>
+                        <button type="button" class="btn btn-primary" onclick="associateLdap()">{{ t('Save') }}</button>
+                      </div>
+                    </div>
+
+                  </fieldset>
+                </form>
               </div>
+            </div>
 
-              <div class="form-group">
-                <div class="col-xs-offset-2 col-xs-10">
-                  <button type="submit" class="btn btn-primary">{{ t('Associate') }}</button>
-                </div>
-              </div>
+            <div id="passport-google-oauth" class="tab-pane" role="tabpanel">
+              (TBD)
+            </div>
+
+            <div id="passport-facebook" class="tab-pane" role="tabpanel">
+              (TBD)
+            </div>
 
-            </fieldset>
-            </form>
-          </div>
+            <div id="passport-twitter" class="tab-pane" role="tabpanel">
+              (TBD)
+            </div>
+
+            <div id="passport-github" class="tab-pane" role="tabpanel">
+              (TBD)
+            </div>
+
+          </div><!-- /.tab-content -->
 
         </div><!-- /.modal-body -->
 
       </div><!-- /.modal-content -->
     </div><!-- /.modal-dialog -->
+
+    <script>
+      function testAssociateLdap() {
+        function showMessage(formId, msg, status) {
+          $('#' + formId + ' > .alert').remove();
+
+          var $message = $('<p class="alert"></p>');
+          $message.addClass('alert-' + status);
+          $message.html(msg.replace('\n', '<br>'));
+          $message.insertBefore('#' + formId);
+
+          if (status == 'success') {
+            setTimeout(function()
+            {
+              $message.fadeOut({
+                complete: function() {
+                  $message.remove();
+                }
+              });
+            }, 5000);
+          }
+        }
+
+        var $form = $('#formLdapAssociation');
+        var $action = '/_api/me/external-accounts/testAssociateLdap';
+        var $id = $form.attr('id');
+        var $button = $('button', this);
+        $button.attr('disabled', 'disabled');
+
+        var jqxhr = $.post($action, $form.serialize(), function(data)
+          {
+            if (!data.status) {
+              showMessage($id, 'data.status not found', 'danger');
+            }
+            else {
+              showMessage($id, data.message, data.status);
+            }
+          })
+          .fail(function() {
+            showMessage($id, 'エラーが発生しました', 'danger');
+          })
+          .always(function() {
+            $button.prop('disabled', false);
+          });
+          return false;
+      }
+    </script>
+
   </div><!-- /.modal -->
 
 </div>