admin panel fast follows (#10723)
fast follows: - https://discord.com/channels/1130383047699738754/1346433965451382845 - https://discord.com/channels/1130383047699738754/1346434512757981264 - https://discord.com/channels/1130383047699738754/1346453484911853610 --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
@ -15,12 +15,14 @@ import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filt
|
||||
import { HealthIndicatorId } from 'src/engine/core-modules/health/enums/health-indicator-id.enum';
|
||||
import { WorkerHealthIndicator } from 'src/engine/core-modules/health/indicators/worker.health';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { AdminPanelGuard } from 'src/engine/guards/admin-panel-guard';
|
||||
import { ImpersonateGuard } from 'src/engine/guards/impersonate-guard';
|
||||
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
|
||||
import { AdminPanelHealthServiceData } from './dtos/admin-panel-health-service-data.dto';
|
||||
import { QueueMetricsData } from './dtos/queue-metrics-data.dto';
|
||||
|
||||
@Resolver()
|
||||
@UseFilters(AuthGraphqlApiExceptionFilter)
|
||||
export class AdminPanelResolver {
|
||||
@ -60,19 +62,19 @@ export class AdminPanelResolver {
|
||||
return true;
|
||||
}
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, ImpersonateGuard)
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, AdminPanelGuard)
|
||||
@Query(() => EnvironmentVariablesOutput)
|
||||
async getEnvironmentVariablesGrouped(): Promise<EnvironmentVariablesOutput> {
|
||||
return this.adminService.getEnvironmentVariablesGrouped();
|
||||
}
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, ImpersonateGuard)
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, AdminPanelGuard)
|
||||
@Query(() => SystemHealth)
|
||||
async getSystemHealthStatus(): Promise<SystemHealth> {
|
||||
return this.adminPanelHealthService.getSystemHealthStatus();
|
||||
}
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, ImpersonateGuard)
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, AdminPanelGuard)
|
||||
@Query(() => AdminPanelHealthServiceData)
|
||||
async getIndicatorHealthStatus(
|
||||
@Args('indicatorId', {
|
||||
@ -83,7 +85,7 @@ export class AdminPanelResolver {
|
||||
return this.adminPanelHealthService.getIndicatorHealthStatus(indicatorId);
|
||||
}
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, ImpersonateGuard)
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, AdminPanelGuard)
|
||||
@Query(() => QueueMetricsData)
|
||||
async getQueueMetrics(
|
||||
@Args('queueName', { type: () => String })
|
||||
|
||||
@ -7,7 +7,6 @@ import { AppHealthIndicator } from 'src/engine/core-modules/health/indicators/ap
|
||||
import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module';
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceHealthModule } from 'src/engine/workspace-manager/workspace-health/workspace-health.module';
|
||||
|
||||
import { HealthCacheService } from './health-cache.service';
|
||||
|
||||
@ -19,7 +18,6 @@ import { WorkerHealthIndicator } from './indicators/worker.health';
|
||||
imports: [
|
||||
TerminusModule,
|
||||
RedisClientModule,
|
||||
WorkspaceHealthModule,
|
||||
ObjectMetadataModule,
|
||||
WorkspaceMigrationModule,
|
||||
],
|
||||
|
||||
@ -4,12 +4,10 @@ import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AppHealthIndicator } from 'src/engine/core-modules/health/indicators/app.health';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { WorkspaceHealthService } from 'src/engine/workspace-manager/workspace-health/workspace-health.service';
|
||||
|
||||
describe('AppHealthIndicator', () => {
|
||||
let service: AppHealthIndicator;
|
||||
let objectMetadataService: jest.Mocked<ObjectMetadataService>;
|
||||
let workspaceHealthService: jest.Mocked<WorkspaceHealthService>;
|
||||
let workspaceMigrationService: jest.Mocked<WorkspaceMigrationService>;
|
||||
let healthIndicatorService: jest.Mocked<HealthIndicatorService>;
|
||||
|
||||
@ -18,10 +16,6 @@ describe('AppHealthIndicator', () => {
|
||||
findMany: jest.fn(),
|
||||
} as any;
|
||||
|
||||
workspaceHealthService = {
|
||||
healthCheck: jest.fn(),
|
||||
} as any;
|
||||
|
||||
workspaceMigrationService = {
|
||||
getPendingMigrations: jest.fn(),
|
||||
} as any;
|
||||
@ -44,10 +38,7 @@ describe('AppHealthIndicator', () => {
|
||||
provide: ObjectMetadataService,
|
||||
useValue: objectMetadataService,
|
||||
},
|
||||
{
|
||||
provide: WorkspaceHealthService,
|
||||
useValue: workspaceHealthService,
|
||||
},
|
||||
|
||||
{
|
||||
provide: WorkspaceMigrationService,
|
||||
useValue: workspaceMigrationService,
|
||||
|
||||
@ -7,7 +7,6 @@ import {
|
||||
import { HealthStateManager } from 'src/engine/core-modules/health/utils/health-state-manager.util';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { WorkspaceHealthService } from 'src/engine/workspace-manager/workspace-health/workspace-health.service';
|
||||
|
||||
@Injectable()
|
||||
export class AppHealthIndicator {
|
||||
@ -15,7 +14,6 @@ export class AppHealthIndicator {
|
||||
|
||||
constructor(
|
||||
private readonly healthIndicatorService: HealthIndicatorService,
|
||||
private readonly workspaceHealthService: WorkspaceHealthService,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||
) {}
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
import { ExecutionContext } from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { AdminPanelGuard } from 'src/engine/guards/admin-panel-guard';
|
||||
|
||||
describe('AdminPanelGuard', () => {
|
||||
const guard = new AdminPanelGuard();
|
||||
|
||||
it('should return true if user can access full admin panel', async () => {
|
||||
const mockContext = {
|
||||
getContext: jest.fn(() => ({
|
||||
req: {
|
||||
user: {
|
||||
canAccessFullAdminPanel: true,
|
||||
},
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
jest
|
||||
.spyOn(GqlExecutionContext, 'create')
|
||||
.mockReturnValue(mockContext as any);
|
||||
|
||||
const mockExecutionContext = {} as ExecutionContext;
|
||||
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if user cannot access full admin panel', async () => {
|
||||
const mockContext = {
|
||||
getContext: jest.fn(() => ({
|
||||
req: {
|
||||
user: {
|
||||
canAccessFullAdminPanel: false,
|
||||
},
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
jest
|
||||
.spyOn(GqlExecutionContext, 'create')
|
||||
.mockReturnValue(mockContext as any);
|
||||
|
||||
const mockExecutionContext = {} as ExecutionContext;
|
||||
|
||||
const result = await guard.canActivate(mockExecutionContext);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,15 @@
|
||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export class AdminPanelGuard implements CanActivate {
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const ctx = GqlExecutionContext.create(context);
|
||||
const request = ctx.getContext().req;
|
||||
|
||||
return request.user.canAccessFullAdminPanel === true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user