mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2026-08-29 06:40:37 +02:00
refactor(core): Move more code into @n8n/permissions. Add aditional tests and docs (no-changelog) (#15062)
Co-authored-by: Danny Martini <danny@n8n.io>
This commit is contained in:
co-authored by
Danny Martini
parent
cdcd059248
commit
2bb190349b
@@ -4,6 +4,7 @@ import {
|
||||
ResolvePasswordTokenQueryDto,
|
||||
} from '@n8n/api-types';
|
||||
import { Body, Get, Post, Query, RestController } from '@n8n/decorators';
|
||||
import { hasGlobalScope } from '@n8n/permissions';
|
||||
import { Response } from 'express';
|
||||
import { Logger } from 'n8n-core';
|
||||
|
||||
@@ -62,18 +63,23 @@ export class PasswordResetController {
|
||||
|
||||
// User should just be able to reset password if one is already present
|
||||
const user = await this.userRepository.findNonShellUser(email);
|
||||
if (!user) {
|
||||
this.logger.debug('No user found in the system');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user?.isOwner && !this.license.isWithinUsersLimit()) {
|
||||
if (user.role !== 'global:owner' && !this.license.isWithinUsersLimit()) {
|
||||
this.logger.debug(
|
||||
'Request to send password reset email failed because the user limit was reached',
|
||||
);
|
||||
throw new ForbiddenError(RESPONSE_ERROR_MESSAGES.USERS_QUOTA_REACHED);
|
||||
}
|
||||
|
||||
if (
|
||||
isSamlCurrentAuthenticationMethod() &&
|
||||
!(
|
||||
user?.hasGlobalScope('user:resetPassword') === true ||
|
||||
user?.settings?.allowSSOManualLogin === true
|
||||
user &&
|
||||
(hasGlobalScope(user, 'user:resetPassword') || user.settings?.allowSSOManualLogin === true)
|
||||
)
|
||||
) {
|
||||
this.logger.debug(
|
||||
@@ -84,8 +90,8 @@ export class PasswordResetController {
|
||||
);
|
||||
}
|
||||
|
||||
const ldapIdentity = user?.authIdentities?.find((i) => i.providerType === 'ldap');
|
||||
if (!user?.password || (ldapIdentity && user.disabled)) {
|
||||
const ldapIdentity = user.authIdentities?.find((i) => i.providerType === 'ldap');
|
||||
if (!user.password || (ldapIdentity && user.disabled)) {
|
||||
this.logger.debug(
|
||||
'Request to send password reset email failed because no user was found for the provided email',
|
||||
{ invalidEmail: email },
|
||||
@@ -140,7 +146,7 @@ export class PasswordResetController {
|
||||
const user = await this.authService.resolvePasswordResetToken(token);
|
||||
if (!user) throw new NotFoundError('');
|
||||
|
||||
if (!user?.isOwner && !this.license.isWithinUsersLimit()) {
|
||||
if (user.role !== 'global:owner' && !this.license.isWithinUsersLimit()) {
|
||||
this.logger.debug(
|
||||
'Request to resolve password token failed because the user limit was reached',
|
||||
{ userId: user.id },
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
Param,
|
||||
Query,
|
||||
} from '@n8n/decorators';
|
||||
import { combineScopes } from '@n8n/permissions';
|
||||
import { combineScopes, getRoleScopes, hasGlobalScope } from '@n8n/permissions';
|
||||
import type { Scope } from '@n8n/permissions';
|
||||
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
|
||||
import { In, Not } from '@n8n/typeorm';
|
||||
@@ -30,13 +30,11 @@ import {
|
||||
TeamProjectOverQuotaError,
|
||||
UnlicensedProjectRoleError,
|
||||
} from '@/services/project.service.ee';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
|
||||
@RestController('/projects')
|
||||
export class ProjectController {
|
||||
constructor(
|
||||
private readonly projectsService: ProjectService,
|
||||
private readonly roleService: RoleService,
|
||||
private readonly projectRepository: ProjectRepository,
|
||||
private readonly eventService: EventService,
|
||||
) {}
|
||||
@@ -69,8 +67,8 @@ export class ProjectController {
|
||||
role: 'project:admin',
|
||||
scopes: [
|
||||
...combineScopes({
|
||||
global: this.roleService.getRoleScopes(req.user.role),
|
||||
project: this.roleService.getRoleScopes('project:admin'),
|
||||
global: getRoleScopes(req.user.role),
|
||||
project: getRoleScopes('project:admin'),
|
||||
}),
|
||||
],
|
||||
};
|
||||
@@ -88,7 +86,7 @@ export class ProjectController {
|
||||
_res: Response,
|
||||
): Promise<ProjectRequest.GetMyProjectsResponse> {
|
||||
const relations = await this.projectsService.getProjectRelationsForUser(req.user);
|
||||
const otherTeamProject = req.user.hasGlobalScope('project:read')
|
||||
const otherTeamProject = hasGlobalScope(req.user, 'project:read')
|
||||
? await this.projectRepository.findBy({
|
||||
type: 'team',
|
||||
id: Not(In(relations.map((pr) => pr.projectId))),
|
||||
@@ -106,8 +104,8 @@ export class ProjectController {
|
||||
if (result.scopes) {
|
||||
result.scopes.push(
|
||||
...combineScopes({
|
||||
global: this.roleService.getRoleScopes(req.user.role),
|
||||
project: this.roleService.getRoleScopes(pr.role),
|
||||
global: getRoleScopes(req.user.role),
|
||||
project: getRoleScopes(pr.role),
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -128,9 +126,7 @@ export class ProjectController {
|
||||
);
|
||||
|
||||
if (result.scopes) {
|
||||
result.scopes.push(
|
||||
...combineScopes({ global: this.roleService.getRoleScopes(req.user.role) }),
|
||||
);
|
||||
result.scopes.push(...combineScopes({ global: getRoleScopes(req.user.role) }));
|
||||
}
|
||||
|
||||
results.push(result);
|
||||
@@ -154,8 +150,8 @@ export class ProjectController {
|
||||
}
|
||||
const scopes: Scope[] = [
|
||||
...combineScopes({
|
||||
global: this.roleService.getRoleScopes(req.user.role),
|
||||
project: this.roleService.getRoleScopes('project:personalOwner'),
|
||||
global: getRoleScopes(req.user.role),
|
||||
project: getRoleScopes('project:personalOwner'),
|
||||
}),
|
||||
];
|
||||
return {
|
||||
@@ -191,8 +187,8 @@ export class ProjectController {
|
||||
})),
|
||||
scopes: [
|
||||
...combineScopes({
|
||||
global: this.roleService.getRoleScopes(req.user.role),
|
||||
...(myRelation ? { project: this.roleService.getRoleScopes(myRelation.role) } : {}),
|
||||
global: getRoleScopes(req.user.role),
|
||||
...(myRelation ? { project: getRoleScopes(myRelation.role) } : {}),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,23 +1,13 @@
|
||||
import { Get, RestController } from '@n8n/decorators';
|
||||
|
||||
import { type AllRoleTypes, RoleService } from '@/services/role.service';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
|
||||
@RestController('/roles')
|
||||
export class RoleController {
|
||||
constructor(private readonly roleService: RoleService) {}
|
||||
|
||||
@Get('/')
|
||||
async getAllRoles() {
|
||||
return Object.fromEntries(
|
||||
Object.entries(this.roleService.getRoles()).map((e) => [
|
||||
e[0],
|
||||
(e[1] as AllRoleTypes[]).map((r) => ({
|
||||
name: this.roleService.getRoleName(r),
|
||||
role: r,
|
||||
scopes: this.roleService.getRoleScopes(r),
|
||||
licensed: this.roleService.isRoleLicensed(r),
|
||||
})),
|
||||
]),
|
||||
);
|
||||
getAllRoles() {
|
||||
return this.roleService.getAllRoles();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user