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

WIP: refactor findOrRegisterUserByLdapInfo

Yuki Takei 8 лет назад
Родитель
Сommit
dc670831d1
3 измененных файлов с 71 добавлено и 32 удалено
  1. 2 1
      config/env.dev.js
  2. 46 1
      lib/models/external-account.js
  3. 23 30
      lib/service/passport.js

+ 2 - 1
config/env.dev.js

@@ -11,13 +11,14 @@ module.exports = {
   // filters for debug
   // filters for debug
   DEBUG: [
   DEBUG: [
     // 'express:*',
     // 'express:*',
+    // 'crowi:*',
     // 'crowi:crowi',
     // 'crowi:crowi',
     'crowi:crowi:dev',
     'crowi:crowi:dev',
     'crowi:crowi:express-init',
     'crowi:crowi:express-init',
+    'crowi:models:external-account',
     // 'crowi:routes:login',
     // 'crowi:routes:login',
     'crowi:routes:login-passport',
     'crowi:routes:login-passport',
     'crowi:service:PassportService',
     'crowi:service:PassportService',
-    // 'crowi:*',
     // 'crowi:routes:page',
     // 'crowi:routes:page',
     // 'crowi:plugins:*',
     // 'crowi:plugins:*',
     // 'crowi:InterceptorManager',
     // 'crowi:InterceptorManager',

+ 46 - 1
lib/models/external-account.js

@@ -1,4 +1,4 @@
-const debug = require('debug')('crowi.models.external-account');
+const debug = require('debug')('crowi:models:external-account');
 const mongoose = require('mongoose');
 const mongoose = require('mongoose');
 const uniqueValidator = require('mongoose-unique-validator');
 const uniqueValidator = require('mongoose-unique-validator');
 const ObjectId = mongoose.Schema.Types.ObjectId;
 const ObjectId = mongoose.Schema.Types.ObjectId;
@@ -23,6 +23,51 @@ schema.plugin(uniqueValidator);
  * @class ExternalAccount
  * @class ExternalAccount
  */
  */
 class ExternalAccount {
 class ExternalAccount {
+
+  /**
+   * get the populated user entity
+   *
+   * @returns Promise<User>
+   * @memberof ExternalAccount
+   */
+  getPopulatedUser() {
+    return this.populate('user').execPopulate()
+      .then((account) => {
+        return account.user;
+      })
+  }
+
+  /**
+   * find an account or register if not found
+   *
+   * @static
+   * @param {string} providerType
+   * @param {string} accountId
+   * @param {object} createUserFunction the function that create a user document and return Promise<User>
+   * @returns {Promise<ExternalAccount>}
+   * @memberof ExternalAccount
+   */
+  static findOrRegister(providerType, accountId, createUserFunction) {
+
+    return this.findOne({ providerType, accountId })
+      .then((account) => {
+        // found
+        if (account != null) {
+          debug(`ExternalAccount '${accountId}' is found `, account);
+          return account;
+        }
+        // not found
+        else {
+          debug(`ExternalAccount '${accountId}' is not found, it is going to be registered.`);
+
+          return createUserFunction().then((user) => {
+              return this.create({ providerType: 'ldap', accountId, user: user._id });
+            });
+        }
+      });
+
+  }
+
 }
 }
 
 
 module.exports = function(crowi) {
 module.exports = function(crowi) {

+ 23 - 30
lib/service/passport.js

@@ -145,12 +145,12 @@ class PassportService {
       if (!req.form.isValid) {
       if (!req.form.isValid) {
         return callback({ message: 'Incorrect credentials.' });
         return callback({ message: 'Incorrect credentials.' });
       }
       }
-      const username = loginForm.username;
+      const ldapAccountId = loginForm.username;
       const password = loginForm.password;
       const password = loginForm.password;
 
 
       // user bind
       // user bind
       if (isUserBind) {
       if (isUserBind) {
-        bindDN = bindDN.replace(/{{username}}/, username);
+        bindDN = bindDN.replace(/{{username}}/, ldapAccountId);
         bindCredentials = password;
         bindCredentials = password;
       }
       }
 
 
@@ -158,7 +158,8 @@ class PassportService {
         const opts = {
         const opts = {
           usernameField: PassportService.USERNAME_FIELD,
           usernameField: PassportService.USERNAME_FIELD,
           passwordField: PassportService.PASSWORD_FIELD,
           passwordField: PassportService.PASSWORD_FIELD,
-          server: { url, bindDN, bindCredentials, searchBase, searchFilter }
+          server: { url, bindDN, bindCredentials, searchBase, searchFilter },
+          passReqToCallback: true,
         };
         };
         debug('ldap configuration: ', opts);
         debug('ldap configuration: ', opts);
         callback(null, opts);
         callback(null, opts);
@@ -166,10 +167,12 @@ class PassportService {
     };
     };
 
 
     passport.use(new LdapStrategy(getLDAPConfiguration,
     passport.use(new LdapStrategy(getLDAPConfiguration,
-      (ldapUserInfo, done) => {
-        debug("LDAP authentication has successed", ldapUserInfo);
+      (req, ldapAccountInfo, done) => {
+        debug("LDAP authentication has successed", ldapAccountInfo);
 
 
-        this.findOrRegisterUserByLdapInfo(ldapUserInfo)
+        const ldapAccountId = req.body.loginForm.username;
+
+        this.findOrRegisterUserByLdapInfo(ldapAccountId, ldapAccountInfo)
           .then((user) => {
           .then((user) => {
             done(null, user);
             done(null, user);
           })
           })
@@ -183,35 +186,25 @@ class PassportService {
     debug('LdapStrategy: setup is done');
     debug('LdapStrategy: setup is done');
   }
   }
 
 
-  findOrRegisterUserByLdapInfo(ldapUserInfo) {
+  /**
+   * find the ExternalAccount or register if not found
+   *
+   * @param {string} ldapAccountId
+   * @param {object} ldapAccountInfo
+   * @returns
+   * @memberof PassportService
+   */
+  findOrRegisterUserByLdapInfo(ldapAccountId, ldapAccountInfo) {
     const User = this.crowi.model('User');
     const User = this.crowi.model('User');
     const ExternalAccount = this.crowi.model('ExternalAccount');
     const ExternalAccount = this.crowi.model('ExternalAccount');
 
 
-    const accountId = ldapUserInfo['uid'];
-
-    return ExternalAccount.findOne({ providerType: 'ldap', accountId: accountId })
-      .then((account) => {
-        if (account != null) {
-          debug(`LdapStrategy: accountId '${accountId}' is found `, account);
-          return account;
-        }
-        else {
-          debug(`LdapStrategy: accountId '${accountId}' is not found, it is going to be registered.`);
-
-          // TODO ensure to be able to select the way to determine username
-          const username = ldapUserInfo['uid'];
-
-          return User.createUser('', username, undefined, undefined, undefined)
-            .then((user) => {
-              return ExternalAccount.create({ providerType: 'ldap', accountId, user: user._id });
-            });
-        }
-      })
-      .then((account) => {
-        return account.populate('user').execPopulate();
+    return ExternalAccount.findOrRegister('ldap', ldapAccountId, () => {
+        // TODO ensure to be able to select the way to determine username
+        const username = ldapAccountInfo['uid'];
+        return User.createUser('', username, undefined, undefined, undefined);
       })
       })
       .then((account) => {
       .then((account) => {
-        return account.user;
+        return account.getPopulatedUser();
       });
       });
   }
   }