From afd6fa99a540c030bc891a9d73e22e5174af6043 Mon Sep 17 00:00:00 2001 From: Hugo Carreira Date: Wed, 17 Jul 2024 15:10:17 +0100 Subject: [PATCH] Restricted the selectable user plugins --- src/common/types/user.ts | 3 +++ src/plugin/plugin.constants.ts | 6 ++++++ src/plugin/plugin.controller.ts | 9 ++++++--- src/plugin/plugins/cv.plugin.ts | 5 ++--- src/plugin/plugins/joan.plugin.ts | 3 ++- src/users/dto/create-user.dto.ts | 3 +++ src/users/entities/user.entity.ts | 14 ++++++++++++-- 7 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 src/plugin/plugin.constants.ts diff --git a/src/common/types/user.ts b/src/common/types/user.ts index 679cda5..48fee6d 100644 --- a/src/common/types/user.ts +++ b/src/common/types/user.ts @@ -1,8 +1,11 @@ +import { PluginDisplayNameT } from '../../plugin/plugin.constants'; + export class User { id: number; providerId: string; username: string; name?: string; + plugins?: PluginDisplayNameT[]; created_at: Date; updated_at: Date; } diff --git a/src/plugin/plugin.constants.ts b/src/plugin/plugin.constants.ts new file mode 100644 index 0000000..d7b2c08 --- /dev/null +++ b/src/plugin/plugin.constants.ts @@ -0,0 +1,6 @@ +export enum PluginDisplayName { + JOAN = 'Joan', + CVS = 'CVs', +} + +export type PluginDisplayNameT = keyof typeof PluginDisplayName; \ No newline at end of file diff --git a/src/plugin/plugin.controller.ts b/src/plugin/plugin.controller.ts index 0f3cb83..1a0de62 100644 --- a/src/plugin/plugin.controller.ts +++ b/src/plugin/plugin.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, UseGuards } from '@nestjs/common'; +import { Controller, Get, Request, UseGuards } from '@nestjs/common'; import { GoogleTokenGuard } from 'src/auth/guards/google-token.guard'; import { PluginService } from './plugin.service'; @@ -8,7 +8,10 @@ export class PluginController { constructor(private readonly pluginService: PluginService) {} @Get() - listPlugins() { - return this.pluginService.availablePlugins; + listPlugins(@Request() req) { + const { plugins = [] } = req.user; + return this.pluginService.availablePlugins.filter((plugin) => { + return plugins.length > 0 && plugins.includes(plugin.displayName); + }); } } diff --git a/src/plugin/plugins/cv.plugin.ts b/src/plugin/plugins/cv.plugin.ts index b2d1f97..bc38d94 100644 --- a/src/plugin/plugins/cv.plugin.ts +++ b/src/plugin/plugins/cv.plugin.ts @@ -1,12 +1,11 @@ -import axios, { AxiosInstance } from 'axios'; -import moment from 'moment-timezone'; import { ConfigService } from '../types'; import { Definition } from '../definition.decorator'; import { Plugin } from '../plugin.decorator'; import { Logger } from '@nestjs/common'; import { CognitiveSearchService } from '../../cognitive-search/cognitive-search.service'; +import { PluginDisplayName } from '../plugin.constants'; -@Plugin({ displayName: 'CVs' }) +@Plugin({ displayName: PluginDisplayName.CVS }) export class CVsPlugin { private readonly logger = new Logger(CVsPlugin.name); diff --git a/src/plugin/plugins/joan.plugin.ts b/src/plugin/plugins/joan.plugin.ts index bac0620..6d60897 100644 --- a/src/plugin/plugins/joan.plugin.ts +++ b/src/plugin/plugins/joan.plugin.ts @@ -4,6 +4,7 @@ import { ConfigService } from '../types'; import { Definition } from '../definition.decorator'; import { Plugin } from '../plugin.decorator'; import { Logger } from '@nestjs/common'; +import { PluginDisplayName } from '../plugin.constants'; interface Desk { id: string; @@ -19,7 +20,7 @@ interface ParkingSpotOptions { timeslot?: string; } -@Plugin({ displayName: 'Joan' }) +@Plugin({ displayName: PluginDisplayName.JOAN }) export class JoanPlugin { private axiosInstance: AxiosInstance; private token: string | null = null; diff --git a/src/users/dto/create-user.dto.ts b/src/users/dto/create-user.dto.ts index ddf9da6..fd4afff 100644 --- a/src/users/dto/create-user.dto.ts +++ b/src/users/dto/create-user.dto.ts @@ -1,3 +1,5 @@ +import { PluginDisplayNameT } from '../../plugin/plugin.constants'; + export class CreateUserDto { providerId: string; username: string; @@ -5,4 +7,5 @@ export class CreateUserDto { refresh_token: string; name?: string; is_active?: boolean; + plugins?: PluginDisplayNameT[]; } diff --git a/src/users/entities/user.entity.ts b/src/users/entities/user.entity.ts index bbd05b6..03ff566 100644 --- a/src/users/entities/user.entity.ts +++ b/src/users/entities/user.entity.ts @@ -8,6 +8,7 @@ import { import { IsEmail } from 'class-validator'; import { Thread } from '../../thread/entities/thread.entity'; import { Feedback } from '../../message/feedback/entities/feedback.entity'; +import { PluginDisplayNameT } from '../../plugin/plugin.constants'; @Entity() @Unique('UQ_USERNAME_PROVIDER', ['username', 'providerId']) @@ -46,6 +47,14 @@ export class User { @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) createdAt: Date; + // Whitelist of the plugins' names the user is permitted to access + @Column({ + type: 'varchar', + array: true, + nullable: true, + }) + plugins: PluginDisplayNameT[]; + constructor( providerId: string, username: string, @@ -59,8 +68,8 @@ export class User { } toJSON(): UserDTO { - const { id, username, providerId } = this; - return { id, username, providerId }; + const { id, username, providerId, plugins } = this; + return { id, username, providerId, plugins }; } } @@ -68,4 +77,5 @@ interface UserDTO { id: number; username: string; providerId: string; + plugins: PluginDisplayNameT[]; }