Add LDAP auth module (#6226)
This commit is contained in:
committed by
Diamond Lewis
parent
cf26434b31
commit
4435154cf9
@@ -23,6 +23,7 @@ const weibo = require('./weibo');
|
||||
const oauth2 = require('./oauth2');
|
||||
const phantauth = require('./phantauth');
|
||||
const microsoft = require('./microsoft');
|
||||
const ldap = require('./ldap');
|
||||
|
||||
const anonymous = {
|
||||
validateAuthData: () => {
|
||||
@@ -57,6 +58,7 @@ const providers = {
|
||||
weibo,
|
||||
phantauth,
|
||||
microsoft,
|
||||
ldap,
|
||||
};
|
||||
|
||||
function authDataValidator(adapter, appIds, options) {
|
||||
|
||||
113
src/Adapters/Auth/ldap.js
Normal file
113
src/Adapters/Auth/ldap.js
Normal file
@@ -0,0 +1,113 @@
|
||||
const ldapjs = require('ldapjs');
|
||||
const Parse = require('parse/node').Parse;
|
||||
|
||||
function validateAuthData(authData, options) {
|
||||
if (!optionsAreValid(options)) {
|
||||
return new Promise((_, reject) => {
|
||||
reject(
|
||||
new Parse.Error(
|
||||
Parse.Error.INTERNAL_SERVER_ERROR,
|
||||
'LDAP auth configuration missing'
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const client = ldapjs.createClient({ url: options.url });
|
||||
const userCn =
|
||||
typeof options.dn === 'string'
|
||||
? options.dn.replace('{{id}}', authData.id)
|
||||
: `uid=${authData.id},${options.suffix}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
client.bind(userCn, authData.password, err => {
|
||||
if (err) {
|
||||
client.destroy(err);
|
||||
return reject(
|
||||
new Parse.Error(
|
||||
Parse.Error.OBJECT_NOT_FOUND,
|
||||
'LDAP: Wrong username or password'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
typeof options.groupCn === 'string' &&
|
||||
typeof options.groupFilter === 'string'
|
||||
) {
|
||||
searchForGroup(client, options, authData.id, resolve, reject);
|
||||
} else {
|
||||
client.unbind();
|
||||
client.destroy();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function optionsAreValid(options) {
|
||||
return (
|
||||
typeof options === 'object' &&
|
||||
typeof options.suffix === 'string' &&
|
||||
typeof options.url === 'string' &&
|
||||
options.url.startsWith('ldap://')
|
||||
);
|
||||
}
|
||||
|
||||
function searchForGroup(client, options, id, resolve, reject) {
|
||||
const filter = options.groupFilter.replace(/{{id}}/gi, id);
|
||||
const opts = {
|
||||
scope: 'sub',
|
||||
filter: filter,
|
||||
};
|
||||
let found = false;
|
||||
client.search(options.suffix, opts, (searchError, res) => {
|
||||
if (searchError) {
|
||||
client.unbind();
|
||||
client.destroy();
|
||||
return reject(
|
||||
new Parse.Error(
|
||||
Parse.Error.INTERNAL_SERVER_ERROR,
|
||||
'LDAP group search failed'
|
||||
)
|
||||
);
|
||||
}
|
||||
res.on('searchEntry', entry => {
|
||||
if (entry.object.cn === options.groupCn) {
|
||||
found = true;
|
||||
client.unbind();
|
||||
client.destroy();
|
||||
return resolve();
|
||||
}
|
||||
});
|
||||
res.on('end', () => {
|
||||
if (!found) {
|
||||
client.unbind();
|
||||
client.destroy();
|
||||
return reject(
|
||||
new Parse.Error(
|
||||
Parse.Error.INTERNAL_SERVER_ERROR,
|
||||
'LDAP: User not in group'
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
res.on('error', () => {
|
||||
return reject(
|
||||
new Parse.Error(
|
||||
Parse.Error.INTERNAL_SERVER_ERROR,
|
||||
'LDAP group search failed'
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function validateAppId() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validateAppId,
|
||||
validateAuthData,
|
||||
};
|
||||
Reference in New Issue
Block a user