diff --git a/harena-manager.postman_collection.json b/harena-manager.postman_collection.json index 8b65380..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 }, @@ -389,6 +389,16 @@ "value": "1", "type": "text", "disabled": true + }, + { + "key": "nItems", + "value": "20", + "type": "text" + }, + { + "key": "nPage", + "value": "1", + "type": "text" } ] }, @@ -533,7 +543,8 @@ }, { "key": "grade", - "value": "aluno", + "value": "student", + "description": "\"professor\" or \"student\"", "type": "text" } ] @@ -676,7 +687,7 @@ "name": "case", "item": [ { - "name": "/case/:id", + "name": "/case", "protocolProfileBehavior": { "disableBodyPruning": true }, @@ -741,7 +752,7 @@ "formdata": [ { "key": "title", - "value": "Caso final - minhoooo", + "value": "Case dump", "type": "text" }, { @@ -777,7 +788,8 @@ { "key": "original_date", "value": "1987-09-13", - "type": "text" + "type": "text", + "disabled": true }, { "key": "complexity", @@ -786,7 +798,7 @@ }, { "key": "institution", - "value": "minho", + "value": "uni", "type": "text" }, { @@ -796,12 +808,89 @@ }, { "key": "permissionSubjectId", - "value": "8575db0a-e0aa-434c-8ca4-29d7ded3937a", + "value": "e31a6421-0f72-4ed9-8383-dcd70910230b", "type": "text" }, { "key": "permissionClearance", - "value": "read", + "value": "1", + "type": "text" + } + ] + }, + "url": { + "raw": "{{api-base-url}}/case", + "host": [ + "{{api-base-url}}" + ], + "path": [ + "case" + ] + } + }, + "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" } ] @@ -883,74 +972,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": { @@ -989,29 +1010,29 @@ "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" }, { "key": "subject_grade", "value": "", - "description": "Choose a specific user grade (professor/aluno)", + "description": "Choose a specific user grade (professor/student)", "type": "text", "disabled": true }, { "key": "clearance", - "value": "4", + "value": "1", "type": "text" }, { "key": "table_id", - "value": "0008f7a0-6635-439d-af22-d0edd6e22138", + "value": "3e506cb9-3bc3-48f8-ab47-42c639c28e1f", "description": "Case ids. Separated by comma if you want multiple ids", "type": "text" } @@ -1566,12 +1587,12 @@ "formdata": [ { "key": "categoryId", - "value": "decisoes-extremas", + "value": "pocus-training", "type": "text" }, { "key": "clearance", - "value": "1", + "value": "4", "type": "text" }, { @@ -1588,14 +1609,39 @@ }, { "key": "fUserType", - "value": "aluno", + "value": "student", "type": "text", "disabled": true }, { "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 } ] }, @@ -1642,22 +1688,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" } ] @@ -2314,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" } ] @@ -2332,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": [ @@ -2362,7 +2504,7 @@ "formdata": [ { "key": "title", - "value": "Turma do Minho", + "value": "group test delete", "type": "text" } ] @@ -2390,12 +2532,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": "6e45f06d-dcec-4c86-98a8-01efe1337e5f", "type": "text" } ] diff --git a/src/adonisjs/app/Controllers/Http/GroupController.js b/src/adonisjs/app/Controllers/Http/GroupController.js index 85479e6..5203a07 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 { @@ -20,6 +21,9 @@ class GroupController { trx.commit() + const user = await User.find(auth.user.id) + await user.groups().attach(group.id) + return response.json(group) } catch (e) { trx.rollback() @@ -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/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 }) + } + } } diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js index 8769ba8..ac375a5 100644 --- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js +++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js @@ -13,6 +13,8 @@ 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 Group = use('App/Models/Group') const uuidv4 = require('uuid/v4') @@ -56,6 +58,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 @@ -66,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') @@ -83,6 +89,8 @@ class CaseController { const trx = await Database.beginTransaction() try { + + const c = new Case() c.id = await uuidv4() c.title = request.input('title') @@ -103,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' @@ -112,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) @@ -129,50 +139,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) { - 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 cv = new CaseVersion() - cv.source = request.input('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) + // 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) + } + + 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) @@ -192,7 +258,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 @@ -224,40 +289,133 @@ 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 + highestClearance = 10 + // 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 + } + } + } + } + //////////////////////////// + + /*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.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){ + 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{ + 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{ + 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) diff --git a/src/adonisjs/app/Controllers/Http/v1/CategoryController.js b/src/adonisjs/app/Controllers/Http/v1/CategoryController.js index 3686048..239cad1 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,203 @@ 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') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_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) + .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(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) + }) + }) + }) + .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') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_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) + .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(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) + }) + }) + }) + .orderBy('cases.created_at', 'desc') + .offset(itemOffset * itemLimit) + .limit(itemLimit) + }else{ - const test = await Database + 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('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(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) + }) + }) + }) + .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', @@ -98,7 +292,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) @@ -106,7 +301,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(){ @@ -114,8 +309,25 @@ 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(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 @@ -125,8 +337,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..cf346cf 100644 --- a/src/adonisjs/app/Controllers/Http/v1/UserController.js +++ b/src/adonisjs/app/Controllers/Http/v1/UserController.js @@ -202,96 +202,262 @@ 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 + 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') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_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) + .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(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) + .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) + }) }) - .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') + .join('case_properties', 'case_properties.case_id', 'cases.id') + .join('properties', 'properties.id', 'case_properties.property_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) + .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(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) + }) }) + }) + .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_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) + .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(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) + }) + }) + }) + .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_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) + .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(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) + .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) + }) }) - .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 }) 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 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", 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')