feat(core): Add LDAP support (#3835)

This commit is contained in:
Ricardo Espinoza
2023-01-24 20:18:39 -05:00
committed by GitHub
parent 259296c5c9
commit 0c70a40317
77 changed files with 3686 additions and 192 deletions

View File

@@ -0,0 +1,32 @@
import * as Db from '@/Db';
import type { User } from '@db/entities/User';
import { compareHash } from '@/UserManagement/UserManagementHelper';
import { InternalHooksManager } from '@/InternalHooksManager';
import * as ResponseHelper from '@/ResponseHelper';
export const handleEmailLogin = async (
email: string,
password: string,
): Promise<User | undefined> => {
const user = await Db.collections.User.findOne({
where: { email },
relations: ['globalRole', 'authIdentities'],
});
if (user?.password && (await compareHash(password, user.password))) {
return user;
}
// At this point if the user has a LDAP ID, means it was previously an LDAP user,
// so suggest to reset the password to gain access to the instance.
const ldapIdentity = user?.authIdentities?.find((i) => i.providerType === 'ldap');
if (user && ldapIdentity) {
void InternalHooksManager.getInstance().userLoginFailedDueToLdapDisabled({
user_id: user.id,
});
throw new ResponseHelper.AuthError('Reset your password to gain access to the instance.');
}
return undefined;
};

View File

@@ -0,0 +1,69 @@
import { InternalHooksManager } from '@/InternalHooksManager';
import {
createLdapUserOnLocalDb,
findAndAuthenticateLdapUser,
getLdapConfig,
getLdapUserRole,
getUserByEmail,
getAuthIdentityByLdapId,
isLdapDisabled,
mapLdapAttributesToUser,
createLdapAuthIdentity,
updateLdapUserOnLocalDb,
} from '@/Ldap/helpers';
import type { User } from '@db/entities/User';
export const handleLdapLogin = async (
loginId: string,
password: string,
): Promise<User | undefined> => {
if (isLdapDisabled()) return undefined;
const ldapConfig = await getLdapConfig();
if (!ldapConfig.loginEnabled) return undefined;
const { loginIdAttribute, userFilter } = ldapConfig;
const ldapUser = await findAndAuthenticateLdapUser(
loginId,
password,
loginIdAttribute,
userFilter,
);
if (!ldapUser) return undefined;
const [ldapId, ldapAttributesValues] = mapLdapAttributesToUser(ldapUser, ldapConfig);
const { email: emailAttributeValue } = ldapAttributesValues;
if (!ldapId || !emailAttributeValue) return undefined;
const ldapAuthIdentity = await getAuthIdentityByLdapId(ldapId);
if (!ldapAuthIdentity) {
const emailUser = await getUserByEmail(emailAttributeValue);
// check if there is an email user with the same email as the authenticated LDAP user trying to log-in
if (emailUser && emailUser.email === emailAttributeValue) {
const identity = await createLdapAuthIdentity(emailUser, ldapId);
await updateLdapUserOnLocalDb(identity, ldapAttributesValues);
} else {
const role = await getLdapUserRole();
const user = await createLdapUserOnLocalDb(role, ldapAttributesValues, ldapId);
void InternalHooksManager.getInstance().onUserSignup(user, {
user_type: 'ldap',
was_disabled_ldap_user: false,
});
return user;
}
} else {
if (ldapAuthIdentity.user) {
if (ldapAuthIdentity.user.disabled) return undefined;
await updateLdapUserOnLocalDb(ldapAuthIdentity, ldapAttributesValues);
}
}
// Retrieve the user again as user's data might have been updated
return (await getAuthIdentityByLdapId(ldapId))?.user;
};