|
|
@@ -66,7 +66,7 @@ module.exports = function(crowi, app) {
|
|
|
* @param {*} res
|
|
|
* @param {*} next
|
|
|
*/
|
|
|
- const loginWithLdap = (req, res, next) => {
|
|
|
+ const loginWithLdap = async(req, res, next) => {
|
|
|
if (!passportService.isLdapStrategySetup) {
|
|
|
debug('LdapStrategy has not been set up');
|
|
|
return next();
|
|
|
@@ -78,77 +78,33 @@ module.exports = function(crowi, app) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- passport.authenticate('ldapauth', (err, ldapAccountInfo, info) => {
|
|
|
- if (res.headersSent) { // dirty hack -- 2017.09.25
|
|
|
- return; // cz: somehow passport.authenticate called twice when ECONNREFUSED error occurred
|
|
|
- }
|
|
|
+ const provider = 'ldap';
|
|
|
+ const ldapAccountInfo = await __promisifiedPassportAuthentication(req, res, next, provider);
|
|
|
|
|
|
- debug('--- authenticate with LdapStrategy ---');
|
|
|
- debug('ldapAccountInfo', ldapAccountInfo);
|
|
|
- debug('info', info);
|
|
|
-
|
|
|
- if (err) { // DB Error
|
|
|
- logger.error('LDAP Server Error: ', err);
|
|
|
- req.flash('warningMessage', 'LDAP Server Error occured.');
|
|
|
- return next(); // pass and the flash message is displayed when all of authentications are failed.
|
|
|
- }
|
|
|
-
|
|
|
- // authentication failure
|
|
|
- if (!ldapAccountInfo) { return next() }
|
|
|
- // check groups
|
|
|
- if (!isValidLdapUserByGroupFilter(ldapAccountInfo)) {
|
|
|
- return loginFailure(req, res, next);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * authentication success
|
|
|
- */
|
|
|
- // it is guaranteed that username that is input from form can be acquired
|
|
|
- // because this processes after authentication
|
|
|
- const ldapAccountId = passportService.getLdapAccountIdFromReq(req);
|
|
|
-
|
|
|
- const attrMapUsername = passportService.getLdapAttrNameMappedToUsername();
|
|
|
- const attrMapName = passportService.getLdapAttrNameMappedToName();
|
|
|
- const usernameToBeRegistered = ldapAccountInfo[attrMapUsername];
|
|
|
- const nameToBeRegistered = ldapAccountInfo[attrMapName];
|
|
|
+ /*
|
|
|
+ * authentication success
|
|
|
+ */
|
|
|
+ // it is guaranteed that username that is input from form can be acquired
|
|
|
+ // because this processes after authentication
|
|
|
+ const ldapAccountId = passportService.getLdapAccountIdFromReq(req);
|
|
|
+ const attrMapUsername = passportService.getLdapAttrNameMappedToUsername();
|
|
|
+ const attrMapName = passportService.getLdapAttrNameMappedToName();
|
|
|
+ const usernameToBeRegistered = ldapAccountInfo[attrMapUsername];
|
|
|
+ const nameToBeRegistered = ldapAccountInfo[attrMapName];
|
|
|
+ const userInfo = {
|
|
|
+ 'id': ldapAccountId,
|
|
|
+ 'username': usernameToBeRegistered,
|
|
|
+ 'name': nameToBeRegistered
|
|
|
+ }
|
|
|
|
|
|
- // find or register(create) user
|
|
|
- ExternalAccount.findOrRegister('ldap', ldapAccountId, usernameToBeRegistered, nameToBeRegistered)
|
|
|
- .catch((err) => {
|
|
|
- if (err.name === 'DuplicatedUsernameException') {
|
|
|
- // get option
|
|
|
- const isSameUsernameTreatedAsIdenticalUser = Config.isSameUsernameTreatedAsIdenticalUser(config, 'ldap');
|
|
|
- if (isSameUsernameTreatedAsIdenticalUser) {
|
|
|
- // associate to existing user
|
|
|
- debug(`ExternalAccount '${ldapAccountId}' will be created and bound to the exisiting User account`);
|
|
|
- return ExternalAccount.associate('ldap', ldapAccountId, err.user);
|
|
|
- }
|
|
|
- }
|
|
|
- throw err; // throw again
|
|
|
- })
|
|
|
- .then((externalAccount) => {
|
|
|
- return externalAccount.getPopulatedUser();
|
|
|
- })
|
|
|
- .then((user) => {
|
|
|
- // login
|
|
|
- req.logIn(user, (err) => {
|
|
|
- if (err) { return next() }
|
|
|
- else {
|
|
|
- return loginSuccess(req, res, user);
|
|
|
- }
|
|
|
- });
|
|
|
- })
|
|
|
- .catch((err) => {
|
|
|
- if (err.name === 'DuplicatedUsernameException') {
|
|
|
- req.flash('provider-DuplicatedUsernameException', 'LDAP');
|
|
|
- return next();
|
|
|
- }
|
|
|
- else {
|
|
|
- return next(err);
|
|
|
- }
|
|
|
- });
|
|
|
+ const externalAccount = await getOrCreateUser(req, next, userInfo, provider);
|
|
|
+ const user = await externalAccount.getPopulatedUser();
|
|
|
|
|
|
- })(req, res, next);
|
|
|
+ // login
|
|
|
+ await req.logIn(user, err => {
|
|
|
+ if (err) { return next(err) };
|
|
|
+ return loginSuccess(req, res, user);
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
@@ -252,7 +208,7 @@ module.exports = function(crowi, app) {
|
|
|
|
|
|
const loginPassportGoogleCallback = async(req, res, next) => {
|
|
|
const provider = 'google';
|
|
|
- const response = await __promisifiedPassportAuthentication(req, res, provider);
|
|
|
+ const response = await __promisifiedPassportAuthentication(req, res, next, provider);
|
|
|
const userInfo = {
|
|
|
'id': response.id,
|
|
|
'username': response.displayName,
|
|
|
@@ -268,17 +224,45 @@ module.exports = function(crowi, app) {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- const __promisifiedPassportAuthentication = (req, res, provider) => {
|
|
|
+ const __promisifiedPassportAuthentication = (req, res, next, provider) => {
|
|
|
+ if(provider === 'ldap'){ provider = 'ldapauth' };
|
|
|
return new Promise((resolve, reject) => {
|
|
|
- passport.authenticate(provider, (err, user, info) => {
|
|
|
- if (err) reject(err);
|
|
|
- if (user) resolve(user);
|
|
|
- })(req, res);
|
|
|
+ passport.authenticate(provider, (err, response, info) => {
|
|
|
+ if (err) {
|
|
|
+ if (provider === 'ldap'){
|
|
|
+ if (res.headersSent) { // dirty hack -- 2017.09.25
|
|
|
+ return; // cz: somehow passport.authenticate called twice when ECONNREFUSED error occurred
|
|
|
+ }
|
|
|
+
|
|
|
+ debug('--- authenticate with LdapStrategy ---');
|
|
|
+ debug('ldapAccountInfo', ldapAccountInfo);
|
|
|
+ debug('info', info);
|
|
|
+
|
|
|
+ if (err) { // DB Error
|
|
|
+ logger.error('LDAP Server Error: ', err);
|
|
|
+ req.flash('warningMessage', 'LDAP Server Error occured.');
|
|
|
+ return next(); // pass and the flash message is displayed when all of authentications are failed.
|
|
|
+ }
|
|
|
+
|
|
|
+ // authentication failure
|
|
|
+ if (!ldapAccountInfo) { return next() }
|
|
|
+ // check groups
|
|
|
+ if (!isValidLdapUserByGroupFilter(ldapAccountInfo)) {
|
|
|
+ return loginFailure(req, res, next);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ reject(err);
|
|
|
+ }
|
|
|
+ if (response) {
|
|
|
+ resolve(response)
|
|
|
+ }
|
|
|
+ })(req, res, next);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
const getOrCreateUser = async(req, next, userInfo, provider) => {
|
|
|
try {
|
|
|
+ // find or register(create) user
|
|
|
const externalAccount = await ExternalAccount.findOrRegister(
|
|
|
provider,
|
|
|
userInfo.id,
|