fix(core): Do not applying auth if UM is disabled (#3218)

* 🔓 not applying auth if UM is disabled

* 🛠 add helpers for UM enabled/disabled

* 👕 fix lint issue

* 🔥 remove unused imports
This commit is contained in:
Ben Hesseldieck 2022-05-02 12:11:46 +02:00 committed by GitHub
parent ea4a8b88c9
commit 4ceac38e03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 32 deletions

View file

@ -35,15 +35,12 @@ import { readFile } from 'fs/promises';
import _, { cloneDeep } from 'lodash'; import _, { cloneDeep } from 'lodash';
import { dirname as pathDirname, join as pathJoin, resolve as pathResolve } from 'path'; import { dirname as pathDirname, join as pathJoin, resolve as pathResolve } from 'path';
import { import {
FindConditions,
FindManyOptions, FindManyOptions,
getConnection, getConnection,
getConnectionManager, getConnectionManager,
In, In,
IsNull, IsNull,
LessThan,
LessThanOrEqual, LessThanOrEqual,
MoreThan,
Not, Not,
Raw, Raw,
} from 'typeorm'; } from 'typeorm';
@ -61,13 +58,7 @@ import { createHmac } from 'crypto';
// tested with all possible systems like Windows, Alpine on ARM, FreeBSD, ... // tested with all possible systems like Windows, Alpine on ARM, FreeBSD, ...
import { compare } from 'bcryptjs'; import { compare } from 'bcryptjs';
import { import { BinaryDataManager, Credentials, LoadNodeParameterOptions, UserSettings } from 'n8n-core';
BinaryDataManager,
Credentials,
IBinaryDataConfig,
LoadNodeParameterOptions,
UserSettings,
} from 'n8n-core';
import { import {
ICredentialType, ICredentialType,
@ -154,14 +145,11 @@ import { WEBHOOK_METHODS } from './WebhookHelpers';
import { userManagementRouter } from './UserManagement'; import { userManagementRouter } from './UserManagement';
import { resolveJwt } from './UserManagement/auth/jwt'; import { resolveJwt } from './UserManagement/auth/jwt';
import { User } from './databases/entities/User'; import { User } from './databases/entities/User';
import { CredentialsEntity } from './databases/entities/CredentialsEntity';
import type { import type {
CredentialRequest,
ExecutionRequest, ExecutionRequest,
WorkflowRequest, WorkflowRequest,
NodeParameterOptionsRequest, NodeParameterOptionsRequest,
OAuthRequest, OAuthRequest,
AuthenticatedRequest,
TagsRequest, TagsRequest,
} from './requests'; } from './requests';
import { DEFAULT_EXECUTIONS_GET_ALL_LIMIT, validateEntity } from './GenericHelpers'; import { DEFAULT_EXECUTIONS_GET_ALL_LIMIT, validateEntity } from './GenericHelpers';
@ -169,7 +157,11 @@ import { ExecutionEntity } from './databases/entities/ExecutionEntity';
import { SharedWorkflow } from './databases/entities/SharedWorkflow'; import { SharedWorkflow } from './databases/entities/SharedWorkflow';
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants'; import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants';
import { credentialsController } from './api/credentials.api'; import { credentialsController } from './api/credentials.api';
import { getInstanceBaseUrl, isEmailSetUp } from './UserManagement/UserManagementHelper'; import {
getInstanceBaseUrl,
isEmailSetUp,
isUserManagementEnabled,
} from './UserManagement/UserManagementHelper';
require('body-parser-xml')(bodyParser); require('body-parser-xml')(bodyParser);
@ -311,9 +303,7 @@ class App {
config.getEnv('personalization.enabled') && config.getEnv('diagnostics.enabled'), config.getEnv('personalization.enabled') && config.getEnv('diagnostics.enabled'),
defaultLocale: config.getEnv('defaultLocale'), defaultLocale: config.getEnv('defaultLocale'),
userManagement: { userManagement: {
enabled: enabled: isUserManagementEnabled(),
config.getEnv('userManagement.disabled') === false ||
config.getEnv('userManagement.isInstanceOwnerSetUp') === true,
showSetupOnFirstLoad: showSetupOnFirstLoad:
config.getEnv('userManagement.disabled') === false && config.getEnv('userManagement.disabled') === false &&
config.getEnv('userManagement.isInstanceOwnerSetUp') === false && config.getEnv('userManagement.isInstanceOwnerSetUp') === false &&
@ -346,9 +336,7 @@ class App {
getSettingsForFrontend(): IN8nUISettings { getSettingsForFrontend(): IN8nUISettings {
// refresh user management status // refresh user management status
Object.assign(this.frontendSettings.userManagement, { Object.assign(this.frontendSettings.userManagement, {
enabled: enabled: isUserManagementEnabled(),
config.getEnv('userManagement.disabled') === false ||
config.getEnv('userManagement.isInstanceOwnerSetUp') === true,
showSetupOnFirstLoad: showSetupOnFirstLoad:
config.getEnv('userManagement.disabled') === false && config.getEnv('userManagement.disabled') === false &&
config.getEnv('userManagement.isInstanceOwnerSetUp') === false && config.getEnv('userManagement.isInstanceOwnerSetUp') === false &&
@ -567,12 +555,14 @@ class App {
return; return;
} }
try { if (isUserManagementEnabled()) {
const authCookie = req.cookies?.[AUTH_COOKIE_NAME] ?? ''; try {
await resolveJwt(authCookie); const authCookie = req.cookies?.[AUTH_COOKIE_NAME] ?? '';
} catch (error) { await resolveJwt(authCookie);
res.status(401).send('Unauthorized'); } catch (error) {
return; res.status(401).send('Unauthorized');
return;
}
} }
this.push.add(req.query.sessionId as string, req, res); this.push.add(req.query.sessionId as string, req, res);
@ -3041,9 +3031,7 @@ export async function start(): Promise<void> {
}, },
deploymentType: config.getEnv('deployment.type'), deploymentType: config.getEnv('deployment.type'),
binaryDataMode: binarDataConfig.mode, binaryDataMode: binarDataConfig.mode,
n8n_multi_user_allowed: n8n_multi_user_allowed: isUserManagementEnabled(),
config.getEnv('userManagement.disabled') === false ||
config.getEnv('userManagement.isInstanceOwnerSetUp') === true,
smtp_set_up: config.getEnv('userManagement.emails.mode') === 'smtp', smtp_set_up: config.getEnv('userManagement.emails.mode') === 'smtp',
}; };

View file

@ -32,6 +32,20 @@ export function isEmailSetUp(): boolean {
return smtp && host && user && pass; return smtp && host && user && pass;
} }
export function isUserManagementEnabled(): boolean {
return (
!config.getEnv('userManagement.disabled') ||
config.getEnv('userManagement.isInstanceOwnerSetUp')
);
}
export function isUserManagementDisabled(): boolean {
return (
config.getEnv('userManagement.disabled') &&
!config.getEnv('userManagement.isInstanceOwnerSetUp')
);
}
async function getInstanceOwnerRole(): Promise<Role> { async function getInstanceOwnerRole(): Promise<Role> {
const ownerRole = await Db.collections.Role.findOneOrFail({ const ownerRole = await Db.collections.Role.findOneOrFail({
where: { where: {

View file

@ -19,7 +19,13 @@ import { usersNamespace } from './users';
import { passwordResetNamespace } from './passwordReset'; import { passwordResetNamespace } from './passwordReset';
import { AuthenticatedRequest } from '../../requests'; import { AuthenticatedRequest } from '../../requests';
import { ownerNamespace } from './owner'; import { ownerNamespace } from './owner';
import { isAuthExcluded, isPostUsersId, isAuthenticatedRequest } from '../UserManagementHelper'; import {
isAuthExcluded,
isPostUsersId,
isAuthenticatedRequest,
isUserManagementDisabled,
} from '../UserManagementHelper';
import { Db } from '../..';
export function addRoutes(this: N8nApp, ignoredEndpoints: string[], restEndpoint: string): void { export function addRoutes(this: N8nApp, ignoredEndpoints: string[], restEndpoint: string): void {
// needed for testing; not adding overhead since it directly returns if req.cookies exists // needed for testing; not adding overhead since it directly returns if req.cookies exists
@ -47,7 +53,7 @@ export function addRoutes(this: N8nApp, ignoredEndpoints: string[], restEndpoint
this.app.use(passport.initialize()); this.app.use(passport.initialize());
this.app.use((req: Request, res: Response, next: NextFunction) => { this.app.use(async (req: Request, res: Response, next: NextFunction) => {
if ( if (
// TODO: refactor me!!! // TODO: refactor me!!!
// skip authentication for preflight requests // skip authentication for preflight requests
@ -73,6 +79,17 @@ export function addRoutes(this: N8nApp, ignoredEndpoints: string[], restEndpoint
return next(); return next();
} }
// skip authentication if user management is disabled
if (isUserManagementDisabled()) {
req.user = await Db.collections.User.findOneOrFail(
{},
{
relations: ['globalRole'],
},
);
return next();
}
return passport.authenticate('jwt', { session: false })(req, res, next); return passport.authenticate('jwt', { session: false })(req, res, next);
}); });

View file

@ -12,6 +12,7 @@ import {
getInstanceBaseUrl, getInstanceBaseUrl,
hashPassword, hashPassword,
isEmailSetUp, isEmailSetUp,
isUserManagementDisabled,
sanitizeUser, sanitizeUser,
validatePassword, validatePassword,
} from '../UserManagementHelper'; } from '../UserManagementHelper';
@ -55,7 +56,7 @@ export function usersNamespace(this: N8nApp): void {
} }
// TODO: this should be checked in the middleware rather than here // TODO: this should be checked in the middleware rather than here
if (config.getEnv('userManagement.disabled')) { if (isUserManagementDisabled()) {
Logger.debug( Logger.debug(
'Request to send email invite(s) to user(s) failed because user management is disabled', 'Request to send email invite(s) to user(s) failed because user management is disabled',
); );