unify totp check
the totp check is done in several places causing errors like 3552232e99
* ldap (addon)
* accesscontrol (dashboard)
* proxyauth
* directoryserver (exposed ldap)
* externalldap (the connector)
The code also makes externalldap auto-create work now across all the cases where there is a username
This commit is contained in:
+25
-52
@@ -2,7 +2,6 @@
|
||||
|
||||
exports = module.exports = {
|
||||
verifyPassword,
|
||||
verifyPasswordAndTotpToken,
|
||||
maybeCreateUser,
|
||||
|
||||
testConfig,
|
||||
@@ -251,59 +250,33 @@ async function maybeCreateUser(identifier) {
|
||||
const user = translateUser(externalLdapConfig, ldapUsers[0]);
|
||||
if (!validUserRequirements(user)) throw new BoxError(BoxError.BAD_FIELD);
|
||||
|
||||
const [error, userId] = await safe(users.add(user.email, { username: user.username, password: null, displayName: user.displayName, source: 'ldap' }, AuditSource.EXTERNAL_LDAP_AUTO_CREATE));
|
||||
if (error) {
|
||||
debug(`maybeCreateUser: failed to auto create user ${user.username}`, error);
|
||||
throw error;
|
||||
return await users.add(user.email, { username: user.username, password: null, displayName: user.displayName, source: 'ldap' }, AuditSource.EXTERNAL_LDAP_AUTO_CREATE);
|
||||
}
|
||||
|
||||
async function verifyPassword(user, password, totpToken) {
|
||||
assert.strictEqual(typeof user, 'object');
|
||||
assert.strictEqual(typeof password, 'string');
|
||||
assert(totpToken === null || typeof totpToken === 'string');
|
||||
|
||||
const externalLdapConfig = await settings.getExternalLdapConfig();
|
||||
if (externalLdapConfig.provider === 'noop') throw new BoxError(BoxError.BAD_STATE, 'not enabled');
|
||||
|
||||
const ldapUsers = await ldapUserSearch(externalLdapConfig, { filter: `${externalLdapConfig.usernameField}=${user.username}` });
|
||||
if (ldapUsers.length === 0) throw new BoxError(BoxError.NOT_FOUND);
|
||||
if (ldapUsers.length > 1) throw new BoxError(BoxError.CONFLICT);
|
||||
|
||||
const client = await getClient(externalLdapConfig, { bind: false });
|
||||
|
||||
let userAuthDn;
|
||||
if (totpToken) {
|
||||
// inject totptoken into first attribute
|
||||
const rdns = ldapUsers[0].dn.split(',');
|
||||
userAuthDn = `${rdns[0]}+totptoken=${totpToken},` + rdns.slice(1).join(',');
|
||||
} else {
|
||||
userAuthDn = ldapUsers[0].dn;
|
||||
}
|
||||
|
||||
// fetch the full record and amend potential twoFA settings
|
||||
const newUser = await users.get(userId);
|
||||
if (user.twoFactorAuthenticationEnabled) newUser.twoFactorAuthenticationEnabled = true;
|
||||
|
||||
return newUser;
|
||||
}
|
||||
|
||||
async function verifyPassword(user, password) {
|
||||
assert.strictEqual(typeof user, 'object');
|
||||
assert.strictEqual(typeof password, 'string');
|
||||
|
||||
const externalLdapConfig = await settings.getExternalLdapConfig();
|
||||
if (externalLdapConfig.provider === 'noop') throw new BoxError(BoxError.BAD_STATE, 'not enabled');
|
||||
|
||||
const ldapUsers = await ldapUserSearch(externalLdapConfig, { filter: `${externalLdapConfig.usernameField}=${user.username}` });
|
||||
if (ldapUsers.length === 0) throw new BoxError(BoxError.NOT_FOUND);
|
||||
if (ldapUsers.length > 1) throw new BoxError(BoxError.CONFLICT);
|
||||
|
||||
const client = await getClient(externalLdapConfig, { bind: false });
|
||||
|
||||
const [error] = await safe(util.promisify(client.bind.bind(client))(ldapUsers[0].dn, password));
|
||||
client.unbind();
|
||||
if (error instanceof ldap.InvalidCredentialsError) throw new BoxError(BoxError.INVALID_CREDENTIALS);
|
||||
if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, error);
|
||||
|
||||
return translateUser(externalLdapConfig, ldapUsers[0]);
|
||||
}
|
||||
|
||||
async function verifyPasswordAndTotpToken(user, password, totpToken) {
|
||||
assert.strictEqual(typeof user, 'object');
|
||||
assert.strictEqual(typeof password, 'string');
|
||||
assert.strictEqual(typeof totpToken, 'string');
|
||||
|
||||
const externalLdapConfig = await settings.getExternalLdapConfig();
|
||||
if (externalLdapConfig.provider === 'noop') throw new BoxError(BoxError.BAD_STATE, 'not enabled');
|
||||
|
||||
const ldapUsers = await ldapUserSearch(externalLdapConfig, { filter: `${externalLdapConfig.usernameField}=${user.username}` });
|
||||
if (ldapUsers.length === 0) throw new BoxError(BoxError.NOT_FOUND);
|
||||
if (ldapUsers.length > 1) throw new BoxError(BoxError.CONFLICT);
|
||||
|
||||
const client = await getClient(externalLdapConfig, { bind: false });
|
||||
|
||||
// inject totptoken into first attribute
|
||||
const rdns = ldapUsers[0].dn.split(',');
|
||||
const totpTokenDn = `${rdns[0]}+totptoken=${totpToken},` + rdns.slice(1).join(',');
|
||||
|
||||
const [error] = await safe(util.promisify(client.bind.bind(client))(totpTokenDn, password));
|
||||
const [error] = await safe(util.promisify(client.bind.bind(client))(userAuthDn, password));
|
||||
client.unbind();
|
||||
if (error instanceof ldap.InvalidCredentialsError) throw new BoxError(BoxError.INVALID_CREDENTIALS);
|
||||
if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, error);
|
||||
|
||||
Reference in New Issue
Block a user