From 6a08cc1c1c2e21710d76f16bbd4029669c95916d Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Fri, 28 May 2021 19:46:22 +0200 Subject: [PATCH] Adding Album Middlewares and routers #45 --- src/backend/middlewares/AlbumMWs.ts | 63 ++++++++++++++++++ src/backend/middlewares/SharingMWs.ts | 1 + src/backend/model/ObjectManagers.ts | 64 ++++++++----------- .../database/interfaces/IAlbumManager.ts | 19 ++++++ .../model/database/memory/AlbumManager.ts | 19 ++++++ .../model/database/sql/AlbumManager.ts | 3 +- src/backend/routes/AlbumRouter.ts | 56 ++++++++++++++++ src/backend/routes/Router.ts | 12 ++-- src/backend/routes/SharingRouter.ts | 2 +- src/common/config/public/ClientConfig.ts | 9 +++ src/common/entities/Error.ts | 2 + 11 files changed, 206 insertions(+), 44 deletions(-) create mode 100644 src/backend/middlewares/AlbumMWs.ts create mode 100644 src/backend/model/database/interfaces/IAlbumManager.ts create mode 100644 src/backend/model/database/memory/AlbumManager.ts create mode 100644 src/backend/routes/AlbumRouter.ts diff --git a/src/backend/middlewares/AlbumMWs.ts b/src/backend/middlewares/AlbumMWs.ts new file mode 100644 index 00000000..de05f97f --- /dev/null +++ b/src/backend/middlewares/AlbumMWs.ts @@ -0,0 +1,63 @@ +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; +import {ObjectManagers} from '../model/ObjectManagers'; +import {Utils} from '../../common/Utils'; +import {Config} from '../../common/config/private/Config'; + + +export class AlbumMWs { + + + public static async listAlbums(req: Request, res: Response, next: NextFunction): Promise { + if (Config.Client.Album.enabled === false) { + return next(); + } + try { + req.resultPipe = await ObjectManagers.getInstance() + .AlbumManager.getAlbums(); + return next(); + + } catch (err) { + return next(new ErrorDTO(ErrorCodes.ALBUM_ERROR, 'Error during listing albums', err)); + } + } + + + public static async deleteAlbum(req: Request, res: Response, next: NextFunction): Promise { + if (Config.Client.Album.enabled === false) { + return next(); + } + if (!req.params.id || !Utils.isUInt32(parseInt(req.params.id, 10))) { + return next(); + } + try { + await ObjectManagers.getInstance().AlbumManager.deleteAlbum(parseInt(req.params.id, 10)); + req.resultPipe = 'ok'; + return next(); + + } catch (err) { + return next(new ErrorDTO(ErrorCodes.ALBUM_ERROR, 'Error during deleting albums', err)); + } + } + + public static async createSavedSearch(req: Request, res: Response, next: NextFunction): Promise { + if (Config.Client.Album.enabled === false) { + return next(); + } + if ((typeof req.body === 'undefined') || (typeof req.body.name !== 'string') || (typeof req.body.searchQuery !== 'object')) { + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'updateSharing filed is missing')); + } + try { + await ObjectManagers.getInstance().AlbumManager.addSavedSearch(req.body.name, req.body.searchQuery); + req.resultPipe = 'ok'; + return next(); + + } catch (err) { + return next(new ErrorDTO(ErrorCodes.ALBUM_ERROR, 'Error during creating saved search albums', err)); + } + } + + +} + + diff --git a/src/backend/middlewares/SharingMWs.ts b/src/backend/middlewares/SharingMWs.ts index 0ec63663..be5697d5 100644 --- a/src/backend/middlewares/SharingMWs.ts +++ b/src/backend/middlewares/SharingMWs.ts @@ -117,6 +117,7 @@ export class SharingMWs { try { req.resultPipe = await ObjectManagers.getInstance().SharingManager.deleteSharing(sharingKey); + req.resultPipe = 'ok'; return next(); } catch (err) { return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during deleting sharing', err)); diff --git a/src/backend/model/ObjectManagers.ts b/src/backend/model/ObjectManagers.ts index a97a9759..85325336 100644 --- a/src/backend/model/ObjectManagers.ts +++ b/src/backend/model/ObjectManagers.ts @@ -9,6 +9,8 @@ import {IPersonManager} from './database/interfaces/IPersonManager'; import {IVersionManager} from './database/interfaces/IVersionManager'; import {IJobManager} from './database/interfaces/IJobManager'; import {LocationManager} from './database/LocationManager'; +import {IAlbumManager} from './database/interfaces/IAlbumManager'; +import {JobManager} from './jobs/JobManager'; const LOG_TAG = '[ObjectManagers]'; @@ -25,6 +27,7 @@ export class ObjectManagers { private versionManager: IVersionManager; private jobManager: IJobManager; private locationManager: LocationManager; + private albumManager: IAlbumManager; get VersionManager(): IVersionManager { @@ -43,6 +46,14 @@ export class ObjectManagers { this.locationManager = value; } + get AlbumManager(): IAlbumManager { + return this.albumManager; + } + + set AlbumManager(value: IAlbumManager) { + this.albumManager = value; + } + get PersonManager(): IPersonManager { return this.personManager; } @@ -121,51 +132,30 @@ export class ObjectManagers { } - public static async InitCommonManagers(): Promise { - const JobManager = require('./jobs/JobManager').JobManager; - ObjectManagers.getInstance().JobManager = new JobManager(); - } - public static async InitMemoryManagers(): Promise { await ObjectManagers.reset(); - const GalleryManager = require('./database/memory/GalleryManager').GalleryManager; - const UserManager = require('./database/memory/UserManager').UserManager; - const SearchManager = require('./database/memory/SearchManager').SearchManager; - const SharingManager = require('./database/memory/SharingManager').SharingManager; - const IndexingManager = require('./database/memory/IndexingManager').IndexingManager; - const PersonManager = require('./database/memory/PersonManager').PersonManager; - const VersionManager = require('./database/memory/VersionManager').VersionManager; - ObjectManagers.getInstance().GalleryManager = new GalleryManager(); - ObjectManagers.getInstance().UserManager = new UserManager(); - ObjectManagers.getInstance().SearchManager = new SearchManager(); - ObjectManagers.getInstance().SharingManager = new SharingManager(); - ObjectManagers.getInstance().IndexingManager = new IndexingManager(); - ObjectManagers.getInstance().PersonManager = new PersonManager(); - ObjectManagers.getInstance().VersionManager = new VersionManager(); - ObjectManagers.getInstance().LocationManager = new LocationManager(); - this.InitCommonManagers(); + this.initManagers('memory'); + Logger.debug(LOG_TAG, 'Memory DB inited'); } public static async InitSQLManagers(): Promise { await ObjectManagers.reset(); await SQLConnection.init(); - const GalleryManager = require('./database/sql/GalleryManager').GalleryManager; - const UserManager = require('./database/sql/UserManager').UserManager; - const SearchManager = require('./database/sql/SearchManager').SearchManager; - const SharingManager = require('./database/sql/SharingManager').SharingManager; - const IndexingManager = require('./database/sql/IndexingManager').IndexingManager; - const PersonManager = require('./database/sql/PersonManager').PersonManager; - const VersionManager = require('./database/sql/VersionManager').VersionManager; - ObjectManagers.getInstance().GalleryManager = new GalleryManager(); - ObjectManagers.getInstance().UserManager = new UserManager(); - ObjectManagers.getInstance().SearchManager = new SearchManager(); - ObjectManagers.getInstance().SharingManager = new SharingManager(); - ObjectManagers.getInstance().IndexingManager = new IndexingManager(); - ObjectManagers.getInstance().PersonManager = new PersonManager(); - ObjectManagers.getInstance().VersionManager = new VersionManager(); - ObjectManagers.getInstance().LocationManager = new LocationManager(); - this.InitCommonManagers(); + this.initManagers('sql'); Logger.debug(LOG_TAG, 'SQL DB inited'); } + private static initManagers(type: 'memory' | 'sql'): void { + ObjectManagers.getInstance().AlbumManager = new (require(`./database/${type}/AlbumManager`).AlbumManager)(); + ObjectManagers.getInstance().GalleryManager = new (require(`./database/${type}/GalleryManager`).GalleryManager)(); + ObjectManagers.getInstance().IndexingManager = new (require(`./database/${type}/IndexingManager`).IndexingManager)(); + ObjectManagers.getInstance().PersonManager = new (require(`./database/${type}/PersonManager`).PersonManager)(); + ObjectManagers.getInstance().SearchManager = new (require(`./database/${type}/SearchManager`).SearchManager)(); + ObjectManagers.getInstance().SharingManager = new (require(`./database/${type}/SharingManager`).SharingManager)(); + ObjectManagers.getInstance().UserManager = new (require(`./database/${type}/UserManager`).UserManager)(); + ObjectManagers.getInstance().VersionManager = new (require(`./database/${type}/VersionManager`).VersionManager)(); + ObjectManagers.getInstance().JobManager = new JobManager(); + ObjectManagers.getInstance().LocationManager = new LocationManager(); + } + } diff --git a/src/backend/model/database/interfaces/IAlbumManager.ts b/src/backend/model/database/interfaces/IAlbumManager.ts new file mode 100644 index 00000000..060300b0 --- /dev/null +++ b/src/backend/model/database/interfaces/IAlbumManager.ts @@ -0,0 +1,19 @@ +import {SearchQueryDTO} from '../../../../common/entities/SearchQueryDTO'; +import {AlbumBaseDTO} from '../../../../common/entities/album/AlbumBaseDTO'; + +export interface IAlbumManager { + /** + * Creates a saved search type of album + */ + addSavedSearch(name: string, searchQuery: SearchQueryDTO): Promise; + + /** + * Deletes an album + */ + deleteAlbum(id: number): Promise; + + /** + * Returns with all albums + */ + getAlbums(): Promise; +} diff --git a/src/backend/model/database/memory/AlbumManager.ts b/src/backend/model/database/memory/AlbumManager.ts new file mode 100644 index 00000000..2e58e8a0 --- /dev/null +++ b/src/backend/model/database/memory/AlbumManager.ts @@ -0,0 +1,19 @@ +import {AlbumBaseDTO} from '../../../../common/entities/album/AlbumBaseDTO'; +import {SearchQueryDTO} from '../../../../common/entities/SearchQueryDTO'; +import {IAlbumManager} from '../interfaces/IAlbumManager'; + +export class AlbumManager implements IAlbumManager { + + public async addSavedSearch(name: string, searchQuery: SearchQueryDTO): Promise { + throw new Error('not supported by memory DB'); + + } + + public async deleteAlbum(id: number): Promise { + throw new Error('not supported by memory DB'); + } + + public async getAlbums(): Promise { + throw new Error('not supported by memory DB'); + } +} diff --git a/src/backend/model/database/sql/AlbumManager.ts b/src/backend/model/database/sql/AlbumManager.ts index 52af4505..dab0ec67 100644 --- a/src/backend/model/database/sql/AlbumManager.ts +++ b/src/backend/model/database/sql/AlbumManager.ts @@ -6,8 +6,9 @@ import {ObjectManagers} from '../../ObjectManagers'; import {ISQLSearchManager} from './ISearchManager'; import {SearchQueryDTO} from '../../../../common/entities/SearchQueryDTO'; import {SavedSearchEntity} from './enitites/album/SavedSearchEntity'; +import { IAlbumManager } from '../interfaces/IAlbumManager'; -export class AlbumManager { +export class AlbumManager implements IAlbumManager{ private static async fillPreviewToAlbum(album: AlbumBaseDTO): Promise { if (!(album as SavedSearchDTO).searchQuery) { throw new Error('no search query present'); diff --git a/src/backend/routes/AlbumRouter.ts b/src/backend/routes/AlbumRouter.ts new file mode 100644 index 00000000..3aee7631 --- /dev/null +++ b/src/backend/routes/AlbumRouter.ts @@ -0,0 +1,56 @@ +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {Express} from 'express'; +import {RenderingMWs} from '../middlewares/RenderingMWs'; +import {UserRoles} from '../../common/entities/UserDTO'; +import {VersionMWs} from '../middlewares/VersionMWs'; +import {AlbumMWs} from '../middlewares/AlbumMWs'; + +export class AlbumRouter { + public static route(app: Express): void { + + this.addListAlbums(app); + this.addAddSavedSearch(app); + this.addDeleteAlbum(app); + } + + + private static addListAlbums(app: Express): void { + app.get(['/api/album'], + // common part + AuthenticationMWs.authenticate, + AuthenticationMWs.authorise(UserRoles.User), + VersionMWs.injectGalleryVersion, + + // specific part + AlbumMWs.listAlbums, + RenderingMWs.renderResult + ); + } + + private static addDeleteAlbum(app: Express): void { + app.delete(['/api/album/:id'], + // common part + AuthenticationMWs.authenticate, + AuthenticationMWs.authorise(UserRoles.Admin), + VersionMWs.injectGalleryVersion, + + // specific part + AlbumMWs.deleteAlbum, + RenderingMWs.renderResult + ); + } + + private static addAddSavedSearch(app: Express): void { + app.put(['/api/album/saved-search'], + // common part + AuthenticationMWs.authenticate, + AuthenticationMWs.authorise(UserRoles.Admin), + VersionMWs.injectGalleryVersion, + + // specific part + AlbumMWs.createSavedSearch, + RenderingMWs.renderResult + ); + } + +} diff --git a/src/backend/routes/Router.ts b/src/backend/routes/Router.ts index 476420de..859721d4 100644 --- a/src/backend/routes/Router.ts +++ b/src/backend/routes/Router.ts @@ -8,6 +8,7 @@ import {AdminRouter} from './admin/AdminRouter'; import {SettingsRouter} from './admin/SettingsRouter'; import {NotificationRouter} from './NotificationRouter'; import {ErrorRouter} from './ErrorRouter'; +import {AlbumRouter} from './AlbumRouter'; export class Router { @@ -15,13 +16,14 @@ export class Router { PublicRouter.route(app); - UserRouter.route(app); - GalleryRouter.route(app); - PersonRouter.route(app); - SharingRouter.route(app); AdminRouter.route(app); - SettingsRouter.route(app); + AlbumRouter.route(app); + GalleryRouter.route(app); NotificationRouter.route(app); + PersonRouter.route(app); + SettingsRouter.route(app); + SharingRouter.route(app); + UserRouter.route(app); ErrorRouter.route(app); } diff --git a/src/backend/routes/SharingRouter.ts b/src/backend/routes/SharingRouter.ts index 4d842b9f..5be08647 100644 --- a/src/backend/routes/SharingRouter.ts +++ b/src/backend/routes/SharingRouter.ts @@ -57,7 +57,7 @@ export class SharingRouter { AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), SharingMWs.deleteSharing, - RenderingMWs.renderOK + RenderingMWs.renderResult ); } diff --git a/src/common/config/public/ClientConfig.ts b/src/common/config/public/ClientConfig.ts index a61254fe..57bf3f0d 100644 --- a/src/common/config/public/ClientConfig.ts +++ b/src/common/config/public/ClientConfig.ts @@ -35,6 +35,13 @@ export class ClientSearchConfig { maxDirectoryResult: number = 200; } + +@SubConfigClass() +export class ClientAlbumConfig { + @ConfigProperty() + enabled: boolean = true; +} + @SubConfigClass() export class ClientSharingConfig { @ConfigProperty() @@ -172,6 +179,8 @@ export class ClientConfig { @ConfigProperty() Sharing: ClientSharingConfig = new ClientSharingConfig(); @ConfigProperty() + Album: ClientAlbumConfig = new ClientAlbumConfig(); + @ConfigProperty() Map: ClientMapConfig = new ClientMapConfig(); @ConfigProperty() RandomPhoto: ClientRandomPhotoConfig = new ClientRandomPhotoConfig(); diff --git a/src/common/entities/Error.ts b/src/common/entities/Error.ts index 0fc322b3..978f6d38 100644 --- a/src/common/entities/Error.ts +++ b/src/common/entities/Error.ts @@ -24,6 +24,8 @@ export enum ErrorCodes { TASK_ERROR = 14, JOB_ERROR = 15, LocationLookUp_ERROR = 16, + + ALBUM_ERROR = 17, } export class ErrorDTO {