From 3df1631a740601d642eb67a086e2fb2ce907175e Mon Sep 17 00:00:00 2001 From: Ezequiel Ramos Date: Fri, 5 Jul 2024 12:33:21 -0300 Subject: [PATCH 1/3] feature/addingWatchLists --- .vscode/settings.json | 8 ++++++ src/controllers/events.ts | 6 ++--- src/controllers/humans.ts | 6 ++--- src/controllers/watch-lists.ts | 45 +++++++++++++++++++++++++++++++++- src/routes/cards.ts | 39 +++++++++++++++++------------ src/routes/watch-lists.ts | 19 ++++++++++++-- tests/watch-lists.test.ts | 18 ++++++++++++++ 7 files changed, 115 insertions(+), 26 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fc009bd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "cSpell.words": [ + "abcdefghijklmnopqrstuvxyz", + "fullframe", + "medmask", + "traceback" + ] +} \ No newline at end of file diff --git a/src/controllers/events.ts b/src/controllers/events.ts index 5ebfe28..4d280d3 100644 --- a/src/controllers/events.ts +++ b/src/controllers/events.ts @@ -1,4 +1,4 @@ -import { WatchList, watchLists } from "./watch-lists"; +import { WatchList, getWatchLists } from "./watch-lists"; function randomCharacters(length: number) { let result = ''; @@ -110,7 +110,7 @@ function createEvent({ created_date, camera }: { created_date?: string; camera: confidence: (Math.random() * 0.45) + 0.5, external_detector: true, looks_like_confidence: null, - matched_lists: [watchLists[0].id], + matched_lists: [getWatchLists()[0].id], meta: {}, quality: 0.79995, video_archive: null, @@ -154,7 +154,7 @@ function createEvent({ created_date, camera }: { created_date?: string; camera: id: null } }, - verbose_matched_lists: [watchLists[0]], + verbose_matched_lists: [getWatchLists()[0]], // TODO: once camera is implemented, bring it here verbose_camera: {}, // TODO: once camera group is implemented, bring it here diff --git a/src/controllers/humans.ts b/src/controllers/humans.ts index 05a36bf..49a8252 100644 --- a/src/controllers/humans.ts +++ b/src/controllers/humans.ts @@ -24,7 +24,7 @@ interface Human { let humanId = 0; const humans: { [humanId: number]: Human | undefined; } = {}; -function createHuman({ name, active }: { name: string; active: boolean; }) { +function createHuman({ name, active, watchLists }: { name: string; active: boolean; watchLists: number[]; }) { humanId++; const human: Human = { "id": humanId, @@ -34,9 +34,7 @@ function createHuman({ name, active }: { name: string; active: boolean; }) { "modified_date": new Date(), "name": name, "comment": "", - "watch_lists": [ - 1 - ], + "watch_lists": watchLists, "meta": {}, "active_after": null, "active_before": null, diff --git a/src/controllers/watch-lists.ts b/src/controllers/watch-lists.ts index e907f30..b550d3d 100644 --- a/src/controllers/watch-lists.ts +++ b/src/controllers/watch-lists.ts @@ -21,6 +21,8 @@ interface WatchList { origin: "ffsecurity"; } +let watchListId = 1; + const watchLists: WatchList[] = [ { "id": -1, @@ -68,4 +70,45 @@ const watchLists: WatchList[] = [ } ]; -export { watchLists, WatchList }; +function getWatchLists() { + return watchLists; +} + +function createWatchList(name: string) { + watchListId++; + const watchList: WatchList = { + "id": watchListId, + "created_date": new Date().toISOString(), + "modified_date": new Date().toISOString(), + "active": true, + "name": name, + "comment": "", + "color": "123456", + "notify": false, + "acknowledge": false, + "camera_groups": [], + "face_threshold": null, + "body_threshold": null, + "car_threshold": null, + "ignore_events": false, + "send_events_to_external_vms": false, + "active_after": null, + "active_before": null, + "disable_schedule": {}, + "recount_schedule_on": null, + "origin": "ffsecurity" + }; + watchLists.push(watchList); + + return watchList; +} + +function getWatchList(id: number) { + const filteredWatchLists = watchLists.filter(watchList => watchList.id == id); + if (filteredWatchLists.length) { + return filteredWatchLists[0]; + } + return null; +} + +export { createWatchList, getWatchLists, getWatchList, WatchList }; diff --git a/src/routes/cards.ts b/src/routes/cards.ts index 8f40471..4660fa6 100644 --- a/src/routes/cards.ts +++ b/src/routes/cards.ts @@ -1,6 +1,7 @@ import { Express, Request, Response } from 'express'; import { validAuthorization } from '../services/route_middlewares'; import { createHuman, deleteHuman, getHuman } from '../controllers/humans'; +import { getWatchLists } from '../controllers/watch-lists'; function loadCardRoutes(app: Express) { @@ -38,32 +39,38 @@ function loadCardRoutes(app: Express) { watchLists = [req.body.watch_lists]; } + const watchListsIds = getWatchLists().map(wl => wl.id); - if (watchLists != 1 || Number(watchLists[0]) != 1) { - const missingPermissions = watchLists - .filter((v: string | number) => !([1, -1].includes(Number(v)))) - .map((v: string | number) => `Watch list(${v}) - view`); + for (const watchList of watchLists) { - if (missingPermissions.length == 0) { - return res.status(400).json({ + if (!watchListsIds.includes(watchList)) { + const missingPermissions = watchLists + .filter((v: string | number) => !(watchListsIds.includes(Number(v)))) + .map((v: string | number) => `Watch list(${v}) - view`); + + if (missingPermissions.length == 0) { + return res.status(400).json({ + "traceback": "", + "code": "BAD_PARAM", + "desc": "You can't add watch list \"Unmatched\" to a card", + "param": "watch_lists" + }); + } + + return res.status(403).json({ "traceback": "", - "code": "BAD_PARAM", - "desc": "You can't add watch list \"Unmatched\" to a card", - "param": "watch_lists" + "code": "PERMISSION_DENIED", + "desc": "Permission denied", + "missing_permissions": missingPermissions }); } - return res.status(403).json({ - "traceback": "", - "code": "PERMISSION_DENIED", - "desc": "Permission denied", - "missing_permissions": missingPermissions - }); } const human = createHuman({ name: req.body.name, - active: req.body.active ?? true + active: req.body.active ?? true, + watchLists }); return res.status(200).json(human); diff --git a/src/routes/watch-lists.ts b/src/routes/watch-lists.ts index 92663dd..1be7af4 100644 --- a/src/routes/watch-lists.ts +++ b/src/routes/watch-lists.ts @@ -1,16 +1,31 @@ import { Express, Request, Response } from 'express'; import { validAuthorization } from '../services/route_middlewares'; -import { watchLists } from '../controllers/watch-lists'; +import { getWatchLists, createWatchList } from '../controllers/watch-lists'; function loadWatchListsRoutes(app: Express) { app.get('/watch-lists/', validAuthorization, async (req: Request, res: Response) => { return res.status(200).json({ - "results": watchLists + "results": getWatchLists() }); }); + app.post('/watch-lists/', validAuthorization, async (req: Request, res: Response) => { + if (!req.body.name) { + return res.status(400).json({ + "traceback": "", + "code": "BAD_PARAM", + "desc": "This field is required.", + "param": "name" + }); + } + + const watchList = createWatchList(req.body.name); + + return res.status(200).json(watchList); + }); + } export { loadWatchListsRoutes }; diff --git a/tests/watch-lists.test.ts b/tests/watch-lists.test.ts index 488907f..6499805 100644 --- a/tests/watch-lists.test.ts +++ b/tests/watch-lists.test.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { agent } from 'supertest'; import { webService } from '../src/services/web-service'; +import { WatchList } from '../src/controllers/watch-lists'; const request = agent(webService.app); @@ -27,4 +28,21 @@ describe('Watch Lists Route Testing', async () => { const res = await request.get(`/watch-lists/`).set('Authorization', 'Token ' + token); expect(res.statusCode).to.be.equal(200); }); + + it('test create watch lists', async () => { + let res; + res = await request.post(`/watch-lists/`) + .set('Authorization', 'Token ' + token) + .send({ + name: 'Company 1' + }) + .type('application/json'); + expect(res.statusCode).to.be.equal(200); + + res = await request.get(`/watch-lists/`).set('Authorization', 'Token ' + token); + expect(res.statusCode).to.be.equal(200); + + const names = res.body.results.map((wl: WatchList) => wl.name); + expect(names).to.includes('Company 1'); + }); }); From 8f3317edd114d3c18771445c317fe8dfbb4be1cb Mon Sep 17 00:00:00 2001 From: Ezequiel Ramos Date: Fri, 5 Jul 2024 13:22:51 -0300 Subject: [PATCH 2/3] fix unmatched validation --- src/routes/cards.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/routes/cards.ts b/src/routes/cards.ts index 4660fa6..1e2a6bb 100644 --- a/src/routes/cards.ts +++ b/src/routes/cards.ts @@ -39,16 +39,13 @@ function loadCardRoutes(app: Express) { watchLists = [req.body.watch_lists]; } - const watchListsIds = getWatchLists().map(wl => wl.id); + const watchListsIds = getWatchLists().filter(wl => wl.id != -1).map(wl => wl.id); for (const watchList of watchLists) { if (!watchListsIds.includes(watchList)) { - const missingPermissions = watchLists - .filter((v: string | number) => !(watchListsIds.includes(Number(v)))) - .map((v: string | number) => `Watch list(${v}) - view`); - if (missingPermissions.length == 0) { + if (watchList == -1) { return res.status(400).json({ "traceback": "", "code": "BAD_PARAM", @@ -57,6 +54,10 @@ function loadCardRoutes(app: Express) { }); } + const missingPermissions = watchLists + .filter((v: string | number) => !(watchListsIds.includes(Number(v)))) + .map((v: string | number) => `Watch list(${v}) - view`); + return res.status(403).json({ "traceback": "", "code": "PERMISSION_DENIED", From ff9443a02f221fa13c5a9ee01d96fff6f4875215 Mon Sep 17 00:00:00 2001 From: Ezequiel Ramos Date: Fri, 5 Jul 2024 13:24:12 -0300 Subject: [PATCH 3/3] fix unmatched validation --- src/routes/cards.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/routes/cards.ts b/src/routes/cards.ts index 1e2a6bb..c5a0e76 100644 --- a/src/routes/cards.ts +++ b/src/routes/cards.ts @@ -41,19 +41,19 @@ function loadCardRoutes(app: Express) { const watchListsIds = getWatchLists().filter(wl => wl.id != -1).map(wl => wl.id); + if (watchLists.includes(-1)) { + return res.status(400).json({ + "traceback": "", + "code": "BAD_PARAM", + "desc": "You can't add watch list \"Unmatched\" to a card", + "param": "watch_lists" + }); + } + for (const watchList of watchLists) { if (!watchListsIds.includes(watchList)) { - if (watchList == -1) { - return res.status(400).json({ - "traceback": "", - "code": "BAD_PARAM", - "desc": "You can't add watch list \"Unmatched\" to a card", - "param": "watch_lists" - }); - } - const missingPermissions = watchLists .filter((v: string | number) => !(watchListsIds.includes(Number(v)))) .map((v: string | number) => `Watch list(${v}) - view`);