From 2c36861b5b88395e1d07653091dc3f9877bf4051 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 23 Mar 2021 19:37:29 -0300 Subject: [PATCH 01/18] fix (postman): case endpoints --- harena-manager.postman_collection.json | 155 +++++++++--------- .../app/Controllers/Http/v1/CaseController.js | 26 +-- 2 files changed, 98 insertions(+), 83 deletions(-) diff --git a/harena-manager.postman_collection.json b/harena-manager.postman_collection.json index 8b65380..33c8def 100644 --- a/harena-manager.postman_collection.json +++ b/harena-manager.postman_collection.json @@ -676,7 +676,7 @@ "name": "case", "item": [ { - "name": "/case/:id", + "name": "/case", "protocolProfileBehavior": { "disableBodyPruning": true }, @@ -818,6 +818,83 @@ }, "response": [] }, + { + "name": "/case", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "caseId", + "value": "", + "type": "text" + }, + { + "key": "source", + "value": "", + "type": "text" + }, + { + "key": "title", + "value": "", + "type": "text" + }, + { + "key": "description", + "value": "", + "type": "text" + }, + { + "key": "language", + "value": "", + "type": "text" + }, + { + "key": "domain", + "value": "", + "type": "text" + }, + { + "key": "specialty", + "value": "", + "type": "text" + }, + { + "key": "keywords", + "value": "", + "type": "text" + }, + { + "key": "originalDate", + "value": "", + "type": "text" + }, + { + "key": "complexity", + "value": "", + "type": "text" + }, + { + "key": "published", + "value": "", + "type": "text" + } + ] + }, + "url": { + "raw": "{{api-base-url}}/case", + "host": [ + "{{api-base-url}}" + ], + "path": [ + "case" + ] + } + }, + "response": [] + }, { "name": "/case/link/user", "event": [ @@ -883,74 +960,6 @@ }, "response": [] }, - { - "name": "/case/:id", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "formdata", - "formdata": [ - { - "key": "title", - "value": "test 444", - "type": "text" - }, - { - "key": "description", - "value": "new description 33333", - "type": "text" - }, - { - "key": "language", - "value": "en-us", - "type": "text", - "disabled": true - }, - { - "key": "domain", - "value": "new domain", - "type": "text", - "disabled": true - }, - { - "key": "specialty", - "value": "new specialty", - "type": "text", - "disabled": true - }, - { - "key": "keywords", - "value": "kw1;kw2", - "type": "text", - "disabled": true - }, - { - "key": "source", - "value": "nc1", - "type": "text", - "disabled": true - }, - { - "key": "original_date", - "value": "", - "type": "text" - } - ] - }, - "url": { - "raw": "{{api-base-url}}/case/{{case-id}}", - "host": [ - "{{api-base-url}}" - ], - "path": [ - "case", - "{{case-id}}" - ] - } - }, - "response": [] - }, { "name": "/case", "request": { @@ -1642,22 +1651,22 @@ "formdata": [ { "key": "id", - "value": "desafio-pocus", + "value": "pocus-training", "type": "text" }, { "key": "title", - "value": "Desafio POCUS", + "value": "Treinamento POCUS", "type": "text" }, { "key": "template", - "value": "desafio-pocus", + "value": "pocus-training", "type": "text" }, { "key": "artifact_id", - "value": "desafio-pocus-image", + "value": "pocus-training-image", "type": "text" } ] diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 8769ba8..7f5602c 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -136,18 +136,24 @@ class CaseController { const c = await Case.find(request.input('caseId')) if (c != null) { - c.title = request.input('title') || null - c.description = request.input('description')|| null - c.language = request.input('language')|| null - c.domain = request.input('domain')|| null - c.specialty = request.input('specialty')|| null - c.keywords = request.input('keywords')|| null - c.original_date = request.input('originalDate')|| null - c.complexity = request.input('complexity')|| null - c.published = request.input('published')|| 0 + + const versions = await CaseVersion.query() + .where('case_id', '=', request.input('caseId')) + .orderBy('created_at', 'asc') + .fetch() + + c.title = request.input('title') || c.title + c.description = request.input('description')|| c.description + c.language = request.input('language')|| c.language + c.domain = request.input('domain')|| c.domain + c.specialty = request.input('specialty')|| c.specialty + c.keywords = request.input('keywords')|| c.keywords + c.original_date = request.input('originalDate')|| c.original_date + c.complexity = request.input('complexity')|| c.complexity + c.published = request.input('published')|| c.published const cv = new CaseVersion() - cv.source = request.input('source') + cv.source = request.input('source')|| versions.last().source cv.id = await uuidv4() await c.versions().save(cv) From b021499b45f7add69bf84cb95b30234e121b3e97 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 30 Mar 2021 21:43:02 -0300 Subject: [PATCH 02/18] fix (package.json): bodyparser version --- src/adonisjs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/adonisjs/package.json b/src/adonisjs/package.json index 97ba7a4..9f5cde1 100644 --- a/src/adonisjs/package.json +++ b/src/adonisjs/package.json @@ -18,7 +18,7 @@ "dependencies": { "@adonisjs/ace": "^5.0.8", "@adonisjs/auth": "^3.0.7", - "@adonisjs/bodyparser": "^2.0.5", + "@adonisjs/bodyparser": "~2.0.5", "@adonisjs/cors": "^1.0.7", "@adonisjs/drive": "^1.0.4", "@adonisjs/fold": "^4.0.9", From 1b249516e5f5664940b8fa9621eda112ae892631 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 30 Mar 2021 22:10:18 -0300 Subject: [PATCH 03/18] fix (adonis): promise inside try/catch --- .../Controllers/Http/v1/ArtifactController.js | 4 ++-- .../app/Controllers/Http/v1/CaseController.js | 16 +++++++++------- .../Controllers/Http/v1/CategoryController.js | 2 +- .../app/Controllers/Http/v1/QuestController.js | 6 ++++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js index 18dba59..1f1f587 100644 --- a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js +++ b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js @@ -102,9 +102,9 @@ class ArtifactController { // Missing check permission async destroy ({ params, response }) { - const trx = await Database.beginTransaction() - + try { + const trx = await Database.beginTransaction() const artifact = await Artifact.findBy('id', params.id) if (artifact != null) { diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 7f5602c..1cda90a 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -80,9 +80,9 @@ class CaseController { /** * Create/save a new case. */ async store ({ request, auth, response }) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() const c = new Case() c.id = await uuidv4() c.title = request.input('title') @@ -130,9 +130,9 @@ class CaseController { /** * Update case details. PUT or PATCH case/:id */ async update ({ request, response }) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() const c = await Case.find(request.input('caseId')) if (c != null) { @@ -195,8 +195,8 @@ class CaseController { * @param {Response} ctx.response */ async destroy ({ request, response }) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() const c = await Case.findBy('id', request.input('caseId')) console.log('============ =============================') if (c != null) { @@ -231,9 +231,9 @@ class CaseController { } async share ({params, request, response}){ - const trx = await Database.beginTransaction() - try { + const trx = await Database.beginTransaction() + const entity = request.input('entity') const subject = request.input('subject') const subject_grade = request.input('subject_grade') @@ -273,8 +273,9 @@ class CaseController { } async storeProperty ({params, request, auth, response}) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() + const case_id = request.input('case_id') const property_title = request.input('property_title') const property_value = request.input('property_value') @@ -308,8 +309,9 @@ class CaseController { } async updateProperty ({request, auth, response}) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() + const case_id = request.input('case_id') const property_title = request.input('property_title') const property_value = request.input('property_value') diff --git a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js index 3686048..3497d42 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js @@ -11,8 +11,8 @@ const Case = use('App/Models/v1/Case') class CategoryController { async store ({ request, response }) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() const category = new Category() category.id = await uuidv4() diff --git a/src/adonisjs/app/Controllers/Http/v1/QuestController.js b/src/adonisjs/app/Controllers/Http/v1/QuestController.js index 101efd1..abfaffd 100644 --- a/src/adonisjs/app/Controllers/Http/v1/QuestController.js +++ b/src/adonisjs/app/Controllers/Http/v1/QuestController.js @@ -84,8 +84,9 @@ class QuestController { async destroy ({ params, response }) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() + const q = await Quest.findBy('id', params.id) if (q != null) { @@ -133,9 +134,10 @@ class QuestController { async linkUser ({ request, response }) { - const trx = await Database.beginTransaction() try { + const trx = await Database.beginTransaction() + const { userId, questId, permission } = request.post() if (permission != 'read' && permission != 'share' && permission != 'write'){ From 1e0b2b5394226d9155b8fc35efa2d53703c9a749 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 30 Mar 2021 22:10:18 -0300 Subject: [PATCH 04/18] Revert "fix (adonis): promise inside try/catch" This reverts commit 1b249516e5f5664940b8fa9621eda112ae892631. --- .../Controllers/Http/v1/ArtifactController.js | 4 ++-- .../app/Controllers/Http/v1/CaseController.js | 16 +++++++--------- .../Controllers/Http/v1/CategoryController.js | 2 +- .../app/Controllers/Http/v1/QuestController.js | 6 ++---- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js index 1f1f587..18dba59 100644 --- a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js +++ b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js @@ -102,9 +102,9 @@ class ArtifactController { // Missing check permission async destroy ({ params, response }) { - + const trx = await Database.beginTransaction() + try { - const trx = await Database.beginTransaction() const artifact = await Artifact.findBy('id', params.id) if (artifact != null) { diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 1cda90a..7f5602c 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -80,9 +80,9 @@ class CaseController { /** * Create/save a new case. */ async store ({ request, auth, response }) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() const c = new Case() c.id = await uuidv4() c.title = request.input('title') @@ -130,9 +130,9 @@ class CaseController { /** * Update case details. PUT or PATCH case/:id */ async update ({ request, response }) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() const c = await Case.find(request.input('caseId')) if (c != null) { @@ -195,8 +195,8 @@ class CaseController { * @param {Response} ctx.response */ async destroy ({ request, response }) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() const c = await Case.findBy('id', request.input('caseId')) console.log('============ =============================') if (c != null) { @@ -231,9 +231,9 @@ class CaseController { } async share ({params, request, response}){ - try { - const trx = await Database.beginTransaction() + const trx = await Database.beginTransaction() + try { const entity = request.input('entity') const subject = request.input('subject') const subject_grade = request.input('subject_grade') @@ -273,9 +273,8 @@ class CaseController { } async storeProperty ({params, request, auth, response}) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() - const case_id = request.input('case_id') const property_title = request.input('property_title') const property_value = request.input('property_value') @@ -309,9 +308,8 @@ class CaseController { } async updateProperty ({request, auth, response}) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() - const case_id = request.input('case_id') const property_title = request.input('property_title') const property_value = request.input('property_value') diff --git a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js index 3497d42..3686048 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js @@ -11,8 +11,8 @@ const Case = use('App/Models/v1/Case') class CategoryController { async store ({ request, response }) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() const category = new Category() category.id = await uuidv4() diff --git a/src/adonisjs/app/Controllers/Http/v1/QuestController.js b/src/adonisjs/app/Controllers/Http/v1/QuestController.js index abfaffd..101efd1 100644 --- a/src/adonisjs/app/Controllers/Http/v1/QuestController.js +++ b/src/adonisjs/app/Controllers/Http/v1/QuestController.js @@ -84,9 +84,8 @@ class QuestController { async destroy ({ params, response }) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() - const q = await Quest.findBy('id', params.id) if (q != null) { @@ -134,10 +133,9 @@ class QuestController { async linkUser ({ request, response }) { + const trx = await Database.beginTransaction() try { - const trx = await Database.beginTransaction() - const { userId, questId, permission } = request.post() if (permission != 'read' && permission != 'share' && permission != 'write'){ From 8764f8f43751f67cb3c9dd99e48eca468e4cadee Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Thu, 1 Apr 2021 23:56:36 -0300 Subject: [PATCH 05/18] feat (case save): check clearance before saving --- .../app/Controllers/Http/v1/CaseController.js | 127 +++++++++++++----- src/adonisjs/app/Models/v1/UsersGroup.js | 12 ++ 2 files changed, 102 insertions(+), 37 deletions(-) create mode 100644 src/adonisjs/app/Models/v1/UsersGroup.js diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 7f5602c..0b793cf 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -13,6 +13,7 @@ const Institution = use('App/Models/v1/Institution') const Permission = use('App/Models/v1/Permission') const Property = use('App/Models/v1/Property') const CaseProperty = use('App/Models/v1/CaseProperty') +const UsersGroup = use('App/Models/v1/UsersGroup') const uuidv4 = require('uuid/v4') @@ -56,6 +57,7 @@ class CaseController { .where('case_properties.case_id', request.input('caseId')) var prop = {} + for(let p in properties){ let title = properties[p].title let value = properties[p].value @@ -83,6 +85,8 @@ class CaseController { const trx = await Database.beginTransaction() try { + + const c = new Case() c.id = await uuidv4() c.title = request.input('title') @@ -129,56 +133,106 @@ class CaseController { } /** * Update case details. PUT or PATCH case/:id */ - async update ({ request, response }) { + async update ({ auth, request, response }) { const trx = await Database.beginTransaction() - + var canEdit = false try { + console.log('============') + console.log('attempting to update case...') const c = await Case.find(request.input('caseId')) if (c != null) { - - const versions = await CaseVersion.query() + console.log('============') + console.log('Case found!') + console.log('Verifying user permissions...') + if(c.author_id == auth.user.id){ + canEdit = true + console.log('============') + console.log('User is the author of case') + console.log('============') + }else{ + var casePermission = await Permission + .query() + .where('table', 'cases') + .where('table_id', c.id) + .where('clearance', '>=', '4') + .fetch() + casePermission = casePermission.toJSON() + console.log('============') + console.log(casePermission) + console.log('============') + for(var _permission in casePermission){ + if((casePermission[_permission]['entity'] == 'user' && casePermission[_permission]['subject'] == auth.user.id) + || (casePermission[_permission]['entity'] == 'institution' && casePermission[_permission]['subject'] == auth.user.institution_id)){ + console.log('============') + console.log('User is part of a institution or user able to edit') + console.log('============') + canEdit = true + }else if(casePermission[_permission]['entity'] == 'group'){ + + var group = await UsersGroup + .query() + .where('group_id', casePermission[_permission]['subject']) + .where('user_id', auth.user.id) + .first() + if(group){ + console.log('============') + console.log('User is part of a group able to edit') + console.log('============') + canEdit = true + } + } + } + } + if (canEdit) { + const versions = await CaseVersion.query() .where('case_id', '=', request.input('caseId')) .orderBy('created_at', 'asc') .fetch() - c.title = request.input('title') || c.title - c.description = request.input('description')|| c.description - c.language = request.input('language')|| c.language - c.domain = request.input('domain')|| c.domain - c.specialty = request.input('specialty')|| c.specialty - c.keywords = request.input('keywords')|| c.keywords - c.original_date = request.input('originalDate')|| c.original_date - c.complexity = request.input('complexity')|| c.complexity - c.published = request.input('published')|| c.published - - const cv = new CaseVersion() - cv.source = request.input('source')|| versions.last().source - cv.id = await uuidv4() - await c.versions().save(cv) - - const institutionAcronym = request.input('institution') - if (institutionAcronym != null){ - let institution = await Institution.findBy('acronym', institutionAcronym) - await c.institution().associate(institution) - } + c.title = request.input('title') || c.title + c.description = request.input('description')|| c.description + c.language = request.input('language')|| c.language + c.domain = request.input('domain')|| c.domain + c.specialty = request.input('specialty')|| c.specialty + c.keywords = request.input('keywords')|| c.keywords + c.original_date = request.input('originalDate')|| c.original_date + c.complexity = request.input('complexity')|| c.complexity + c.published = request.input('published')|| c.published + + const cv = new CaseVersion() + cv.source = request.input('source')|| versions.last().source + cv.id = await uuidv4() + await c.versions().save(cv) + + const institutionAcronym = request.input('institution') + if (institutionAcronym != null){ + let institution = await Institution.findBy('acronym', institutionAcronym) + await c.institution().associate(institution) + } + + const permission = new Permission() + permission.id = await uuidv4() + permission.entity = request.input('permissionEntity') + permission.subject = request.input('permissionSubjectId') + permission.clearance = request.input('permissionClearance') + permission.table = 'cases' + permission.table_id = c.id + await permission.save(trx) - const permission = new Permission() - permission.id = await uuidv4() - permission.entity = request.input('permissionEntity') - permission.subject = request.input('permissionSubjectId') - permission.clearance = request.input('permissionClearance') - permission.table = 'cases' - permission.table_id = c.id - permission.save(trx) + await c.save() - await c.save() + trx.commit() - trx.commit() + c.source = cv.source - return response.json(c) + return response.json(c) + }else { + trx.rollback() + return response.json({error:"Error ocurred, you don't have permission to save the changes."}) + } - } else return response.status(500).json('case not found') + } else return response.status(500).json('Case not found.') } catch (e) { trx.rollback() console.log(e) @@ -198,7 +252,6 @@ class CaseController { const trx = await Database.beginTransaction() try { const c = await Case.findBy('id', request.input('caseId')) - console.log('============ =============================') if (c != null) { await c.versions().delete() await Permission diff --git a/src/adonisjs/app/Models/v1/UsersGroup.js b/src/adonisjs/app/Models/v1/UsersGroup.js new file mode 100644 index 0000000..38de253 --- /dev/null +++ b/src/adonisjs/app/Models/v1/UsersGroup.js @@ -0,0 +1,12 @@ +'use strict' + +/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */ +const Model = use('Model') + +class UsersGroup extends Model { + static get incrementing () { + return false + } +} + +module.exports = UsersGroup From 3966876081c07c9ef3d9d202a075edf5e2260e48 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Thu, 1 Apr 2021 23:57:34 -0300 Subject: [PATCH 06/18] feat (ArtifactController): error handling and response --- .../app/Controllers/Http/v1/ArtifactController.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js index 18dba59..20cae40 100644 --- a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js +++ b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js @@ -94,8 +94,16 @@ class ArtifactController { return response.json(bodyMessage) } catch (e) { + console.log('============ Artifact catch error') console.log(e) - return response.status(e.status).json({ message: e.message }) + switch (e.message) { + case 'dest already exists.': + return response.status(500).json({ message: 'Could not upload artifact, id already exists.' }) + break; + default: + return response.status(e.status).json({ message: e.message }) + } + } } From 4a9bd5f4eefe2bcadc7789f3a488650c6063b044 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Fri, 2 Apr 2021 00:02:06 -0300 Subject: [PATCH 07/18] feat (case list): updated json output levels (cases, pages) --- .../Controllers/Http/v1/CategoryController.js | 157 ++++++++++- .../app/Controllers/Http/v1/UserController.js | 244 ++++++++++++------ 2 files changed, 321 insertions(+), 80 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js index 3686048..9ed696d 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js @@ -43,9 +43,9 @@ class CategoryController { if (category != null) { category.title = request.input('title') || null - if (request.input('artifactId')){ - category.artifact_id = request.input('artifactId') - } + if (request.input('artifactId')){ + category.artifact_id = request.input('artifactId') + } await category.save() return response.json(category) @@ -78,7 +78,7 @@ class CategoryController { const user = await auth.user - const clearance = parseInt(request.input('clearance')) + const clearance = parseInt(request.input('clearance')) || 10 const categoryId = request.input('categoryId') const category = await Category.find(categoryId) @@ -87,9 +87,149 @@ class CategoryController { const institutionFilter = request.input('fInstitution') || `%` const userTypeFilter = request.input('fUserType') || `%` const specialtyFilter = request.input('fSpecialty') || `%` + const propertyFilter = request.input('fProperty') || null + const propertyValueFilter = request.input('fPropertyValue') || `%` + + var itemOffset = 0 + const itemLimit = request.input('nItems') || 20 + if (request.input('page') && request.input('page') < 1) + itemOffset = 0 + else + itemOffset = request.input('page') -1 || 0 + + let result = null + var totalPages = null + // console.log(institutionFilter) + // console.log(userTypeFilter) + if(propertyFilter != null){ + + + let countCases = await Database + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('cases.category_id', category.id) + .where('properties.title', propertyFilter) + .where('case_properties.value','like', propertyValueFilter) + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) + .countDistinct('cases.id as cases') + + totalPages = Math.ceil(countCases[0]['cases'] / itemLimit) + + if(itemOffset >= totalPages) + itemOffset = 0 + + const selectPropertyTitle = ('case_properties.value AS ' + propertyFilter) + result = await Database + .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', + 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', + 'cases.author_grade', 'cases.published', 'users.username', + 'institutions.title AS institution', 'institutions.acronym AS institution_acronym', + 'institutions.country AS institution_country', 'cases.created_at', + Database.raw(`CASE WHEN case_properties.value = 0 AND properties.title = 'feedback' + THEN 'Waiting for feedback' WHEN case_properties.value = 1 AND properties.title = 'feedback' + THEN 'Feedback complete' ELSE case_properties.value END AS ?`,[propertyFilter])]) + .distinct('cases.id') + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('cases.category_id', category.id) + .where('properties.title', propertyFilter) + .where('case_properties.value','like', propertyValueFilter) + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) + .orderBy('cases.created_at', 'desc') + .offset(itemOffset * itemLimit) + .limit(itemLimit) - const test = await Database + }else{ + + let countCases = await Database + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('cases.category_id', category.id) + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) + .countDistinct('cases.id as cases') + + totalPages = Math.ceil(countCases[0]['cases'] / itemLimit) + + if(itemOffset >= totalPages) + itemOffset = 0 + + result = await Database .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', 'cases.author_grade', 'cases.published', 'users.username', @@ -106,7 +246,7 @@ class CategoryController { .where('cases.author_grade', 'like', userTypeFilter) .where(function(){ if (specialtyFilter != '%') - this.where('cases.specialty', 'like', specialtyFilter) + this.where('cases.specialty', 'like', specialtyFilter) }) .where(function(){ @@ -125,8 +265,11 @@ class CategoryController { }) }) .orderBy('cases.created_at', 'desc') + .offset(itemOffset * itemLimit) + .limit(itemLimit) + } - return response.json(test) + return response.json({cases:result, pages:totalPages}) } catch (e) { console.log(e) } diff --git a/src/adonisjs/app/Controllers/Http/v1/UserController.js b/src/adonisjs/app/Controllers/Http/v1/UserController.js index abd372b..eac52b2 100644 --- a/src/adonisjs/app/Controllers/Http/v1/UserController.js +++ b/src/adonisjs/app/Controllers/Http/v1/UserController.js @@ -202,96 +202,194 @@ class UserController { const specialtyFilter = request.input('fSpecialty') || `%` const propertyFilter = request.input('fProperty') || null const propertyValueFilter = request.input('fPropertyValue') || '%' - let result = null - // console.log(institutionFilter) - // console.log(userTypeFilter) + var itemOffset = 0 + const itemLimit = request.input('nItems') || 20 + if (request.input('page') && request.input('page') < 1) + itemOffset = 0 + else + itemOffset = request.input('page') -1 || 0 + + // console.log('==============================================================================') + // console.log(itemOffset) + // console.log('==============================================================================') + let result = null + var totalPages = null if(propertyFilter != null){ - const selectPropertyTitle = ('case_properties.value AS ' + propertyFilter) - result = await Database - .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', - 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', - 'cases.author_grade', 'cases.published', 'users.username', - 'institutions.title AS institution', 'institutions.acronym AS institution_acronym', - 'institutions.country AS institution_country', 'cases.created_at', - Database.raw(`CASE WHEN case_properties.value = 0 AND properties.title = 'feedback' - THEN 'Waiting for feedback' WHEN case_properties.value = 1 AND properties.title = 'feedback' - THEN 'Feedback complete' ELSE case_properties.value END AS ?`,[propertyFilter])]) - .distinct('cases.id') - .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.table_id') - .join('case_properties', 'case_properties.case_id', 'cases.id') - .join('properties', 'properties.id', 'case_properties.property_id') - .join('users', 'users.id', 'cases.author_id') - .join('institutions', 'users.institution_id', 'institutions.id') - .where('properties.title', propertyFilter) - .where('case_properties.value','like', propertyValueFilter) - .where('cases.published', '>=', publishedFilter) - .where('cases.institution_id', 'like', institutionFilter) - .where('cases.author_grade', 'like', userTypeFilter) - .where(function(){ - if (specialtyFilter != '%') - this.where('cases.specialty', 'like', specialtyFilter) - }) - .where(function(){ + let countCases = await Database + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('properties.title', propertyFilter) + .where('case_properties.value','like', propertyValueFilter) + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { this - .where('cases.author_id', user.id) - .orWhere(function () { + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) }) }) - .orderBy('cases.created_at', 'desc') - }else{ - - result = await Database - .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', - 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', - 'cases.author_grade', 'cases.published', 'users.username', - 'institutions.title AS institution', 'institutions.acronym AS institution_acronym', - 'institutions.country AS institution_country', 'cases.created_at']) - .distinct('cases.id') - .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.table_id') - .join('users', 'users.id', 'cases.author_id') - .join('institutions', 'users.institution_id', 'institutions.id') - .where('cases.published', '>=', publishedFilter) - .where('cases.institution_id', 'like', institutionFilter) - .where('cases.author_grade', 'like', userTypeFilter) - .where(function(){ - if (specialtyFilter != '%') - this.where('cases.specialty', 'like', specialtyFilter) + }) + .countDistinct('cases.id as cases') + // console.log('============ count cases') + // console.log(countCases[0]['cases'] ) + // console.log(itemLimit) + // console.log(countCases[0]['cases'] / itemLimit) + // console.log(Math.ceil(countCases[0]['cases'] / itemLimit)) + totalPages = Math.ceil(countCases[0]['cases'] / itemLimit) + + if(itemOffset >= totalPages) + itemOffset = 0 + + const selectPropertyTitle = ('case_properties.value AS ' + propertyFilter) + result = await Database + .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', + 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', + 'cases.author_grade', 'cases.published', 'users.username', + 'institutions.title AS institution', 'institutions.acronym AS institution_acronym', + 'institutions.country AS institution_country', 'cases.created_at', + Database.raw(`CASE WHEN case_properties.value = 0 AND properties.title = 'feedback' + THEN 'Waiting for feedback' WHEN case_properties.value = 1 AND properties.title = 'feedback' + THEN 'Feedback complete' ELSE case_properties.value END AS ?`,[propertyFilter])]) + .distinct('cases.id') + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('properties.title', propertyFilter) + .where('case_properties.value','like', propertyValueFilter) + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) }) + }) + .orderBy('cases.created_at', 'desc') + .offset(itemOffset * itemLimit) + .limit(itemLimit) + - .where(function(){ + }else{ + let countCases = await Database + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) + .countDistinct('cases.id as cases') + // console.log('================================================================ number of pages') + // console.log(countCases[0]['cases']) + // console.log(itemLimit) + // console.log(countCases[0]['cases'] / itemLimit) + // console.log(Math.ceil(countCases[0]['cases'] / itemLimit)) + totalPages = Math.ceil(countCases[0]['cases'] / itemLimit) + + if(itemOffset >= totalPages) + itemOffset = 0 + + result = await Database + .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', + 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', + 'cases.author_grade', 'cases.published', 'users.username', + 'institutions.title AS institution', 'institutions.acronym AS institution_acronym', + 'institutions.country AS institution_country', 'cases.created_at']) + .distinct('cases.id') + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users', 'users.id', 'cases.author_id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('cases.published', '>=', publishedFilter) + .where('cases.institution_id', 'like', institutionFilter) + .where('cases.author_grade', 'like', userTypeFilter) + .where(function(){ + if (specialtyFilter != '%') + this.where('cases.specialty', 'like', specialtyFilter) + }) + + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { this - .where('cases.author_id', user.id) - .orWhere(function () { + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + .where('permissions.clearance', '>=', clearance) + .where(function(){ this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) }) }) - .orderBy('cases.created_at', 'desc') + }) + .orderBy('cases.created_at', 'desc') + .offset(itemOffset * itemLimit) + .limit(itemLimit) + } console.log(result) - return response.json(result) + return response.json({cases:result, pages:totalPages}) } catch (e) { console.log(e) return response.status(500).json({ message: e.message }) From 1524be2e47353646f92bfabdb4447dc04bafd0bc Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Fri, 2 Apr 2021 00:34:42 -0300 Subject: [PATCH 08/18] feat (postman): updated endpoints listing cases --- harena-manager.postman_collection.json | 63 ++++++++++++++++++++------ 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/harena-manager.postman_collection.json b/harena-manager.postman_collection.json index 33c8def..07b15b9 100644 --- a/harena-manager.postman_collection.json +++ b/harena-manager.postman_collection.json @@ -389,6 +389,16 @@ "value": "1", "type": "text", "disabled": true + }, + { + "key": "nItems", + "value": "20", + "type": "text" + }, + { + "key": "nPage", + "value": "1", + "type": "text" } ] }, @@ -741,7 +751,7 @@ "formdata": [ { "key": "title", - "value": "Caso final - minhoooo", + "value": "Case dump", "type": "text" }, { @@ -777,7 +787,8 @@ { "key": "original_date", "value": "1987-09-13", - "type": "text" + "type": "text", + "disabled": true }, { "key": "complexity", @@ -786,7 +797,7 @@ }, { "key": "institution", - "value": "minho", + "value": "uni", "type": "text" }, { @@ -796,7 +807,7 @@ }, { "key": "permissionSubjectId", - "value": "8575db0a-e0aa-434c-8ca4-29d7ded3937a", + "value": "e31a6421-0f72-4ed9-8383-dcd70910230b", "type": "text" }, { @@ -1020,7 +1031,7 @@ }, { "key": "table_id", - "value": "0008f7a0-6635-439d-af22-d0edd6e22138", + "value": "caa57510-6195-4352-91f8-09fffafb7ed1", "description": "Case ids. Separated by comma if you want multiple ids", "type": "text" } @@ -1575,13 +1586,14 @@ "formdata": [ { "key": "categoryId", - "value": "decisoes-extremas", + "value": "pocus-training", "type": "text" }, { "key": "clearance", - "value": "1", - "type": "text" + "value": "4", + "type": "text", + "disabled": true }, { "key": "published", @@ -1603,8 +1615,33 @@ }, { "key": "fSpecialty", - "value": "especialidade 1", - "type": "text" + "value": "0", + "type": "text", + "disabled": true + }, + { + "key": "fProperty", + "value": "feedback", + "type": "text", + "disabled": true + }, + { + "key": "fPropertyValue", + "value": "1", + "type": "text", + "disabled": true + }, + { + "key": "nItems", + "value": "20", + "type": "text", + "disabled": true + }, + { + "key": "nPage", + "value": "1", + "type": "text", + "disabled": true } ] }, @@ -2371,7 +2408,7 @@ "formdata": [ { "key": "title", - "value": "Turma do Minho", + "value": "Test Uni", "type": "text" } ] @@ -2399,12 +2436,12 @@ "formdata": [ { "key": "groupId", - "value": "37b4159f-b2bf-4014-b5dc-655df6506311", + "value": "8a419a89-4692-4b32-b485-82a2df44f31f", "type": "text" }, { "key": "userId", - "value": "781c4351-16d7-4b24-b214-bb9fdb3e75bf", + "value": "ab76f569-5c11-4708-abf4-75be3735f956", "type": "text" } ] From 7845bdc7b13d3e111931cb4d0ecbdc5db338b3c5 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 6 Apr 2021 13:28:02 -0300 Subject: [PATCH 09/18] refactor (CaseController): comment logs --- .../app/Controllers/Http/v1/CaseController.js | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 0b793cf..c531306 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -137,19 +137,19 @@ class CaseController { const trx = await Database.beginTransaction() var canEdit = false try { - console.log('============') - console.log('attempting to update case...') + // console.log('============') + // console.log('attempting to update case...') const c = await Case.find(request.input('caseId')) if (c != null) { - console.log('============') - console.log('Case found!') - console.log('Verifying user permissions...') + // console.log('============') + // console.log('Case found!') + // console.log('Verifying user permissions...') if(c.author_id == auth.user.id){ canEdit = true - console.log('============') - console.log('User is the author of case') - console.log('============') + // console.log('============') + // console.log('User is the author of case') + // console.log('============') }else{ var casePermission = await Permission .query() @@ -158,15 +158,15 @@ class CaseController { .where('clearance', '>=', '4') .fetch() casePermission = casePermission.toJSON() - console.log('============') - console.log(casePermission) - console.log('============') + // console.log('============') + // console.log(casePermission) + // console.log('============') for(var _permission in casePermission){ if((casePermission[_permission]['entity'] == 'user' && casePermission[_permission]['subject'] == auth.user.id) || (casePermission[_permission]['entity'] == 'institution' && casePermission[_permission]['subject'] == auth.user.institution_id)){ - console.log('============') - console.log('User is part of a institution or user able to edit') - console.log('============') + // console.log('============') + // console.log('User is part of a institution or user able to edit') + // console.log('============') canEdit = true }else if(casePermission[_permission]['entity'] == 'group'){ @@ -176,9 +176,9 @@ class CaseController { .where('user_id', auth.user.id) .first() if(group){ - console.log('============') - console.log('User is part of a group able to edit') - console.log('============') + // console.log('============') + // console.log('User is part of a group able to edit') + // console.log('============') canEdit = true } } From a430ea9f320941155a8ef57d1e0f0b87697a9880 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Fri, 9 Apr 2021 16:35:49 -0300 Subject: [PATCH 10/18] feat (GroupController): listCases, linkUser, removeUser endpoints --- .../app/Controllers/Http/GroupController.js | 137 ++++++++++++++++-- src/adonisjs/start/routes.js | 8 +- 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/GroupController.js b/src/adonisjs/app/Controllers/Http/GroupController.js index 85479e6..63c402e 100644 --- a/src/adonisjs/app/Controllers/Http/GroupController.js +++ b/src/adonisjs/app/Controllers/Http/GroupController.js @@ -2,13 +2,14 @@ const Group = use('App/Models/Group') const User = use('App/Models/v1/User') +const UsersGroup = use('App/Models/v1/UsersGroup') const Database = use('Database') const uuidv4 = require('uuid/v4') class GroupController { - async store ({ request, response }) { + async store ({ request, response, auth }) { const trx = await Database.beginTransaction() try { @@ -18,6 +19,9 @@ class GroupController { await group.save(trx) + const user = await User.find(auth.user.id) + await user.groups().attach(groupId) + trx.commit() return response.json(group) @@ -33,36 +37,137 @@ class GroupController { async linkUser ({ request, auth, response }) { try { const { userId, groupId } = request.post() - const user = await User.find(userId) + const canLinkUser = await UsersGroup + .query() + .where('user_id', auth.user.id) + .where('group_id', groupId) + .first() + if(canLinkUser && user){ + await user.groups().attach(groupId) + return response.json(user.username + ' successfully added to the group!') + }else if(!canLinkUser){ + return response.status(500).json('Error. You must be part of the group to be able to add another user.') + }else{ + return response.status(500).json('Error. Could not find the user to be added into the group.') + } - await user.groups().attach(groupId) + } catch (e) { + console.log(e) + return response.status(e.status).json({ message: e.toString() }) + } + } + + + async listCases ({ request, response, auth }) { + try { + const groupId = request.input('groupId') + if(await Group.find(groupId)){ + var itemOffset = 0 + const itemLimit = request.input('nItems') || 20 + if (request.input('page') && request.input('page') < 1) + itemOffset = 0 + else + itemOffset = request.input('page') - 1 || 0 + + var totalPages = null + + let countCases = await Database + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('permissions.entity', 'group') + .where('permissions.subject', groupId) + .countDistinct('cases.id as cases') + + + totalPages = Math.ceil(countCases[0]['cases'] / itemLimit) + + if(itemOffset >= totalPages) + itemOffset = 0 + + const result = await Database + .select([ 'cases.id', 'cases.title','cases.description', 'cases.language', 'cases.domain', + 'cases.specialty', 'cases.keywords', 'cases.complexity', 'cases.original_date', + 'cases.author_grade', 'cases.published', 'users.username', + 'institutions.title AS institution', 'institutions.acronym AS institution_acronym', + 'institutions.country AS institution_country', 'cases.created_at']) + .distinct('cases.id') + .from('cases') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') + .join('institutions', 'users.institution_id', 'institutions.id') + .where('permissions.entity', 'group') + .where('permissions.subject', groupId) + .orderBy('cases.created_at', 'desc') + .offset(itemOffset * itemLimit) + .limit(itemLimit) + + + return response.json(result) + }else{ + return response.status(500).json('Error. Could not find selected group.') + } - return response.json('user successfully added to the group') } catch (e) { console.log(e) return response.status(e.status).json({ message: e.toString() }) } } + async listUsers ({ request, auth, response }) { + try { + const groupId = request.input('groupId') + if(await Group.find(groupId)){ + const result = await Database + .select('user_id','group_id','groups.title as group_title') + .from('users_groups') + .join('groups','users_groups.group_id','groups.id') + .where ('users_groups.group_id', groupId) + + return response.json(result) + } + else { + return response.status(500).json('Error. Could not find selected group.') + } + } catch (e) { + console.log(e) + return response.status(e.status).json({ message: e.toString() }) + } + + + } - async listCases ({ request, response }) { + async removeUser ({ request, auth, response }){ try { + const userId = request.input('userId') const groupId = request.input('groupId') + const user = await User.find(userId) - const result = await Database - .select([ 'cases.id', 'cases.title','description', 'users.username']) - .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.case_id') - .where('entity', 'group') - .where('subject', groupId) - .where('clearance', 'read') - .leftJoin('users_cases', 'cases.id', 'users_cases.case_id') - .leftJoin('users', 'users.id', 'users_cases.user_id') - - return response.json(result) + const canRemoveUser = await UsersGroup + .query() + .where('user_id', auth.user.id) + .where('group_id', groupId) + .first() + const isInGroup = await UsersGroup + .query() + .where('user_id', user.id) + .where('group_id', groupId) + .first() + if(canRemoveUser && user && isInGroup){ + await user.groups().detach(groupId) + return response.json(user.username + ' successfully removed from the group!') + }else if(!canRemoveUser){ + return response.status(500).json('Error. You must be part of the group to be able to remove another user.') + }else{ + return response.status(500).json('Error. Could not find the user to be removed from the group.') + } } catch (e) { console.log(e) + return response.status(e.status).json({ message: e.toString() }) } } } diff --git a/src/adonisjs/start/routes.js b/src/adonisjs/start/routes.js index e41166a..f4bcf6e 100644 --- a/src/adonisjs/start/routes.js +++ b/src/adonisjs/start/routes.js @@ -167,9 +167,11 @@ Route.group(() => { |---------------------------------------------------------------------------------------------- */ Route.group(() => { - Route.post( '', 'GroupController.store') - Route.post( 'link/user', 'GroupController.linkUser') - Route.get( 'cases', 'GroupController.listCases') + Route.post( '', 'GroupController.store') + Route.post( 'link/user', 'GroupController.linkUser') + Route.delete( 'user', 'GroupController.removeUser') + Route.get( 'cases', 'GroupController.listCases') + Route.get( 'users', 'GroupController.listUsers') // Route.get( 'list', 'v1/CategoryController.listCategories') // Route.put( ':id', 'v1/CategoryController.update') From ab57cd54f8ff5d7c27ffa121ff2c9f406853328e Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Fri, 9 Apr 2021 16:48:37 -0300 Subject: [PATCH 11/18] refactor (listCases): verify all permissions. Same with share case --- .../app/Controllers/Http/v1/CaseController.js | 85 +++++++--- .../Controllers/Http/v1/CategoryController.js | 156 ++++++++++++++++-- .../app/Controllers/Http/v1/UserController.js | 146 ++++++++++++++-- 3 files changed, 336 insertions(+), 51 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index c531306..3f400ad 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -283,36 +283,83 @@ class CaseController { } } - async share ({params, request, response}){ + async share ({params, request, response, auth}){ const trx = await Database.beginTransaction() try { + var canShare = false + var highestClearance = 0 const entity = request.input('entity') const subject = request.input('subject') const subject_grade = request.input('subject_grade') const clearance = request.input('clearance') const table_id = request.input('table_id').split(',') - // console.log(entity) - // console.log(subject) - // console.log(clearance) - // console.log(table_id) for (let c in table_id){ - // console.log('============ case for') console.log(table_id[c]) - if(await Case.findBy('id', table_id[c])){ - // console.log('================================================ case added') - // console.log(table_id[c]) - let permission = new Permission() - permission.id = await uuidv4() - permission.entity = entity - permission.subject = subject - permission.subject_grade = subject_grade - permission.clearance = clearance - permission.table = 'cases' - permission.table_id = table_id[c] - await permission.save(trx) - }else return response.json('Could not find the case id, please review and try again') + var _case = await Case.findBy('id', table_id[c]) + if(_case){ + ///////////////////////////// + if(_case.author_id == auth.user.id){ + canShare = true + // console.log('============') + // console.log('User is the author of case') + // console.log('============') + }else{ + var casePermission = await Permission + .query() + .where('table', 'cases') + .where('table_id', _case.id) + .where('clearance', '>=', '3') + .fetch() + casePermission = casePermission.toJSON() + // console.log('============') + // console.log(casePermission) + // console.log('============') + for(var _permission in casePermission){ + if((casePermission[_permission]['entity'] == 'user' && casePermission[_permission]['subject'] == auth.user.id) + || (casePermission[_permission]['entity'] == 'institution' && casePermission[_permission]['subject'] == auth.user.institution_id)){ + // console.log('============') + // console.log('User is part of a institution or user able to edit') + // console.log('============') + if(casePermission[_permission]['clearance'] > highestClearance) + highestClearance = casePermission[_permission]['clearance'] + canShare = true + }else if(casePermission[_permission]['entity'] == 'group'){ + + var group = await UsersGroup + .query() + .where('group_id', casePermission[_permission]['subject']) + .where('user_id', auth.user.id) + .first() + if(group){ + // console.log('============') + // console.log('User is part of a group able to edit') + // console.log('============') + if(casePermission[_permission]['clearance'] > highestClearance) + highestClearance = casePermission[_permission]['clearance'] + canShare = true + } + } + } + } + //////////////////////////// + if(canShare && clearance < highestClearance){ + let permission = new Permission() + permission.id = await uuidv4() + permission.entity = entity + permission.subject = subject + permission.subject_grade = subject_grade + permission.clearance = clearance + permission.table = 'cases' + permission.table_id = table_id[c] + await permission.save(trx) + }else if (!canShare){ + return response.status(500).json("Couldn't share the case. Your permission is not high enough, contact the author of the case.") + }else{ + return response.status(500).json("Couldn't share the case. You're trying to share a case with higher permission than what you actually have. Please lower the permission (example: '1' or '2')") + } + }else return response.status(500).json('Could not find the case id, please review and try again') } trx.commit() diff --git a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js index 9ed696d..a21bd9b 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js @@ -106,10 +106,11 @@ class CategoryController { let countCases = await Database .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.table_id') .join('case_properties', 'case_properties.case_id', 'cases.id') .join('properties', 'properties.id', 'case_properties.property_id') - .join('users', 'users.id', 'cases.author_id') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('cases.category_id', category.id) .where('properties.title', propertyFilter) @@ -127,8 +128,39 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this @@ -156,10 +188,11 @@ class CategoryController { THEN 'Feedback complete' ELSE case_properties.value END AS ?`,[propertyFilter])]) .distinct('cases.id') .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.table_id') .join('case_properties', 'case_properties.case_id', 'cases.id') .join('properties', 'properties.id', 'case_properties.property_id') - .join('users', 'users.id', 'cases.author_id') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('cases.category_id', category.id) .where('properties.title', propertyFilter) @@ -177,8 +210,39 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this @@ -196,7 +260,8 @@ class CategoryController { let countCases = await Database .from('cases') .leftJoin('permissions', 'cases.id', 'permissions.table_id') - .join('users', 'users.id', 'cases.author_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('cases.category_id', category.id) .where('cases.published', '>=', publishedFilter) @@ -212,8 +277,39 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this @@ -238,7 +334,8 @@ class CategoryController { .distinct('cases.id') .from('cases') .leftJoin('permissions', 'cases.id', 'permissions.table_id') - .join('users', 'users.id', 'cases.author_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('cases.category_id', category.id) .where('cases.published', '>=', publishedFilter) @@ -254,8 +351,39 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this diff --git a/src/adonisjs/app/Controllers/Http/v1/UserController.js b/src/adonisjs/app/Controllers/Http/v1/UserController.js index eac52b2..e6f6614 100644 --- a/src/adonisjs/app/Controllers/Http/v1/UserController.js +++ b/src/adonisjs/app/Controllers/Http/v1/UserController.js @@ -209,20 +209,17 @@ class UserController { else itemOffset = request.input('page') -1 || 0 - // console.log('==============================================================================') - // console.log(itemOffset) - // console.log('==============================================================================') - let result = null var totalPages = null if(propertyFilter != null){ let countCases = await Database .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.table_id') .join('case_properties', 'case_properties.case_id', 'cases.id') .join('properties', 'properties.id', 'case_properties.property_id') - .join('users', 'users.id', 'cases.author_id') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('properties.title', propertyFilter) .where('case_properties.value','like', propertyValueFilter) @@ -239,8 +236,39 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this @@ -272,10 +300,11 @@ class UserController { THEN 'Feedback complete' ELSE case_properties.value END AS ?`,[propertyFilter])]) .distinct('cases.id') .from('cases') - .leftJoin('permissions', 'cases.id', 'permissions.table_id') .join('case_properties', 'case_properties.case_id', 'cases.id') .join('properties', 'properties.id', 'case_properties.property_id') - .join('users', 'users.id', 'cases.author_id') + .leftJoin('permissions', 'cases.id', 'permissions.table_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('properties.title', propertyFilter) .where('case_properties.value','like', propertyValueFilter) @@ -292,8 +321,39 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this @@ -311,7 +371,8 @@ class UserController { let countCases = await Database .from('cases') .leftJoin('permissions', 'cases.id', 'permissions.table_id') - .join('users', 'users.id', 'cases.author_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('cases.published', '>=', publishedFilter) .where('cases.institution_id', 'like', institutionFilter) @@ -326,8 +387,39 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + ////// + .where(function(){ + this + .where('cases.author_id', user.id) + .orWhere(function () { + this + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) + .where('permissions.clearance', '>=', clearance) + .where(function(){ + this + .whereNull('permissions.subject_grade') + .orWhere('permissions.subject_grade', user.grade) + }) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this @@ -356,7 +448,8 @@ class UserController { .distinct('cases.id') .from('cases') .leftJoin('permissions', 'cases.id', 'permissions.table_id') - .join('users', 'users.id', 'cases.author_id') + .join('users_groups') + .join('users', 'cases.author_id','users.id') .join('institutions', 'users.institution_id', 'institutions.id') .where('cases.published', '>=', publishedFilter) .where('cases.institution_id', 'like', institutionFilter) @@ -371,8 +464,25 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) + .where(function(){ + this + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) + }) + }) .where('permissions.clearance', '>=', clearance) .where(function(){ this From 8986940b8a887976e5520e50eb0a902b76d02b4b Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Fri, 9 Apr 2021 17:48:47 -0300 Subject: [PATCH 12/18] feat (postman): new group endpoints --- harena-manager.postman_collection.json | 110 +++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 7 deletions(-) diff --git a/harena-manager.postman_collection.json b/harena-manager.postman_collection.json index 07b15b9..ec8c781 100644 --- a/harena-manager.postman_collection.json +++ b/harena-manager.postman_collection.json @@ -1009,12 +1009,12 @@ "formdata": [ { "key": "entity", - "value": "institution", + "value": "user", "type": "text" }, { "key": "subject", - "value": "c5562bfd-9a94-40f0-b08a-3627e3e417e0", + "value": "4a689978-57d8-4470-a8db-d7959a42586d", "type": "text" }, { @@ -1026,12 +1026,12 @@ }, { "key": "clearance", - "value": "4", + "value": "1", "type": "text" }, { "key": "table_id", - "value": "caa57510-6195-4352-91f8-09fffafb7ed1", + "value": "3e506cb9-3bc3-48f8-ab47-42c639c28e1f", "description": "Case ids. Separated by comma if you want multiple ids", "type": "text" } @@ -2360,7 +2360,17 @@ "formdata": [ { "key": "groupId", - "value": "37b4159f-b2bf-4014-b5dc-655df6506311", + "value": "8a419a89-4692-4b32-b485-82a2df44f31f", + "type": "text" + }, + { + "key": "nItems", + "value": "20", + "type": "text" + }, + { + "key": "nPage", + "value": "1", "type": "text" } ] @@ -2378,6 +2388,92 @@ }, "response": [] }, + { + "name": "/group/users (wip)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "groupId", + "value": "8a419a89-4692-4b32-b485-82a2df44f31f", + "type": "text" + } + ] + }, + "url": { + "raw": "{{api-base-url}}/group/users", + "host": [ + "{{api-base-url}}" + ], + "path": [ + "group", + "users" + ] + } + }, + "response": [] + }, + { + "name": "/group/user (wip)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "groupId", + "value": "b26b6fe4-1bb6-470f-a0c2-033fb7be54c7", + "type": "text" + }, + { + "key": "userId", + "value": "4a689978-57d8-4470-a8db-d7959a42586d", + "type": "text" + } + ] + }, + "url": { + "raw": "{{api-base-url}}/group/user", + "host": [ + "{{api-base-url}}" + ], + "path": [ + "group", + "user" + ] + } + }, + "response": [] + }, { "name": "/group (wip)", "event": [ @@ -2408,7 +2504,7 @@ "formdata": [ { "key": "title", - "value": "Test Uni", + "value": "group title", "type": "text" } ] @@ -2441,7 +2537,7 @@ }, { "key": "userId", - "value": "ab76f569-5c11-4708-abf4-75be3735f956", + "value": "6e45f06d-dcec-4c86-98a8-01efe1337e5f", "type": "text" } ] From 8b8fef4134459782aaa6fbab9e9514d7bf51a150 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 13 Apr 2021 11:47:57 -0300 Subject: [PATCH 13/18] fix (list cases): duplicate subquery --- .../Controllers/Http/v1/CategoryController.js | 168 ++++++------------ .../app/Controllers/Http/v1/UserController.js | 126 +++++-------- 2 files changed, 98 insertions(+), 196 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js index a21bd9b..239cad1 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js @@ -128,37 +128,23 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) @@ -210,37 +196,23 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) @@ -277,37 +249,23 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) @@ -351,37 +309,23 @@ class CategoryController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) diff --git a/src/adonisjs/app/Controllers/Http/v1/UserController.js b/src/adonisjs/app/Controllers/Http/v1/UserController.js index e6f6614..cf346cf 100644 --- a/src/adonisjs/app/Controllers/Http/v1/UserController.js +++ b/src/adonisjs/app/Controllers/Http/v1/UserController.js @@ -236,37 +236,23 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) @@ -321,37 +307,23 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ + this + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) @@ -387,37 +359,23 @@ class UserController { .where('cases.author_id', user.id) .orWhere(function () { this - ////// .where(function(){ this - .where('cases.author_id', user.id) - .orWhere(function () { + .where(function(){ this - .where(function(){ - this - .where(function(){ - this - .where('permissions.entity', 'institution') - .where('permissions.subject', user.institution_id) - }) - .orWhere(function(){ - this - .where('permissions.entity', 'user') - .where('permissions.subject', user.id) - }) - .orWhere(function() { - this - .where('permissions.entity', 'group') - .whereRaw('permissions.subject = users_groups.group_id') - .where('users_groups.user_id', user.id) - }) - }) - .where('permissions.clearance', '>=', clearance) - .where(function(){ - this - .whereNull('permissions.subject_grade') - .orWhere('permissions.subject_grade', user.grade) - }) + .where('permissions.entity', 'institution') + .where('permissions.subject', user.institution_id) + }) + .orWhere(function(){ + this + .where('permissions.entity', 'user') + .where('permissions.subject', user.id) + }) + .orWhere(function() { + this + .where('permissions.entity', 'group') + .whereRaw('permissions.subject = users_groups.group_id') + .where('users_groups.user_id', user.id) }) }) .where('permissions.clearance', '>=', clearance) From 51c03c6ff90763f684f42a18db7bd8663dd5d489 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 13 Apr 2021 13:46:00 -0300 Subject: [PATCH 14/18] fix (GroupController): creating group and sharing case --- src/adonisjs/app/Controllers/Http/GroupController.js | 6 +++--- src/adonisjs/app/Controllers/Http/v1/CaseController.js | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/GroupController.js b/src/adonisjs/app/Controllers/Http/GroupController.js index 63c402e..5203a07 100644 --- a/src/adonisjs/app/Controllers/Http/GroupController.js +++ b/src/adonisjs/app/Controllers/Http/GroupController.js @@ -19,11 +19,11 @@ class GroupController { await group.save(trx) - const user = await User.find(auth.user.id) - await user.groups().attach(groupId) - trx.commit() + const user = await User.find(auth.user.id) + await user.groups().attach(group.id) + return response.json(group) } catch (e) { trx.rollback() diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 3f400ad..ed1822c 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -302,9 +302,11 @@ class CaseController { ///////////////////////////// if(_case.author_id == auth.user.id){ canShare = true + highestClearance = 10 // console.log('============') // console.log('User is the author of case') // console.log('============') + }else{ var casePermission = await Permission .query() From b518b57343402ff9216d53b8c5d7651124ce791a Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 13 Apr 2021 21:49:20 -0300 Subject: [PATCH 15/18] feat (share case): verify if id exists and error feedback --- .../app/Controllers/Http/v1/CaseController.js | 57 +++++++++++++++++-- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index ed1822c..1d2ac42 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -14,6 +14,7 @@ const Permission = use('App/Models/v1/Permission') const Property = use('App/Models/v1/Property') const CaseProperty = use('App/Models/v1/CaseProperty') const UsersGroup = use('App/Models/v1/UsersGroup') +const Group = use('App/Models/Group') const uuidv4 = require('uuid/v4') @@ -346,26 +347,70 @@ class CaseController { } } //////////////////////////// - if(canShare && clearance < highestClearance){ + + /*Transforms subject entry into respective id from table, depending on entity type + Also verifies if object exists e.g.(user with email test@test) + Default value usually is institution id + */ + var _subject = await Institution.find(subject) + if(entity =='user'){ + if(subject.includes('@')) + _subject = await User.findBy('email',subject) + else + _subject = await User.find(subject) + }else if(entity =='group'){ + _subject = await Group.findBy('title', subject) + } + + if(canShare && clearance < highestClearance && _subject){ let permission = new Permission() permission.id = await uuidv4() permission.entity = entity - permission.subject = subject + permission.subject = _subject.id permission.subject_grade = subject_grade permission.clearance = clearance permission.table = 'cases' permission.table_id = table_id[c] await permission.save(trx) + }else if (!canShare){ - return response.status(500).json("Couldn't share the case. Your permission is not high enough, contact the author of the case.") + trx.rollback() + return response.status(500). + json({message:"Error. Couldn't share the case. Your permission is not high enough, contact the author of the case."}) + }else if(!_subject){ + switch (entity) { + case 'institution': + trx.rollback() + return response.status(500). + json({message:"Error. Couldn't find the informed institution, you probably forgot to select one. Please review and try again."}) + break + case 'user': + trx.rollback() + return response.status(500). + json({message:"Error. Couldn't find an user with the informed email. Please review and try again."}) + break + case 'group': + trx.rollback() + return response.status(500). + json({message:"Error. Couldn't find a group with the informed title. Please review and try again."}) + break + default: + } + }else{ - return response.status(500).json("Couldn't share the case. You're trying to share a case with higher permission than what you actually have. Please lower the permission (example: '1' or '2')") + trx.rollback() + return response.status(500). + json({message:"Error. Couldn't share one or more cases. You're trying to share a case with higher permission than what you actually have. Please lower the permission (example: 'Play' or 'Share')"}) } - }else return response.status(500).json('Could not find the case id, please review and try again') + }else{ + trx.rollback() + return response.status(500). + json({message:'Error. Could not find the case id, please review and try again'}) + } } trx.commit() - return response.json('Cases shared successfully!') + return response.json({message:'Cases shared successfully!'}) } catch (e) { trx.rollback() console.log(e) From 5118bd355b49e6575349fcd932c9a130e104c48f Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Wed, 14 Apr 2021 22:20:42 -0300 Subject: [PATCH 16/18] feat (CaseController): GET case returns case author username --- src/adonisjs/app/Controllers/Http/v1/CaseController.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 1d2ac42..cda23cb 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -69,9 +69,12 @@ class CaseController { c.versions = versions c.property = prop + const caseAuthor = await User.find(c.author_id) const institution = await Institution.find(c.institution_id) - c.institution = institution.acronym - c.institutionTitle = institution.title + c.institution_acronym = institution.acronym + c.institution = institution.title + c.institution_country = institution.country + c.username = caseAuthor.username return response.json(c) } else return response.status(500).json('case not found') From ebbc24700e9b2367efe161ab76d323b6e906ced1 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 27 Apr 2021 12:05:37 -0300 Subject: [PATCH 17/18] feat (postman): user grade changed from 'aluno' to 'student' --- harena-manager.postman_collection.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/harena-manager.postman_collection.json b/harena-manager.postman_collection.json index ec8c781..cc66771 100644 --- a/harena-manager.postman_collection.json +++ b/harena-manager.postman_collection.json @@ -368,7 +368,7 @@ }, { "key": "fUserType", - "value": "aluno", + "value": "student", "type": "text", "disabled": true }, @@ -543,7 +543,8 @@ }, { "key": "grade", - "value": "aluno", + "value": "student", + "description": "\"professor\" or \"student\"", "type": "text" } ] @@ -812,7 +813,7 @@ }, { "key": "permissionClearance", - "value": "read", + "value": "1", "type": "text" } ] @@ -1020,7 +1021,7 @@ { "key": "subject_grade", "value": "", - "description": "Choose a specific user grade (professor/aluno)", + "description": "Choose a specific user grade (professor/student)", "type": "text", "disabled": true }, @@ -1592,8 +1593,7 @@ { "key": "clearance", "value": "4", - "type": "text", - "disabled": true + "type": "text" }, { "key": "published", @@ -1609,7 +1609,7 @@ }, { "key": "fUserType", - "value": "aluno", + "value": "student", "type": "text", "disabled": true }, @@ -2504,7 +2504,7 @@ "formdata": [ { "key": "title", - "value": "group title", + "value": "group test delete", "type": "text" } ] From ac22848e6cb8e62a54e6e2d308a4926bac44fea6 Mon Sep 17 00:00:00 2001 From: Heitor Mattosinho Date: Tue, 27 Apr 2021 13:34:50 -0300 Subject: [PATCH 18/18] refactor (case store): deactivate automatic share with institution --- src/adonisjs/app/Controllers/Http/v1/CaseController.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index cda23cb..ac375a5 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -111,6 +111,7 @@ class CaseController { cv.source = request.input('source') await c.versions().save(cv, trx) + /* const permission = new Permission() permission.id = await uuidv4() permission.entity = request.input('permissionEntity') || 'institution' @@ -120,6 +121,7 @@ class CaseController { permission.table_id = c.id permission.save(trx) + */ let institution = await Institution.find(auth.user.institution_id) await c.institution().associate(institution, trx)