mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
refactor(core): Decouple LDAP from internal hooks (no-changelog) (#10157)
Co-authored-by: Ricardo Espinoza <ricardo@n8n.io>
This commit is contained in:
parent
30784fb76c
commit
dea212659a
|
@ -618,40 +618,6 @@ export class InternalHooks {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async onLdapSyncFinished(data: {
|
|
||||||
type: string;
|
|
||||||
succeeded: boolean;
|
|
||||||
users_synced: number;
|
|
||||||
error: string;
|
|
||||||
}): Promise<void> {
|
|
||||||
return await this.telemetry.track('Ldap general sync finished', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
async onUserUpdatedLdapSettings(data: {
|
|
||||||
user_id: string;
|
|
||||||
loginIdAttribute: string;
|
|
||||||
firstNameAttribute: string;
|
|
||||||
lastNameAttribute: string;
|
|
||||||
emailAttribute: string;
|
|
||||||
ldapIdAttribute: string;
|
|
||||||
searchPageSize: number;
|
|
||||||
searchTimeout: number;
|
|
||||||
synchronizationEnabled: boolean;
|
|
||||||
synchronizationInterval: number;
|
|
||||||
loginLabel: string;
|
|
||||||
loginEnabled: boolean;
|
|
||||||
}): Promise<void> {
|
|
||||||
return await this.telemetry.track('Ldap general sync finished', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
async onLdapLoginSyncFailed(data: { error: string }): Promise<void> {
|
|
||||||
return await this.telemetry.track('Ldap login sync failed', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
async userLoginFailedDueToLdapDisabled(data: { user_id: string }): Promise<void> {
|
|
||||||
return await this.telemetry.track('User login failed since ldap disabled', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execution Statistics
|
* Execution Statistics
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
import { Get, Post, Put, RestController, GlobalScope } from '@/decorators';
|
import { Get, Post, Put, RestController, GlobalScope } from '@/decorators';
|
||||||
import { InternalHooks } from '@/InternalHooks';
|
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
|
|
||||||
import { NON_SENSIBLE_LDAP_CONFIG_PROPERTIES } from './constants';
|
import { NON_SENSIBLE_LDAP_CONFIG_PROPERTIES } from './constants';
|
||||||
import { getLdapSynchronizations } from './helpers.ee';
|
import { getLdapSynchronizations } from './helpers.ee';
|
||||||
import { LdapConfiguration } from './types';
|
import { LdapConfiguration } from './types';
|
||||||
import { LdapService } from './ldap.service.ee';
|
import { LdapService } from './ldap.service.ee';
|
||||||
|
import { EventService } from '@/eventbus/event.service';
|
||||||
|
|
||||||
@RestController('/ldap')
|
@RestController('/ldap')
|
||||||
export class LdapController {
|
export class LdapController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly internalHooks: InternalHooks,
|
|
||||||
private readonly ldapService: LdapService,
|
private readonly ldapService: LdapService,
|
||||||
|
private readonly eventService: EventService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get('/config')
|
@Get('/config')
|
||||||
|
@ -42,8 +42,8 @@ export class LdapController {
|
||||||
|
|
||||||
const data = await this.ldapService.loadConfig();
|
const data = await this.ldapService.loadConfig();
|
||||||
|
|
||||||
void this.internalHooks.onUserUpdatedLdapSettings({
|
this.eventService.emit('ldap-settings-updated', {
|
||||||
user_id: req.user.id,
|
userId: req.user.id,
|
||||||
...pick(data, NON_SENSIBLE_LDAP_CONFIG_PROPERTIES),
|
...pick(data, NON_SENSIBLE_LDAP_CONFIG_PROPERTIES),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import config from '@/config';
|
||||||
import type { User } from '@db/entities/User';
|
import type { User } from '@db/entities/User';
|
||||||
import type { RunningMode, SyncStatus } from '@db/entities/AuthProviderSyncHistory';
|
import type { RunningMode, SyncStatus } from '@db/entities/AuthProviderSyncHistory';
|
||||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||||
import { InternalHooks } from '@/InternalHooks';
|
|
||||||
import { Logger } from '@/Logger';
|
import { Logger } from '@/Logger';
|
||||||
|
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
|
@ -45,6 +44,7 @@ import {
|
||||||
LDAP_LOGIN_ENABLED,
|
LDAP_LOGIN_ENABLED,
|
||||||
LDAP_LOGIN_LABEL,
|
LDAP_LOGIN_LABEL,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
import { EventService } from '@/eventbus/event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class LdapService {
|
export class LdapService {
|
||||||
|
@ -56,9 +56,9 @@ export class LdapService {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly logger: Logger,
|
private readonly logger: Logger,
|
||||||
private readonly internalHooks: InternalHooks,
|
|
||||||
private readonly settingsRepository: SettingsRepository,
|
private readonly settingsRepository: SettingsRepository,
|
||||||
private readonly cipher: Cipher,
|
private readonly cipher: Cipher,
|
||||||
|
private readonly eventService: EventService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
|
@ -257,9 +257,7 @@ export class LdapService {
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
void this.internalHooks.onLdapLoginSyncFailed({
|
this.eventService.emit('ldap-login-sync-failed', { error: e.message });
|
||||||
error: e.message,
|
|
||||||
});
|
|
||||||
this.logger.error('LDAP - Error during search', { message: e.message });
|
this.logger.error('LDAP - Error during search', { message: e.message });
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -383,10 +381,10 @@ export class LdapService {
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
void this.internalHooks.onLdapSyncFinished({
|
this.eventService.emit('ldap-general-sync-finished', {
|
||||||
type: !this.syncTimer ? 'scheduled' : `manual_${mode}`,
|
type: !this.syncTimer ? 'scheduled' : `manual_${mode}`,
|
||||||
succeeded: true,
|
succeeded: true,
|
||||||
users_synced: usersToCreate.length + usersToUpdate.length + usersToDisable.length,
|
usersSynced: usersToCreate.length + usersToUpdate.length + usersToDisable.length,
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import type { User } from '@db/entities/User';
|
import type { User } from '@db/entities/User';
|
||||||
import { PasswordUtility } from '@/services/password.utility';
|
import { PasswordUtility } from '@/services/password.utility';
|
||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
import { InternalHooks } from '@/InternalHooks';
|
|
||||||
import { isLdapLoginEnabled } from '@/Ldap/helpers.ee';
|
import { isLdapLoginEnabled } from '@/Ldap/helpers.ee';
|
||||||
import { UserRepository } from '@db/repositories/user.repository';
|
import { UserRepository } from '@db/repositories/user.repository';
|
||||||
import { AuthError } from '@/errors/response-errors/auth.error';
|
import { AuthError } from '@/errors/response-errors/auth.error';
|
||||||
|
import { EventService } from '@/eventbus/event.service';
|
||||||
|
|
||||||
export const handleEmailLogin = async (
|
export const handleEmailLogin = async (
|
||||||
email: string,
|
email: string,
|
||||||
|
@ -23,9 +23,7 @@ export const handleEmailLogin = async (
|
||||||
// so suggest to reset the password to gain access to the instance.
|
// so suggest to reset the password to gain access to the instance.
|
||||||
const ldapIdentity = user?.authIdentities?.find((i) => i.providerType === 'ldap');
|
const ldapIdentity = user?.authIdentities?.find((i) => i.providerType === 'ldap');
|
||||||
if (user && ldapIdentity && !isLdapLoginEnabled()) {
|
if (user && ldapIdentity && !isLdapLoginEnabled()) {
|
||||||
void Container.get(InternalHooks).userLoginFailedDueToLdapDisabled({
|
Container.get(EventService).emit('login-failed-due-to-ldap-disabled', { userId: user.id });
|
||||||
user_id: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
throw new AuthError('Reset your password to gain access to the instance.');
|
throw new AuthError('Reset your password to gain access to the instance.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,6 +266,36 @@ export type Event = {
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
'ldap-general-sync-finished': {
|
||||||
|
type: string;
|
||||||
|
succeeded: boolean;
|
||||||
|
usersSynced: number;
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
'ldap-settings-updated': {
|
||||||
|
userId: string;
|
||||||
|
loginIdAttribute: string;
|
||||||
|
firstNameAttribute: string;
|
||||||
|
lastNameAttribute: string;
|
||||||
|
emailAttribute: string;
|
||||||
|
ldapIdAttribute: string;
|
||||||
|
searchPageSize: number;
|
||||||
|
searchTimeout: number;
|
||||||
|
synchronizationEnabled: boolean;
|
||||||
|
synchronizationInterval: number;
|
||||||
|
loginLabel: string;
|
||||||
|
loginEnabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
'ldap-login-sync-failed': {
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
'login-failed-due-to-ldap-disabled': {
|
||||||
|
userId: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Events listened to by more than one relay
|
* Events listened to by more than one relay
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -66,6 +66,18 @@ export class TelemetryEventRelay {
|
||||||
this.eventService.on('community-package-deleted', (event) => {
|
this.eventService.on('community-package-deleted', (event) => {
|
||||||
this.communityPackageDeleted(event);
|
this.communityPackageDeleted(event);
|
||||||
});
|
});
|
||||||
|
this.eventService.on('ldap-general-sync-finished', (event) => {
|
||||||
|
this.ldapGeneralSyncFinished(event);
|
||||||
|
});
|
||||||
|
this.eventService.on('ldap-settings-updated', (event) => {
|
||||||
|
this.ldapSettingsUpdated(event);
|
||||||
|
});
|
||||||
|
this.eventService.on('ldap-login-sync-failed', (event) => {
|
||||||
|
this.ldapLoginSyncFailed(event);
|
||||||
|
});
|
||||||
|
this.eventService.on('login-failed-due-to-ldap-disabled', (event) => {
|
||||||
|
this.loginFailedDueToLdapDisabled(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private teamProjectUpdated({ userId, role, members, projectId }: Event['team-project-updated']) {
|
private teamProjectUpdated({ userId, role, members, projectId }: Event['team-project-updated']) {
|
||||||
|
@ -293,4 +305,56 @@ export class TelemetryEventRelay {
|
||||||
package_author_email: packageAuthorEmail,
|
package_author_email: packageAuthorEmail,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ldapGeneralSyncFinished({
|
||||||
|
type,
|
||||||
|
succeeded,
|
||||||
|
usersSynced,
|
||||||
|
error,
|
||||||
|
}: Event['ldap-general-sync-finished']) {
|
||||||
|
void this.telemetry.track('Ldap general sync finished', {
|
||||||
|
type,
|
||||||
|
succeeded,
|
||||||
|
users_synced: usersSynced,
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ldapSettingsUpdated({
|
||||||
|
userId,
|
||||||
|
loginIdAttribute,
|
||||||
|
firstNameAttribute,
|
||||||
|
lastNameAttribute,
|
||||||
|
emailAttribute,
|
||||||
|
ldapIdAttribute,
|
||||||
|
searchPageSize,
|
||||||
|
searchTimeout,
|
||||||
|
synchronizationEnabled,
|
||||||
|
synchronizationInterval,
|
||||||
|
loginLabel,
|
||||||
|
loginEnabled,
|
||||||
|
}: Event['ldap-settings-updated']) {
|
||||||
|
void this.telemetry.track('User updated Ldap settings', {
|
||||||
|
user_id: userId,
|
||||||
|
loginIdAttribute,
|
||||||
|
firstNameAttribute,
|
||||||
|
lastNameAttribute,
|
||||||
|
emailAttribute,
|
||||||
|
ldapIdAttribute,
|
||||||
|
searchPageSize,
|
||||||
|
searchTimeout,
|
||||||
|
synchronizationEnabled,
|
||||||
|
synchronizationInterval,
|
||||||
|
loginLabel,
|
||||||
|
loginEnabled,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ldapLoginSyncFailed({ error }: Event['ldap-login-sync-failed']) {
|
||||||
|
void this.telemetry.track('Ldap login sync failed', { error });
|
||||||
|
}
|
||||||
|
|
||||||
|
private loginFailedDueToLdapDisabled({ userId }: Event['login-failed-due-to-ldap-disabled']) {
|
||||||
|
void this.telemetry.track('User login failed since ldap disabled', { user_ud: userId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue