From c0719e4e478cd0e48dc25bc37e995845d3018a20 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Tue, 12 Nov 2024 13:52:01 +0100 Subject: [PATCH 01/13] chore: removed useless oackage consul --- app/api/index.js | 8 +----- consul.js | 75 ------------------------------------------------ package.json | 1 - web.js | 12 -------- 4 files changed, 1 insertion(+), 95 deletions(-) delete mode 100644 consul.js diff --git a/app/api/index.js b/app/api/index.js index 96dbbe4..414364a 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -18,10 +18,8 @@ const routers = new Router() routers.use(bodyParser()) routers.get('/healthcheck', (ctx) => { - // ctx.body = 'inra.paca.gatekeeper is up!' - console.log('consul hit!!') ctx.res.statusCode = 200 - ctx.res.end('OK!') + ctx.res.end('OK') }) // user @@ -96,8 +94,4 @@ routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.al routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update) routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole) -// user-resource - -// role-field - module.exports = routers diff --git a/consul.js b/consul.js deleted file mode 100644 index 9ec9b07..0000000 --- a/consul.js +++ /dev/null @@ -1,75 +0,0 @@ -const Consul = require("consul"); - -class ConsulConfig { - constructor() { - //Initialize consumer - this.consul = new Consul({ - host: this.ConsulIp, - port: this.ConsulPort, - promisify: true, - }); - - // Service registration and health check configuration - this.consul.agent.service.register( - { - name: this.ServiceName, - Address: this.ServiceIp, - port: this.ServicePort, - /* check: { - http: 'http://147.100.18.116:4000/healthcheck', - interval: '10s', - timeout: '6s', - } */ - }, - function (err, result) { - if (err) { - console.error(err); - throw err; - } - - console.log( - "in-sylva.gatekeeper" + "registered successfully!" + result - ); - } - ); - } - - async getConfig(key) { - const result = await this.consul.kv.get(key); - - if (!result) { - return Promise.reject(key + "does not exist"); - } - - return JSON.parse(result.Value); - } - - //Read user configuration simple package - async getUserConfig(key) { - const result = await this.getConfig("develop/user"); - - if (!key) { - return result; - } - - return result[key]; - } - - //Update user configuration simple package - async setUserConfig(key, val) { - const user = await this.getConfig("develop/user"); - - user[key] = val; - - return this.consul.kv.set("develop/user", JSON.stringify(user)); - } -} - -ConsulConfig.prototype.ConsulIp = null; -ConsulConfig.prototype.ConsulPort = null; -ConsulConfig.prototype.ServiceIp = null; -ConsulConfig.prototype.ServicePort = null; -ConsulConfig.prototype.ServiceName = "in-sylva-source-manager"; - -module.exports = ConsulConfig; - diff --git a/package.json b/package.json index 6e9070b..8287ebe 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "array.prototype.flatmap": "1.2.4", "bcrypt": "^5.1.0", "bluebird": "3.7.2", - "consul": "^0.37.0", "keycloak-admin": "1.14.8", "keycloak-connect": "12.0.3", "keycloak-koa-connect": "^1.0.5", diff --git a/web.js b/web.js index dfb191c..f714d79 100644 --- a/web.js +++ b/web.js @@ -11,17 +11,6 @@ logger.level = config.logger.level const server = http.createServer(app.callback()) const serverListen = promisify(server.listen).bind(server) -if (process.env.NODE_ENV === 'production') { - - // const ConsulConfig = require('./consul'); - // const consul = new ConsulConfig(); - // consul.ConsulIp = process.env.CONSUL_IP - // consul.ConsulPort = process.env.CONSUL_PORT - // consul.ServiceIp = process.env.SERVICE_IP - // consul.ServicePort = process.env.PORT - // consul.ServiceName = process.env.SERVICE_NAME -} - serverListen(config.port) .then(() => { logger.info(`in-sylva.gatekeeper service is up and running on localhost:${config.port}`) @@ -30,4 +19,3 @@ serverListen(config.port) logger.error(err) process.exit(1) }) - -- GitLab From d9926e0566e05be6a9bbf53c1701b6c17a663154 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Tue, 12 Nov 2024 17:09:48 +0100 Subject: [PATCH 02/13] chore: general clean-up --- app/api/index.js | 22 ++++---- app/api/realm/delete.js | 4 +- app/api/realm/get.js | 5 +- app/api/realm/post.js | 5 +- app/api/realm/put.js | 5 +- app/api/role-user/delete.js | 3 +- app/api/role-user/get.js | 3 +- app/api/role-user/post.js | 2 - app/api/role-user/put.js | 3 +- app/api/role-v2/index.js | 2 - app/api/roles/delete.js | 4 +- app/api/roles/get.js | 2 - app/api/roles/post.js | 4 +- app/api/roles/put.js | 4 +- app/api/user-requests/delete.js | 4 +- app/api/user-requests/get.js | 4 +- app/api/user-requests/post.js | 4 +- app/api/user-search-history/delete.js | 4 +- app/api/user-search-history/get.js | 4 +- app/api/user-search-history/post.js | 7 ++- app/api/users/delete.js | 2 - app/api/users/get.js | 1 - app/api/users/post.js | 3 ++ app/api/users/put.js | 4 +- app/dal/groupService.js | 72 +++++++------------------- app/dal/policyService.js | 74 +++++---------------------- app/dal/realmService.js | 23 +++------ app/dal/roleAllocationService.js | 26 +++------- app/dal/roleService.js | 38 ++++++-------- app/dal/searchHistoryService.js | 35 ++++--------- app/dal/userRequestService.js | 52 +++++-------------- app/dal/userService.js | 51 ++++++------------ app/models/Group.js | 40 +-------------- app/models/Policy.js | 42 +-------------- app/models/Role.js | 18 ------- app/models/StdField.js | 7 --- app/models/User.js | 5 +- app/utils/format.js | 4 +- app/utils/hashPass.js | 20 -------- app/utils/memory-store.js | 29 ----------- init-keycloak.js | 26 +++------- keycloak.js | 8 +-- server.js | 19 ++----- 43 files changed, 153 insertions(+), 541 deletions(-) delete mode 100644 app/api/role-v2/index.js delete mode 100644 app/utils/hashPass.js delete mode 100644 app/utils/memory-store.js diff --git a/app/api/index.js b/app/api/index.js index 414364a..acc378f 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -2,8 +2,7 @@ const Router = require("koa-router") const bodyParser = require("koa-bodyparser") - -const { keycloak } = require('../../init-keycloak') +/* const { keycloak } = require('../../init-keycloak') */ // handlers const userHandler = require('./users') @@ -13,7 +12,7 @@ const searchHistoryHandler = require('./user-search-history') const userRequestHandler = require('./user-requests') const groupHandler = require('./group') const policyHandler = require('./policy') -const { groups } = require("../dal/groupService") + const routers = new Router() routers.use(bodyParser()) @@ -22,7 +21,7 @@ routers.get('/healthcheck', (ctx) => { ctx.res.end('OK') }) -// user +// Users routers.post('/user', userHandler.addNewUser) routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user) routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users) @@ -34,17 +33,17 @@ routers.post('/user/assigned-by-role', userHandler.getAssignedUserByRole) routers.post('/user/send-mail', userHandler.sendMail) routers.post('/user/reset-password', userHandler.resetPassword) -// System User +// System admin user routers.post('/user/create-system-user', userHandler.createSystemUser) routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole) routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole) -// search-history +// Search history routers.post('/user/add-history', searchHistoryHandler.add) routers.post('/user/fetch-history', searchHistoryHandler.fetch) routers.delete('/user/delete-history', searchHistoryHandler.deleteH) -// user requests +// User requests routers.post('/user/create-request', userRequestHandler.createRequest) routers.delete('/user/delete-request', userRequestHandler.deleteRequest) routers.post('/user/process-request', userRequestHandler.processRequest) @@ -52,7 +51,7 @@ routers.get('/user/list-requests', userRequestHandler.fetchRequests) routers.post('/user/list-requests-by-user', userRequestHandler.fetchRequestsByUser) routers.get('/user/list-pending-requests', userRequestHandler.fetchPendingRequests) -// group +// Groups routers.post('/user/groups', groupHandler.groups) routers.post('/user/group-policies', groupHandler.groupPolicies) routers.post('/user/group-users', groupHandler.groupUsers) @@ -66,7 +65,7 @@ routers.delete('/user/delete-group', groupHandler.deleteGroup) routers.delete('/user/delete-group-policy', groupHandler.deleteGroupPolicy) routers.delete('/user/delete-group-user', groupHandler.deleteGroupUser) -// policy +// Policies routers.post('/policy/add', policyHandler.createPolicy) routers.delete('/policy/delete', policyHandler.deletePolicy) routers.put('/policy/update', policyHandler.updatePolicy) @@ -81,14 +80,15 @@ routers.delete('/policyField/delete', policyHandler.deletePolicyField) routers.put('/policyField/update', policyHandler.updatePolicyField) routers.get('/policyField/list', policyHandler.policyFields) routers.post('/policySource/add', policyHandler.createPolicySource) -// role + +// Roles routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole) routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles) routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role) routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole) routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update) -// role-user +// Role allocation to users routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole) routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles) routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update) diff --git a/app/api/realm/delete.js b/app/api/realm/delete.js index 791f45c..7549275 100644 --- a/app/api/realm/delete.js +++ b/app/api/realm/delete.js @@ -4,7 +4,6 @@ const realmService = require('../../dal/realmService') const logger = require('../../utils/format') const util = require('util') - const DeleteRealm = { async deleteRealm(ctx) { try { @@ -19,8 +18,7 @@ const DeleteRealm = { } } - module.exports = { deleteRealm: DeleteRealm.deleteRealm, DeleteRealm -} \ No newline at end of file +} diff --git a/app/api/realm/get.js b/app/api/realm/get.js index 743d94c..e360853 100644 --- a/app/api/realm/get.js +++ b/app/api/realm/get.js @@ -4,9 +4,7 @@ const realmService = require('../../dal/realmService') const logger = require('../../utils/format') const util = require('util') - const GetRealm = { - async find(ctx) { try { ctx.body = await realmService.realms() @@ -33,9 +31,8 @@ const GetRealm = { } - module.exports = { realms: GetRealm.find, realm: GetRealm.findOne, GetRealm -} \ No newline at end of file +} diff --git a/app/api/realm/post.js b/app/api/realm/post.js index 0e04834..b27dd6e 100644 --- a/app/api/realm/post.js +++ b/app/api/realm/post.js @@ -4,9 +4,7 @@ const realmService = require("../../dal/realmService") const logger = require("../../utils/format") const util = require('util') - const AddRealm = { - async AddNewRealm(ctx) { try { ctx.body = await realmService.create(ctx.request.body) @@ -20,8 +18,7 @@ const AddRealm = { } } - module.exports = { addRealm: AddRealm.AddNewRealm, AddRealm -} \ No newline at end of file +} diff --git a/app/api/realm/put.js b/app/api/realm/put.js index 3c8e3d9..8a4b28b 100644 --- a/app/api/realm/put.js +++ b/app/api/realm/put.js @@ -4,9 +4,7 @@ const realmService = require("../../dal/realmService"); const logger = require('../../utils/format') const util = require('util') - const UpdateRealm = { - async update(ctx) { try { ctx.body = await realmService.update(ctx.request.body); @@ -20,8 +18,7 @@ const UpdateRealm = { } } - module.exports = { update: UpdateRealm.update, UpdateRealm -} \ No newline at end of file +} diff --git a/app/api/role-user/delete.js b/app/api/role-user/delete.js index 7394e1b..618849b 100644 --- a/app/api/role-user/delete.js +++ b/app/api/role-user/delete.js @@ -6,7 +6,6 @@ const util = require('util') const DeleteAllocatedRole = { - async deleteAllocatedRole(ctx) { try { ctx.body = await roleAllocationService.delete(ctx.request.body) @@ -23,4 +22,4 @@ const DeleteAllocatedRole = { module.exports = { deleteAllocatedRole: DeleteAllocatedRole.deleteAllocatedRole, DeleteAllocatedRole -} \ No newline at end of file +} diff --git a/app/api/role-user/get.js b/app/api/role-user/get.js index 29deb2f..cc3d513 100644 --- a/app/api/role-user/get.js +++ b/app/api/role-user/get.js @@ -5,7 +5,6 @@ const logger = require("../../utils/format") const util = require('util') const GetAllocatedRole = { - async find(ctx) { try { const allocatedRoles = await roleAllocationService.allocatedRoles(ctx.request.body) @@ -24,4 +23,4 @@ const GetAllocatedRole = { module.exports = { allocatedRoles: GetAllocatedRole.find, GetAllocatedRole -} \ No newline at end of file +} diff --git a/app/api/role-user/post.js b/app/api/role-user/post.js index 798ed05..26313ab 100644 --- a/app/api/role-user/post.js +++ b/app/api/role-user/post.js @@ -4,9 +4,7 @@ const roleAllocationService = require("../../dal/roleAllocationService") const logger = require("../../utils/format") const util = require('util') - const AllocateRoleToUser = { - async allocateRoleToUser(ctx) { try { ctx.body = await roleAllocationService.create(ctx.request.body) diff --git a/app/api/role-user/put.js b/app/api/role-user/put.js index 58cf427..dbd82d8 100644 --- a/app/api/role-user/put.js +++ b/app/api/role-user/put.js @@ -18,8 +18,7 @@ const UpdateAllocatedRole = { } } - module.exports = { update: UpdateAllocatedRole.update, UpdateAllocatedRole -} \ No newline at end of file +} diff --git a/app/api/role-v2/index.js b/app/api/role-v2/index.js deleted file mode 100644 index b7ff1bc..0000000 --- a/app/api/role-v2/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' - diff --git a/app/api/roles/delete.js b/app/api/roles/delete.js index 56b6b38..a1c80fc 100644 --- a/app/api/roles/delete.js +++ b/app/api/roles/delete.js @@ -4,9 +4,7 @@ const roleService = require('../../dal/roleService') const logger = require('../../utils/format') const util = require('util') - const DeleteRole = { - async deleteRole(ctx) { try { ctx.body = await roleService.delete(ctx.request.body) @@ -23,4 +21,4 @@ const DeleteRole = { module.exports = { deleteRole: DeleteRole.deleteRole, DeleteRole, -} \ No newline at end of file +} diff --git a/app/api/roles/get.js b/app/api/roles/get.js index 37789be..b92913d 100644 --- a/app/api/roles/get.js +++ b/app/api/roles/get.js @@ -35,5 +35,3 @@ module.exports = { role: GetRole.findOne, GetRole } - - diff --git a/app/api/roles/post.js b/app/api/roles/post.js index d38fd7b..230c2ff 100644 --- a/app/api/roles/post.js +++ b/app/api/roles/post.js @@ -4,9 +4,7 @@ const roleService = require("../../dal/roleService") const logger = require('../../utils/format') const util = require('util') - const AddRole = { - async addNewRole(ctx) { try { ctx.body = await roleService.create(ctx.request.body) @@ -23,4 +21,4 @@ const AddRole = { module.exports = { addNewRole: AddRole.addNewRole, AddRole -} \ No newline at end of file +} diff --git a/app/api/roles/put.js b/app/api/roles/put.js index 24e1fd6..5338694 100644 --- a/app/api/roles/put.js +++ b/app/api/roles/put.js @@ -4,14 +4,12 @@ const roleService = require('../../dal/roleService') const logger = require('../../utils/format') const util = require('util') - const UpdateRole = { async update(ctx) { try { ctx.body = await roleService.update(ctx.request.body) ctx.status = 201 logger.info('role is updated successfully!') - } catch (err) { ctx.body = err || 'Error occurred!' ctx.status = 500 @@ -23,4 +21,4 @@ const UpdateRole = { module.exports = { update: UpdateRole.update, UpdateRole -} \ No newline at end of file +} diff --git a/app/api/user-requests/delete.js b/app/api/user-requests/delete.js index 2e2515d..3723d10 100644 --- a/app/api/user-requests/delete.js +++ b/app/api/user-requests/delete.js @@ -4,9 +4,7 @@ const userRequestService = require('../../dal/userRequestService') const logger = require('../../utils/format') const util = require('util') - const UserRequest = { - async delete(ctx) { try { ctx.body = await userRequestService.delete(ctx.request.body) @@ -23,4 +21,4 @@ const UserRequest = { module.exports = { deleteRequest: UserRequest.delete, UserRequest -} \ No newline at end of file +} diff --git a/app/api/user-requests/get.js b/app/api/user-requests/get.js index d682e94..18bd98c 100644 --- a/app/api/user-requests/get.js +++ b/app/api/user-requests/get.js @@ -4,9 +4,7 @@ const userRequestService = require('../../dal/userRequestService') const logger = require('../../utils/format') const util = require('util') - const UserRequest = { - async list(ctx) { try { ctx.body = await userRequestService.fetch(ctx.request.body) @@ -36,4 +34,4 @@ module.exports = { fetchRequests: UserRequest.list, fetchPendingRequests: UserRequest.listPending, UserRequest -} \ No newline at end of file +} diff --git a/app/api/user-requests/post.js b/app/api/user-requests/post.js index 9d865c9..c1b3ef2 100644 --- a/app/api/user-requests/post.js +++ b/app/api/user-requests/post.js @@ -5,7 +5,6 @@ const logger = require('../../utils/format') const util = require('util') const UserRequest = { - async create(ctx) { try { ctx.body = await userRequestService.create(ctx.request.body) @@ -17,6 +16,7 @@ const UserRequest = { logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) } }, + async process(ctx) { try { ctx.body = await userRequestService.process(ctx.request.body) @@ -47,4 +47,4 @@ module.exports = { processRequest: UserRequest.process, fetchRequestsByUser: UserRequest.listByUser, UserRequest -} \ No newline at end of file +} diff --git a/app/api/user-search-history/delete.js b/app/api/user-search-history/delete.js index 2d43762..fb2ad03 100644 --- a/app/api/user-search-history/delete.js +++ b/app/api/user-search-history/delete.js @@ -4,9 +4,7 @@ const searchHistoryService = require('../../dal/searchHistoryService') const logger = require('../../utils/format') const util = require('util') - const SearchHistory = { - async delete(ctx) { try { ctx.body = await searchHistoryService.delete(ctx.request.body) @@ -23,4 +21,4 @@ const SearchHistory = { module.exports = { deleteH: SearchHistory.delete, SearchHistory -} \ No newline at end of file +} diff --git a/app/api/user-search-history/get.js b/app/api/user-search-history/get.js index 7f2b75d..33e150e 100644 --- a/app/api/user-search-history/get.js +++ b/app/api/user-search-history/get.js @@ -4,9 +4,7 @@ const searchHistoryService = require('../../dal/searchHistoryService') const logger = require('../../utils/format') const util = require('util') - const SearchHistory = { - async list(ctx) { try { ctx.body = await searchHistoryService.fetch(ctx.request.body) @@ -23,4 +21,4 @@ const SearchHistory = { module.exports = { fetch: SearchHistory.list, SearchHistory -} \ No newline at end of file +} diff --git a/app/api/user-search-history/post.js b/app/api/user-search-history/post.js index 61e2a33..c31879d 100644 --- a/app/api/user-search-history/post.js +++ b/app/api/user-search-history/post.js @@ -4,8 +4,7 @@ const searchHistoryService = require('../../dal/searchHistoryService') const logger = require('../../utils/format') const util = require('util') -const SearchHistory = { - +const SearchHistory = { async add(ctx) { try { ctx.body = await searchHistoryService.create(ctx.request.body) @@ -16,10 +15,10 @@ const SearchHistory = { ctx.status = 500 logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) } - } + } } module.exports = { add: SearchHistory.add, SearchHistory -} \ No newline at end of file +} diff --git a/app/api/users/delete.js b/app/api/users/delete.js index 3ec3c0a..ceaf0ad 100644 --- a/app/api/users/delete.js +++ b/app/api/users/delete.js @@ -1,4 +1,3 @@ - 'use strict' const userService = require("../../dal/userService") @@ -6,7 +5,6 @@ const logger = require('../../utils/format') const util = require('util') const DeleteUser = { - async deleteUser(ctx) { try { ctx.body = await userService.delete(ctx.request.body) diff --git a/app/api/users/get.js b/app/api/users/get.js index 9330633..7f73c7c 100644 --- a/app/api/users/get.js +++ b/app/api/users/get.js @@ -77,7 +77,6 @@ const GetUser = { logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) } } - }; module.exports = { diff --git a/app/api/users/post.js b/app/api/users/post.js index a368b49..5679838 100644 --- a/app/api/users/post.js +++ b/app/api/users/post.js @@ -31,6 +31,7 @@ const AddUser = { logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) } }, + async sendMail(ctx) { try { ctx.body = await userService.sendMail(ctx.request.body) @@ -42,6 +43,7 @@ const AddUser = { logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) } }, + async userWithGroupAndRole(ctx) { try { ctx.body = await userService.userWithGroupAndRole(ctx.request.body); @@ -53,6 +55,7 @@ const AddUser = { logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) } }, + async resetPassword(ctx) { try { ctx.body = await userService.resetPassword(ctx.request.body); diff --git a/app/api/users/put.js b/app/api/users/put.js index 26cf36e..74a19f1 100644 --- a/app/api/users/put.js +++ b/app/api/users/put.js @@ -4,9 +4,7 @@ const userService = require("../../dal/userService") const logger = require('../../utils/format') const util = require('util') - const UpdateUser = { - async update(ctx) { try { ctx.body = await userService.update(ctx.request.body) @@ -23,4 +21,4 @@ const UpdateUser = { module.exports = { update: UpdateUser.update, UpdateUser -} \ No newline at end of file +} diff --git a/app/dal/groupService.js b/app/dal/groupService.js index b2d9900..cd141c3 100644 --- a/app/dal/groupService.js +++ b/app/dal/groupService.js @@ -1,9 +1,6 @@ 'use strict' -// const db = require('../../db'); - const { Group, GroupUser, GroupsPolicy } = require('../models/Group') - const userService = require('./userService') const db = require('../../db') @@ -14,31 +11,26 @@ const GroupService = { throw Error("The request body is empty!") } - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") - - const user = await userService.detail({ kcId: ctx.kcId }) + } + const user = await userService.detail({ kcId: ctx.kcId }); if (user) { - const group = await Group.findOne({ where: { name: ctx.name, user_id: user.id, } }) - if (group) { throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`) } else { - const newGroup = await Group.create({ + return await Group.create({ name: ctx.name, description: ctx.description, user_id: user.id, }) - - return newGroup } - } else { throw Error('The user account could not found.') } @@ -59,12 +51,10 @@ const GroupService = { if (groupPolicy) { throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`) } else { - const newGroupPolicy = await GroupsPolicy.create({ + return await GroupsPolicy.create({ group_id: ctx.groupId, policy_id: ctx.policyId }) - - return newGroupPolicy } }, @@ -73,28 +63,25 @@ const GroupService = { throw Error("The request body is empty!") } - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") + } const user = await userService.detail({ kcId: ctx.kcId }) if (user) { - const groupUser = await GroupUser.findOne({ where: { group_id: ctx.groupId, user_id: user.id } }) - if (groupUser) { throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`) } else { - const newGroupUser = await GroupUser.create({ + return await GroupUser.create({ group_id: ctx.groupId, user_id: user.id }) - - return newGroupUser } } else { throw Error('The user account could not found.') @@ -106,15 +93,13 @@ const GroupService = { throw Error("The request body is empty!") } - const group = await Group.update({ + return await Group.update({ name: ctx.name, description: ctx.description, }, { - where: { id: ctx.id, user_id: ctx.userId } + where: {id: ctx.id, user_id: ctx.userId} }) - return group - }, async updateGroupPolicy(ctx) { @@ -122,12 +107,10 @@ const GroupService = { throw Error("The request body is empty!") } - const groupPolicy = await GroupsPolicy.update({ + return await GroupsPolicy.update({ group_id: ctx.groupId, policy_id: ctx.policyId - }, { where: { id: ctx.id } }) - - return groupPolicy + }, {where: {id: ctx.id}}) }, async updateGroupUser(ctx) { @@ -137,12 +120,10 @@ const GroupService = { const user = await userService.detail({ kcId: ctx.kcId }) if (user) { - const groupUser = await GroupUser.update({ + return await GroupUser.update({ group_id: ctx.groupId, user_id: user.id - }, { where: { id: ctx.id } }) - - return groupUser + }, {where: {id: ctx.id}}) } else { throw Error('The user account could not found.') @@ -154,13 +135,11 @@ const GroupService = { throw Error("The request body is empty!") } if (ctx.id) { - const group = await Group.destroy({ + return await Group.destroy({ where: { id: ctx.id } }) - - return group } }, @@ -169,13 +148,11 @@ const GroupService = { throw Error("The request body is empty!") } - const groupPolicy = await GroupsPolicy.destroy({ + return await GroupsPolicy.destroy({ where: { id: ctx.id } }) - - return groupPolicy }, async deleteGroupUser(ctx) { @@ -193,20 +170,12 @@ const GroupService = { return groupUser }, - async groups(ctx) { - /*if (!ctx) { - throw Error("The request body is empty!") - }*/ - + async groups() { return await Group.findAll({}) }, - async groupPolicies(ctx) { - /*if (!ctx) { - throw Error("The request body is empty!") - }*/ - + async groupPolicies() { return await GroupsPolicy.findAll({}) }, @@ -214,16 +183,13 @@ const GroupService = { if (!ctx) { throw Error("The request body is empty!") } - const params = { groupId: ctx.groupId } - const groupUsers = await db.raw(` select g.id as groupId, u.id as userId, u.username, g.name, g.description from group_users gu inner join users u on u.id = gu.user_id inner join groups g on gu.group_id = g.id where g.id = :groupId `, params) - return groupUsers.rows } } @@ -245,4 +211,4 @@ module.exports = { groups: GroupService.groups, groupPolicies: GroupService.groupPolicies, groupUsers: GroupService.groupUsers, -} \ No newline at end of file +} diff --git a/app/dal/policyService.js b/app/dal/policyService.js index dc2faa3..7488169 100644 --- a/app/dal/policyService.js +++ b/app/dal/policyService.js @@ -11,10 +11,9 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") - + } const user = await userService.detail({ kcId: ctx.kcId }) if (user) { const policy = await Policy.findOne({ @@ -28,14 +27,12 @@ const PolicyService = { if (policy) { throw Error(`This Policy name:${ctx.name} and sourceId:${ctx.sourceId} already inserted to database!`) } else { - const newPolicy = await Policy.create({ + return await Policy.create({ name: ctx.name, // source_id: ctx.sourceId, user_id: user.id, is_default: false }) - - return newPolicy } } else { throw Error('The user account could not found.') @@ -46,7 +43,6 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - const { policyId, stdFieldId } = ctx if (policyId && stdFieldId) { @@ -56,16 +52,13 @@ const PolicyService = { std_field_id: stdFieldId, } }) - if (policyField) { throw Error(`This policyId:${policyId} and stdFieldId:${stdFieldId} already assigned to each other in the database!`) } else { - const newPolicyField = await PolicyField.create({ + return await PolicyField.create({ policy_id: policyId, std_field_id: stdFieldId, }) - - return newPolicyField } } }, @@ -74,7 +67,6 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - const { policyId, sourceId } = ctx if (policyId && sourceId) { @@ -87,11 +79,10 @@ const PolicyService = { if (policySource) { throw Error(`This policyId:${policyId} and sourceId:${sourceId} already assigned to each other in the database!`) } else { - const newPolicySource = await PolicySource.create({ + return await PolicySource.create({ policy_id: policyId, source_id: sourceId, }) - return newPolicySource } } }, @@ -100,38 +91,31 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - - const policySource = await PolicySource.update({ + return await PolicySource.update({ source_id: ctx.sourceId, }, { where: { id: ctx.id } }) - - return policySource }, async deletePolicySource(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const policySource = await PolicySource.destroyi({ + return await PolicySource.destroyi({ where: { id: ctx.id } }) - - return policySource }, async updatePolicy(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const policy = await Policy.update({ + return await Policy.update({ name: ctx.name, source_id: ctx.sourceId, is_default: ctx.isDeafault @@ -140,16 +124,13 @@ const PolicyService = { id: ctx.id, } }) - return policy - }, async updatePolicyField(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const policyField = await PolicyField.update({ + return await PolicyField.update({ policy_id: ctx.policyId, std_field_id: ctx.stdFieldId, }, { @@ -157,46 +138,37 @@ const PolicyService = { id: ctx.id } }) - - return policyField }, async deletePolicyField(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const policyField = await PolicyField.destroy({ + return await PolicyField.destroy({ where: { id: ctx.id } }) - - return policyField }, async deletePolicy(ctx) { if (!ctx) { throw Error("The request body is empty!") } - const policyField = await PolicyField.destroy({ where: { policy_id: ctx.id } }) - - const policy = await Policy.destroy({ + await Policy.destroy({ where: { id: ctx.id } }) - return policyField }, - async policies(ctx) { - + async policies() { return await Policy.findAll({}) }, @@ -204,25 +176,19 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - try { - const params = { userId: ctx.kcId } - const policiesByUser = await db.raw( `select DISTINCT p.id, p.name, p.user_id, p.source_id, u.kc_id from policies p inner join users u on p.user_id = u.id where u.kc_id = :userId`, params) - return policiesByUser.rows - } catch (error) { throw new Error(error) } }, - async policyFields(ctx) { - + async policyFields() { return await PolicyField.findAll({}) }, @@ -230,9 +196,7 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - const params = { policyId: ctx.policyId } - const assignedPolicies = await db.raw(` select pf.id, sf.field_name, sf.definition_and_comment, sf.field_type, sf.values from policies p inner join policy_fields pf on p.id = pf.policy_id @@ -241,7 +205,6 @@ const PolicyService = { inner join sources s on ps.source_id = s.id where p.id = :policyId `, params) - return assignedPolicies.rows }, @@ -255,7 +218,6 @@ const PolicyService = { left join policy_sources ps on p.id = ps.policy_id left join sources s on ps.source_id = s.id `) - return policiesWIthSource.rows }, @@ -263,21 +225,15 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - try { - const params = { userId: ctx.kcId } - const policiesByUser = await db.raw(` select p.id, p.name as policyName, s.name as sourceName, p.user_id, p.source_id, u.kc_id from policies p inner join users u on p.user_id = u.id left join policy_sources ps on p.id = ps.policy_id left join sources s on ps.source_id = s.id where u.kc_id = :userId`, params) - - return policiesByUser.rows - } catch (error) { throw new Error(error) } @@ -287,7 +243,6 @@ const PolicyService = { if (!ctx) { throw Error("The request body is empty!") } - const params = { policyId: ctx.policyId } const groupDetailsByPolicy = await db.raw(` select p.id as policyId, g.id as groupId, gp.id groupPolicyId, g.name as group_name, g.description as group_description, s.name as source_name, s.description as source_description from policies p @@ -297,7 +252,6 @@ const PolicyService = { left join sources s on ps.source_id = s.id where p.id = :policyId `, params) - return groupDetailsByPolicy.rows } @@ -322,4 +276,4 @@ module.exports = { getPoliciesWithSources: PolicyService.getPoliciesWithSources, getPoliciesWithSourcesByUser: PolicyService.getPoliciesWithSourcesByUser, getGroupDetailsByPolicy: PolicyService.getGroupDetailsByPolicy, -} \ No newline at end of file +} diff --git a/app/dal/realmService.js b/app/dal/realmService.js index 1b30495..c311b95 100644 --- a/app/dal/realmService.js +++ b/app/dal/realmService.js @@ -1,37 +1,30 @@ 'use strict' - const db = require('../../db'); const RealmService = { - async create(ctx) { - const realm = await db('realm').insert({ + return await db('realm').insert({ name: ctx.name }).returning('*').then((result) => result[0]) - return realm }, async update(ctx) { - const realm = await db('realm').where('id', ctx.id).update({ + return db('realm').where('id', ctx.id).update({ name: ctx.name - }) - return realm + }); }, async delete(ctx) { - const result = await db.delete().from('realm').where('id', ctx.id).timeout(1000, { cancel: true }) - return result + return db.delete().from('realm').where('id', ctx.id).timeout(1000, {cancel: true}); }, async realm(ctx) { - const realm = await db.select().from('realm').where('id', ctx.id).timeout(1000, { cancel: true }); - return realm + return db.select().from('realm').where('id', ctx.id).timeout(1000, {cancel: true}); }, - async realms(ctx) { - const realms = await db.select().from('realm').timeout(1000, { cancel: true }); - return realms + async realms() { + return db.select().from('realm').timeout(1000, {cancel: true}); } } @@ -41,4 +34,4 @@ module.exports = { delete: RealmService.delete, realm: RealmService.realm, realms: RealmService.realms -} \ No newline at end of file +} diff --git a/app/dal/roleAllocationService.js b/app/dal/roleAllocationService.js index 3454077..acf784e 100644 --- a/app/dal/roleAllocationService.js +++ b/app/dal/roleAllocationService.js @@ -2,8 +2,7 @@ const db = require('../../db') - -const { Role, RoleUser } = require('../models/Role') +const { RoleUser } = require('../models/Role') const RoleAllocationService = { @@ -12,13 +11,11 @@ const RoleAllocationService = { if (!ctx) { throw Error("The request body is empty!") } - const roleUser = RoleUser.findOne({ where: { kc_id: ctx.kc_id } }) - if (!roleUser) { return await RoleUser.create({ role_id: ctx.role_id, @@ -35,16 +32,14 @@ const RoleAllocationService = { // It updates allocated user. async update(ctx) { - const result = await db('roles_users').where('id', ctx.id) + return await db('roles_users').where('id', ctx.id) .update({ kc_id: ctx.kc_id }).returning('*').then((result) => result[0]) - return result }, async delete(ctx) { - const result = await db.delete().from('roles_users').where('id', ctx.id).timeout(1000, { cancel: true }) - return result + return db.delete().from('roles_users').where('id', ctx.id).timeout(1000, {cancel: true}); }, // It returns allocated roles by kc_id. @@ -54,29 +49,24 @@ const RoleAllocationService = { throw Error("The request body is empty!") } if (ctx.kc_id) { - const allocatedRoles = await db.raw(` + return await db.raw(` select roles.id, u.username as user, roles.name as role , roles.description from roles inner join roles_users ru on roles.id = ru.role_id inner join users u on ru.kc_id = u.kc_id where u.kc_id = ?`, [ctx.kc_id]) - - return allocatedRoles } } catch (err) { - throw new Error(error) + throw new Error(err) } }, async allocatedRoles(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const allocatedRoles = await db.raw(` + return db.raw(` select u.username as user,r.name as role from roles r inner join roles_users ru on r.id = ru.role_id - inner join users u on ru.kc_id = u.kc_id`) - - return allocatedRoles + inner join users u on ru.kc_id = u.kc_id`); }, } @@ -85,4 +75,4 @@ module.exports = { allocatedRoles: RoleAllocationService.allocatedRolesByKcId, update: RoleAllocationService.update, delete: RoleAllocationService.delete -} \ No newline at end of file +} diff --git a/app/dal/roleService.js b/app/dal/roleService.js index 8164194..036c97e 100644 --- a/app/dal/roleService.js +++ b/app/dal/roleService.js @@ -4,62 +4,54 @@ const db = require('../../db') const { Role, RoleUser } = require('../models/Role') const RoleService = { - // Get all roles async roles(ctx) { - const roles = await db.select().from('roles').timeout(1000, { cancel: true }) - return roles + return db.select().from('roles').timeout(1000, {cancel: true}); }, + // Get a role - async role(ctx) { - const role = await db.select().from('roles').where('id', ctx.id).timeout(1000, { cancel: true }) - return role + role: async function (ctx) { + return db.select().from('roles').where('id', ctx.id).timeout(1000, {cancel: true}); }, + // Delete role by id async delete(ctx) { - const result = await db.delete().from('roles').where('id', ctx.id).timeout(1000, { cancel: true }) - return result + return db.delete().from('roles').where('id', ctx.id).timeout(1000, {cancel: true}) }, + // Update role by id async update(ctx) { - const result = await db('roles').where('id', ctx.id) + return await db('roles').where('id', ctx.id) .update({ name: ctx.name, description: ctx.description }).returning('*').then((result) => result[0]) - return result }, + // Create a role async create(ctx) { - const role = await db('roles').insert({ + return await db('roles').insert({ name: ctx.name, description: ctx.description }).returning('*').then((result) => result[0]) - - return role }, + // Delete a role async deleteRole(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - console.log(ctx) - - const roleUser = await RoleUser.destroy({ + await RoleUser.destroy({ where: { role_id: ctx.id } }) - - const role = await Role.destroy({ + return await Role.destroy({ where: { id: ctx.id } }) - - return role - }, + }, } module.exports = { @@ -68,4 +60,4 @@ module.exports = { role: RoleService.role, delete: RoleService.deleteRole, update: RoleService.update, -} \ No newline at end of file +} diff --git a/app/dal/searchHistoryService.js b/app/dal/searchHistoryService.js index 2d5a291..e3f1b0e 100644 --- a/app/dal/searchHistoryService.js +++ b/app/dal/searchHistoryService.js @@ -5,27 +5,22 @@ const userService = require("./userService"); const { SearchHistory } = require('../models/UserHistory'); const SearchHistoryService = { - async create(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") - + } const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - const result = await SearchHistory.create({ + return await SearchHistory.create({ kc_id: user.kc_id, query: ctx.query, name: ctx.name, ui_structure: ctx.uiStructure, description: ctx.description }) - - return result } else { throw Error('The user account could not found.') } @@ -35,21 +30,16 @@ const SearchHistoryService = { if (!ctx) { throw Error("The request body is empty!") } - - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") - + } const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - - const histories = await SearchHistory.findAll({ + return await SearchHistory.findAll({ where: { kc_id: user.kc_id } }) - - return histories } }, @@ -57,9 +47,9 @@ const SearchHistoryService = { if (!ctx) { throw Error("The request body is empty!") } - - if (ctx.kc_id === undefined) + if (ctx.kc_id === undefined) { throw Error("kcId did not supported.") + } }, async delete(ctx) { @@ -67,20 +57,17 @@ const SearchHistoryService = { throw Error("The request body is empty!") } - const result = await SearchHistory.destroy({ + return await SearchHistory.destroy({ where: { id: ctx.id } - }) - - return result; + }); } } - module.exports = { create: SearchHistoryService.create, update: SearchHistoryService.update, delete: SearchHistoryService.delete, fetch: SearchHistoryService.getSearchHistories -} \ No newline at end of file +} diff --git a/app/dal/userRequestService.js b/app/dal/userRequestService.js index b430bae..9e7518c 100644 --- a/app/dal/userRequestService.js +++ b/app/dal/userRequestService.js @@ -7,32 +7,26 @@ const { UserRequest } = require('../models/UserRequest'); const db = require('../../db'); const UserRequestService = { - async create(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") - + } const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - const result = await UserRequest.create({ + return await UserRequest.create({ user_id: user.id, request_message: ctx.message, is_processed: false, }) - - return result } else { throw Error('The user account could not found.') } }, - async getAllRequests(ctx) { - + async getAllRequests() { return await UserRequest.findAll({}) }, @@ -40,23 +34,12 @@ const UserRequestService = { if (!ctx) { throw Error("The request body is empty!") } - - if (ctx.kcId === undefined) + if (ctx.kcId === undefined) { throw Error("kcId did not supported.") - + } const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - - - const requests = await db.select("*").from('user_requests').where('user_id', user.id).timeout(1000, { cancel: true }) - // const requests = await UserRequest.find({ - // where: { - // user_id: user.id - // } - // }) - - return requests + return db.select("*").from('user_requests').where('user_id', user.id).timeout(1000, {cancel: true}); } }, @@ -64,45 +47,36 @@ const UserRequestService = { if (!ctx) { throw Error("The request body is empty!") } - console.log("hey") - const requests = await UserRequest.findAll({ + return await UserRequest.findAll({ where: { is_processed: false } }) - - return requests }, async update(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const group = await UserRequest.update({ + return await UserRequest.update({ is_processed: true, }, { - where: { id: ctx.id } + where: {id: ctx.id} }) - return result }, async delete(ctx) { if (!ctx) { throw Error("The request body is empty!") } - - const result = await UserRequest.destroy({ + return await UserRequest.destroy({ where: { id: ctx.id } - }) - - return result; + }); } } - module.exports = { create: UserRequestService.create, process: UserRequestService.update, @@ -110,4 +84,4 @@ module.exports = { fetch: UserRequestService.getAllRequests, fetchPending: UserRequestService.getPendingRequests, fetchByUser: UserRequestService.getUserRequests -} \ No newline at end of file +} diff --git a/app/dal/userService.js b/app/dal/userService.js index e03b4ce..5741920 100644 --- a/app/dal/userService.js +++ b/app/dal/userService.js @@ -4,7 +4,7 @@ const KcAdminClient = require("keycloak-admin").default const { Issuer } = require("openid-client") const db = require('../../db') const { User } = require('../models/User') -const { Role, RoleUser } = require('../models/Role') +const { RoleUser } = require('../models/Role') const { postgresSeq } = require('../config/db') const { BotService, MailService } = require('@in-sylva/common') const { Op } = require("sequelize"); @@ -80,7 +80,6 @@ const UserService = { const password = await generatePassword(10); const salt = bcrypt.genSaltSync() const hashedPassword = bcrypt.hashSync(password, salt) - console.log("generated password: " + password); // Update user in insylva db. const [updatedRows, _] = await User.update({ password: hashedPassword, @@ -124,10 +123,9 @@ const UserService = { async users(ctx) { try { await auth() - const users = await keycloakAdmin.users.find({ + return await keycloakAdmin.users.find({ realm: process.env.KEYCLOAK_REALM }) - return users } catch (err) { ctx.status = err.status || 500 @@ -163,7 +161,6 @@ const UserService = { firstname: ctx.firstName, lastname: ctx.lastName }).returning('*').then((result) => result[0]) - return user }, @@ -173,18 +170,14 @@ const UserService = { if (!ctx) { throw Error("The request body is empty!") } - await auth() - const userId = ctx.userId - if (userId) { const deleted = await User.destroy({ where: { kc_id: userId } }) - if (deleted) { return await keycloakAdmin.users.del({ id: userId, @@ -198,6 +191,7 @@ const UserService = { throw Error(error) } }, + // GET single user async user(ctx) { try { @@ -240,10 +234,8 @@ const UserService = { if (!ctx) { throw Error("The request body is empty!") } - const user = await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, { cancel: true }).then((result) => result[0]) - return user - // To-do - // Return user details such as roles and policies + return await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, {cancel: true}).then((result) => result[0]) + // TODO return user details such as roles and policies } catch (error) { ctx.status = error.status || 500 ctx.body = error.message @@ -267,11 +259,13 @@ const UserService = { ] } }) - if (checkUser.count > 0) + if (checkUser.count > 0) { return { user: null, status: 409, message: `"${ctx.email}" or "${ctx.username}" already exist, please try again with different credentials.` } - const roleId = (ctx.roleId == 0 || ctx.roleId == undefined) ? 3 : ctx.roleId - if (!!roleId && roleId == 0) + } + const roleId = (ctx.roleId === 0 || ctx.roleId === undefined) ? 3 : ctx.roleId + if (!!roleId && roleId === 0) { throw Error("The roleId is empty!") + } // Insert this new user into insylva db. const newUser = await User.create({ username: ctx.username, @@ -312,7 +306,6 @@ const UserService = { kc_id: kcUser.id }) } - } } else { await t.rollback() @@ -320,7 +313,7 @@ const UserService = { await t.commit() const date = new Date().toLocaleDateString() const message = `[INFO]:[User ${ctx.username} is created with this email address: ${ctx.email} successfully.]:[${date}]` - const subject = "In-Sylva New User Added" + const subject = "In-Sylva new user added" await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, process.env.IN_SYLVA_EMAIL_TO, subject, "", message) await botService.message(message) return { user: newUser, status: 201 } @@ -353,33 +346,27 @@ const UserService = { }, - async getAssignedUserByRole(ctx) { try { if (!ctx) { throw Error("The request body is empty!") } - const params = { roleId: ctx.id } - const assignedUserByRole = await db.raw(` select u.username as username,u.email as useremail, r.name as rolename from roles r inner join roles_users ru on r.id = ru.role_id inner join users u on ru.kc_id = u.kc_id where r.id = :roleId `, params) - return assignedUserByRole.rows - } catch (error) { throw new Error(error) } }, - async createSystemUser(ctx) { + async createSystemUser() { try { await auth() - const checkUser = await User.findAndCountAll({ where: { [Op.or]: [ @@ -389,8 +376,9 @@ const UserService = { } }) - if (checkUser.count) + if (checkUser.count) { return { user: null, status: 409 } + } // Insert new user into keycloak db const kc_user = await keycloakAdmin.users.create({ @@ -420,7 +408,6 @@ const UserService = { password: process.env.IN_SYLVA_ADMIN_PASSWORD }) - await RoleUser.create({ role_id: 1, kc_id: kc_user.id @@ -432,9 +419,8 @@ const UserService = { } }, - async usersWithGroupAndRole(ctx) { + async usersWithGroupAndRole() { try { - const usersWithGroupsAndRole = await db.raw( `select DISTINCT u.id, u.kc_id, u.username, u.email, g.name as groupName, g.description as groupDescription, r.name as roleName, r.description as roleDescription from users u @@ -442,9 +428,7 @@ const UserService = { inner join roles r on ru.role_id = r.id left join group_users gu on u.id = gu.user_id left join groups g on g.id = gu.group_id`) - return usersWithGroupsAndRole.rows - } catch (error) { throw new Error(error) } @@ -452,9 +436,7 @@ const UserService = { async userWithGroupAndRole(ctx) { try { - const params = { userId: ctx.id } - const userWithGroupAndRole = await db.raw( `select DISTINCT u.id, u.kc_id, u.username, u.email, g.id as groupId, g.name as groupName, g.description as groupDescription, r.name as roleName, r.id as roleId, r.description as roleDescription from users u @@ -463,14 +445,11 @@ const UserService = { left join group_users gu on u.id = gu.user_id left join groups g on g.id = gu.group_id where u.kc_id = :userId`, params) - return userWithGroupAndRole.rows - } catch (error) { throw new Error(error) } } - } module.exports = { diff --git a/app/models/Group.js b/app/models/Group.js index 5966c10..00c3764 100644 --- a/app/models/Group.js +++ b/app/models/Group.js @@ -1,4 +1,5 @@ 'use strict' + const { postgresSeq } = require('../config/db') const Sequelize = require('sequelize') const { Policy } = require('./Policy') @@ -26,7 +27,6 @@ Group.init({ modelName: "groups" }) - GroupsPolicy.init({ group_id: { type: Sequelize.INTEGER, allowNull: false, @@ -73,44 +73,8 @@ GroupUser.init({ modelName: "group_users" }) -// Group.belongsTo(Policy, { through: GroupsPolicy, uniqueKey: "group_policy_group_id_fkey" }) -// Policy.belongsTo(Group, { through: GroupsPolicy, uniqueKey: "group_policy_policy_id_fkey" }) - -// User.belongsTo(Group, { through: GroupUser, uniqueKey: "group_user_group_id_fkey" }) -// Group.belongsTo(User, { through: GroupUser, uniqueKey: "group_user_user_id_fkey" }) - -/* -Group.hasMany(GroupsPolicy) -Policy.hasMany(GroupsPolicy) -Group.hasMany(GroupUser) -User.hasMany(GroupUser) - -GroupsPolicy.belongsToMany(Group, { - foreignKey: { - name: "group_policy_group_id_fkey" - } -}) - -GroupsPolicy.belongsToMany(Policy, { - foreignKey: { - name: "group_policy_policy_id_fkey" - } -}) - -GroupUser.belongsToMany(Group, { - foreignKey: { - name: "group_user_group_id_fkey" - } -}) - -GroupUser.belongsTo(User, { - foreignKey: { - name: "group_user_user_id_fkey" - } -}) */ - module.exports = { Group, GroupsPolicy, GroupUser, -} \ No newline at end of file +} diff --git a/app/models/Policy.js b/app/models/Policy.js index 8c4c47e..5f79304 100644 --- a/app/models/Policy.js +++ b/app/models/Policy.js @@ -71,7 +71,7 @@ PolicyField.init( sequelize: postgresSeq, modelName: "policy_fields", }) - + PolicySource.init({ policy_id: { type: Sequelize.INTEGER, @@ -114,7 +114,7 @@ Policy.belongsToMany(StdField, { Policy.belongsToMany(Source, { through: PolicyField, uniqueKey: "policy_source_id_fkey", -}); +}); StdField.belongsToMany(Policy, { through: PolicyField, @@ -132,44 +132,6 @@ UserProfile.init( modelName: "user_profile", } ); -/* -Policy.belongsToMany(StdField, { - through: PolicyField, - uniqueKey: "policy_field_policy_id_fkey", -}); - -Policy.belongsToMany(Source, { - through: PolicyField, - uniqueKey: "policy_source_id_fkey", -}); - -StdField.belongsToMany(Policy, { - through: PolicyField, - uniqueKey: "std_fields_id_fkkey", -});*/ - -/* -Policy.hasMany(PolicyField) -Source.hasMany(PolicyField) -StdField.hasMany(PolicyField) - -PolicyField.belongsToMany(Policy, { - foreignKey: { - name: "policy_field_policy_id_fkey" - } -}) - -PolicyField.belongsToMany(Source, { - foreignKey: { - name: "policy_field_source_id_fkey" - } -}) - -PolicyField.hasMany(StdField, { - foreignKey: { - name: "std_fields_id_fkkey" - } -}) */ module.exports = { Policy, diff --git a/app/models/Role.js b/app/models/Role.js index 3d8ebfd..0c2a95e 100644 --- a/app/models/Role.js +++ b/app/models/Role.js @@ -41,24 +41,6 @@ RoleUser.init({ modelName: "roles_users" }) -// Role.belongsTo(User, { through: RoleUser, uniqueKey: "roles_users_role_id_fkey" }) -// User.belongsTo(Role, { through: RoleUser, uniqueKey: "roles_users_kc_id_fkey" }) -/* -Role.hasMany(RoleUser) -User.hasMany(Role) - -RoleUser.belongsToMany(Role, { - foreignKey: { - name: "roles_users_role_id_fkey" - } -}) -RoleUser.hasMany(User, { - foreignKey: { - name: "roles_users_kc_id_fkey" - } -}) */ - - module.exports = { Role, RoleUser diff --git a/app/models/StdField.js b/app/models/StdField.js index 7173782..5ae463c 100644 --- a/app/models/StdField.js +++ b/app/models/StdField.js @@ -3,7 +3,6 @@ const { postgresSeq } = require('../config/db') const Sequelize = require('sequelize') - class StdField extends Sequelize.Model { } StdField.init({ @@ -33,9 +32,3 @@ StdField.init({ module.exports = { StdField } - - - - - - diff --git a/app/models/User.js b/app/models/User.js index 364e98e..14f18e3 100644 --- a/app/models/User.js +++ b/app/models/User.js @@ -27,14 +27,11 @@ User.init({ } }) - User.beforeCreate(async (user, options) => { const salt = bcrypt.genSaltSync() user.password = bcrypt.hashSync(user.password, salt) }) - - module.exports = { User -} \ No newline at end of file +} diff --git a/app/utils/format.js b/app/utils/format.js index 9e60ff7..118da74 100644 --- a/app/utils/format.js +++ b/app/utils/format.js @@ -4,7 +4,6 @@ const { createLogger, format, transports } = require('winston'); const { combine, timestamp, printf, colorize, splat, label } = format; const path = require('path'); - const mFormat = printf((info) => { if (info.meta && info.meta instanceof Error) { return `${info.timestamp} ${info.level} ${info.message} : ${info.meta.stack}`; @@ -12,12 +11,11 @@ const mFormat = printf((info) => { return `${info.timestamp} ${info.level} [${info.label}]: ${info.message}`; }); -const LOG_LEVEL = process.env.LOG_LEVEL || 'debug'; const logger = createLogger({ transports: [ new (transports.Console)( { - level: LOG_LEVEL, + level: process.env.LOG_LEVEL || 'debug', format: combine( label({ label: path.basename(process.mainModule.filename) }), colorize(), diff --git a/app/utils/hashPass.js b/app/utils/hashPass.js deleted file mode 100644 index 80b32c5..0000000 --- a/app/utils/hashPass.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict' - -const bcrypt = require('bcrypt') -const logger = require('winston') - -async function hashPass(valueToHash) { - const rounds = 10 - - try { - const hashedValue = await bcrypt.hash(valueToHash, rounds) - return hashedValue - } catch (err) { - logger.error(err) - throw err - } -} - -module.exports = { - hashPass -} diff --git a/app/utils/memory-store.js b/app/utils/memory-store.js deleted file mode 100644 index b0308ce..0000000 --- a/app/utils/memory-store.js +++ /dev/null @@ -1,29 +0,0 @@ -function MemoryStore () { - this.sessions = Object.create(null); - } - - MemoryStore.prototype.get = function (sessionId) { - var sess = this.sessions[sessionId]; - if (!sess) { - return; - } - sess = JSON.parse(sess); - if (sess.expire && sess.expire <= Date.now()) { - delete this.sessions[sessionId]; - return; - } - return sess; - }; - - MemoryStore.prototype.set = function (sessionId, session, maxAge) { - if (maxAge > 0) { - session.expire = Date.now() + maxAge; - } - this.sessions[sessionId] = JSON.stringify(session); - }; - - MemoryStore.prototype.destroy = function (sessionId) { - delete this.sessions[sessionId]; - }; - - module.exports = MemoryStore; \ No newline at end of file diff --git a/init-keycloak.js b/init-keycloak.js index 7f76922..c0b75b7 100644 --- a/init-keycloak.js +++ b/init-keycloak.js @@ -1,27 +1,13 @@ 'use strict' const KeycloakConnect = require('@in-sylva/keycloak-koa-connect').default -const bodyStore = require('@in-sylva/keycloak-koa-connect/stores/body-store').default // If this option is used, it is legal to include the value of jwt in the body -const queryStore = require('@in-sylva/keycloak-koa-connect/stores/query-store').default // If this option is used, it is also legal to pass a token at http://a.com?jwt=token -// var Keycloak = require('keycloak-connect'); - -// const KeycloakConnect = require('@pixelygroup/keycloak-koa-connect').default -// const bodyStore = require('@pixelygroup/keycloak-koa-connect').default // If this option is used, it is legal to include the value of jwt in the body -// const queryStore = require('@pixelygroup/keycloak-koa-connect').default // If this option is used, it is also legal to pass a token at http://a.com?jwt=token - const config = require('./keycloak.js') -const keycloak = new KeycloakConnect({ store: [queryStore, bodyStore]}, config) - -/* -var keycloak = new Keycloak({ - store: true - }, { - clientId: config.resource, - serverUrl: config["auth-server-url"], - realm: config.realm, - bearerOnly: true - }); */ +// If this option is used, it is legal to include the value of jwt in the body +const bodyStore = require('@in-sylva/keycloak-koa-connect/stores/body-store').default +// If this option is used, it is also legal to pass a token at http://a.com?jwt=token +const queryStore = require('@in-sylva/keycloak-koa-connect/stores/query-store').default +const keycloak = new KeycloakConnect({ store: [queryStore, bodyStore]}, config) -module.exports = { keycloak } \ No newline at end of file +module.exports = { keycloak } diff --git a/keycloak.js b/keycloak.js index dcfe832..2724de9 100644 --- a/keycloak.js +++ b/keycloak.js @@ -1,5 +1,4 @@ module.exports = { - 'realm': process.env.KEYCLOAK_REALM, 'auth-server-url': process.env.KEYCLOAK_SERVER_URL, "ssl-required": "none", @@ -13,9 +12,4 @@ module.exports = { 'bearer-only':true, 'use-resource-role-mappings': true, 'realm-public-key': `${process.env.KEYCLOAK_SERVER_PUBLIC_KEY}` - /* - 'ssl-required':'external', - "public-client": true, - 'confidential-port': 0, - 'realm-public-key': `${process.env.KEYCLOAK_SERVER_PUBLIC_KEY}`*/ -} \ No newline at end of file +} diff --git a/server.js b/server.js index 6f9d0ec..b41eca1 100644 --- a/server.js +++ b/server.js @@ -6,10 +6,6 @@ const api = require('./app/api') const koaLogger = require('koa-logger') const cors = require('koa2-cors') const { keycloak } = require('./init-keycloak'); -let session = require('koa-session'); -let MemoryStore = require('./app/utils/memory-store') - -let store = new MemoryStore(); async function responseTime(ctx, next) { const start = Date.now(); @@ -32,27 +28,18 @@ middlewares.forEach(function (middleware) { app.use(middleware); }) - app .use(cors({ origin: '*' })) - /*.use(session({ - key: 'koa:sess', - maxAge: 86400000, - renew: false, - store: store, - signed: false - }, app))*/ .use(koaLogger()) .use(function (ctx, next) { return next().catch((err) => { if (err) { + // Protected resource, use Authorization header to get access\n console.log(err) ctx.status = 401 - ctx.body = err //'Protected resource, use Authorization header to get access\n' - } else { - /* */ + ctx.body = err } }) }) @@ -65,4 +52,4 @@ app.on('error', (err) => { throw err }) -module.exports = app \ No newline at end of file +module.exports = app -- GitLab From 6dfeca85e9fda18552397a8b1362999973d82943 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Fri, 15 Nov 2024 15:28:42 +0100 Subject: [PATCH 03/13] added new routes, handlers and services for user fields display settings --- app/api/index.js | 155 +++++++++--------- .../user-fields-display-settings/delete.js | 25 +++ app/api/user-fields-display-settings/get.js | 37 +++++ app/api/user-fields-display-settings/index.js | 16 ++ app/api/user-fields-display-settings/post.js | 24 +++ app/api/user-fields-display-settings/put.js | 24 +++ app/dal/groupService.js | 92 +++++------ app/dal/userFieldsDisplaySettingsService.js | 139 ++++++++++++++++ app/models/UserFieldsDisplaySettings.js | 48 ++++++ 9 files changed, 433 insertions(+), 127 deletions(-) create mode 100644 app/api/user-fields-display-settings/delete.js create mode 100644 app/api/user-fields-display-settings/get.js create mode 100644 app/api/user-fields-display-settings/index.js create mode 100644 app/api/user-fields-display-settings/post.js create mode 100644 app/api/user-fields-display-settings/put.js create mode 100644 app/dal/userFieldsDisplaySettingsService.js create mode 100644 app/models/UserFieldsDisplaySettings.js diff --git a/app/api/index.js b/app/api/index.js index acc378f..e93fb17 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -1,97 +1,106 @@ 'use strict' -const Router = require("koa-router") -const bodyParser = require("koa-bodyparser") +const Router = require("koa-router"); +const bodyParser = require("koa-bodyparser"); /* const { keycloak } = require('../../init-keycloak') */ -// handlers -const userHandler = require('./users') -const roleHandler = require('./roles') -const allocationRoleHandler = require('./role-user') -const searchHistoryHandler = require('./user-search-history') -const userRequestHandler = require('./user-requests') -const groupHandler = require('./group') -const policyHandler = require('./policy') +// Handlers +const userHandler = require('./users'); +const roleHandler = require('./roles'); +const allocationRoleHandler = require('./role-user'); +const searchHistoryHandler = require('./user-search-history'); +const userRequestHandler = require('./user-requests'); +const groupHandler = require('./group'); +const policyHandler = require('./policy'); +const UserFieldsDisplaySettingsHandler = require("./user-fields-display-settings"); -const routers = new Router() +const routers = new Router(); + +routers.use(bodyParser()); -routers.use(bodyParser()) routers.get('/healthcheck', (ctx) => { - ctx.res.statusCode = 200 - ctx.res.end('OK') -}) + ctx.res.statusCode = 200; + ctx.res.end('OK'); +}); // Users -routers.post('/user', userHandler.addNewUser) -routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user) -routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users) -routers.delete('/user/delete',/* keycloak.protect(),*/ userHandler.deleteUser) -routers.put('/user/update',/* keycloak.protect(),*/ userHandler.update) -routers.post('/user/kcid', /* keycloak.protect(),*/ userHandler.kcId) -routers.post('/user/detail', /* keycloak.protect(),*/ userHandler.detail) -routers.post('/user/assigned-by-role', userHandler.getAssignedUserByRole) -routers.post('/user/send-mail', userHandler.sendMail) -routers.post('/user/reset-password', userHandler.resetPassword) +routers.post('/user', userHandler.addNewUser); +routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user); +routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users); +routers.delete('/user/delete',/* keycloak.protect(),*/ userHandler.deleteUser); +routers.put('/user/update',/* keycloak.protect(),*/ userHandler.update); +routers.post('/user/kcid', /* keycloak.protect(),*/ userHandler.kcId); +routers.post('/user/detail', /* keycloak.protect(),*/ userHandler.detail); +routers.post('/user/assigned-by-role', userHandler.getAssignedUserByRole); +routers.post('/user/send-mail', userHandler.sendMail); +routers.post('/user/reset-password', userHandler.resetPassword); // System admin user -routers.post('/user/create-system-user', userHandler.createSystemUser) -routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole) -routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole) +routers.post('/user/create-system-user', userHandler.createSystemUser); +routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole); +routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole); // Search history -routers.post('/user/add-history', searchHistoryHandler.add) -routers.post('/user/fetch-history', searchHistoryHandler.fetch) -routers.delete('/user/delete-history', searchHistoryHandler.deleteH) +routers.post('/user/add-history', searchHistoryHandler.add); +routers.post('/user/fetch-history', searchHistoryHandler.fetch); +routers.delete('/user/delete-history', searchHistoryHandler.deleteH); + +// User fields display settings +routers.post('/user/fields-display-settings/', /* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.createUserFieldsDisplaySettings); +routers.get('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUsersFieldsDisplaySettings); +routers.get('/user/fields-display-settings/:userId',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUserFieldsDisplaySettings); +routers.put('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.updateUserFieldsDisplaySettings); +routers.delete('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.deleteUserFieldsDisplaySettings); // User requests -routers.post('/user/create-request', userRequestHandler.createRequest) -routers.delete('/user/delete-request', userRequestHandler.deleteRequest) -routers.post('/user/process-request', userRequestHandler.processRequest) -routers.get('/user/list-requests', userRequestHandler.fetchRequests) -routers.post('/user/list-requests-by-user', userRequestHandler.fetchRequestsByUser) -routers.get('/user/list-pending-requests', userRequestHandler.fetchPendingRequests) +routers.post('/user/create-request', userRequestHandler.createRequest); +routers.delete('/user/delete-request', userRequestHandler.deleteRequest); +routers.post('/user/process-request', userRequestHandler.processRequest); +routers.get('/user/list-requests', userRequestHandler.fetchRequests); +routers.post('/user/list-requests-by-user', userRequestHandler.fetchRequestsByUser); +routers.get('/user/list-pending-requests', userRequestHandler.fetchPendingRequests); // Groups -routers.post('/user/groups', groupHandler.groups) -routers.post('/user/group-policies', groupHandler.groupPolicies) -routers.post('/user/group-users', groupHandler.groupUsers) -routers.post('/user/add-group', groupHandler.createGroup) -routers.post('/user/add-group-policy', groupHandler.createGroupPolicy) -routers.post('/user/add-group-user', groupHandler.createGroupUser) -routers.put('/user/update-group', groupHandler.updateGroup) -routers.put('/user/update-group-policy', groupHandler.updateGroupPolicy) -routers.put('/user/update-group-user', groupHandler.updateGroupUser) -routers.delete('/user/delete-group', groupHandler.deleteGroup) -routers.delete('/user/delete-group-policy', groupHandler.deleteGroupPolicy) -routers.delete('/user/delete-group-user', groupHandler.deleteGroupUser) +routers.post('/user/groups', groupHandler.groups); +routers.post('/user/group-policies', groupHandler.groupPolicies); +routers.post('/user/group-users', groupHandler.groupUsers); +routers.post('/user/add-group', groupHandler.createGroup); +routers.post('/user/add-group-policy', groupHandler.createGroupPolicy); +routers.post('/user/add-group-user', groupHandler.createGroupUser); +routers.put('/user/update-group', groupHandler.updateGroup); +routers.put('/user/update-group-policy', groupHandler.updateGroupPolicy); +routers.put('/user/update-group-user', groupHandler.updateGroupUser); +routers.delete('/user/delete-group', groupHandler.deleteGroup); +routers.delete('/user/delete-group-policy', groupHandler.deleteGroupPolicy); +routers.delete('/user/delete-group-user', groupHandler.deleteGroupUser); // Policies -routers.post('/policy/add', policyHandler.createPolicy) -routers.delete('/policy/delete', policyHandler.deletePolicy) -routers.put('/policy/update', policyHandler.updatePolicy) -routers.get('/policy/list', policyHandler.policies) -routers.post('/policy/list-by-user', policyHandler.policiesByUser) -routers.post('/policy/assigned-fields', policyHandler.assignedPolicies) -routers.get('/policy/policies-with-sources', policyHandler.getPoliciesWithSources) -routers.post('/policy/policies-with-sources-by-user', policyHandler.getPoliciesWithSourcesByUser) -routers.post('/policy/policies-with-groups', policyHandler.getGroupDetailsByPolicy) -routers.post('/policyField/add', policyHandler.createPolicyField) -routers.delete('/policyField/delete', policyHandler.deletePolicyField) -routers.put('/policyField/update', policyHandler.updatePolicyField) -routers.get('/policyField/list', policyHandler.policyFields) -routers.post('/policySource/add', policyHandler.createPolicySource) +routers.post('/policy/add', policyHandler.createPolicy); +routers.delete('/policy/delete', policyHandler.deletePolicy); +routers.put('/policy/update', policyHandler.updatePolicy); +routers.get('/policy/list', policyHandler.policies); +routers.post('/policy/list-by-user', policyHandler.policiesByUser); +routers.post('/policy/assigned-fields', policyHandler.assignedPolicies); +routers.get('/policy/policies-with-sources', policyHandler.getPoliciesWithSources); +routers.post('/policy/policies-with-sources-by-user', policyHandler.getPoliciesWithSourcesByUser); +routers.post('/policy/policies-with-groups', policyHandler.getGroupDetailsByPolicy); +routers.post('/policyField/add', policyHandler.createPolicyField); +routers.delete('/policyField/delete', policyHandler.deletePolicyField); +routers.put('/policyField/update', policyHandler.updatePolicyField); +routers.get('/policyField/list', policyHandler.policyFields); +routers.post('/policySource/add', policyHandler.createPolicySource); // Roles -routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole) -routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles) -routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role) -routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole) -routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update) +routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole); +routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles); +routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role); +routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole); +routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update); // Role allocation to users -routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole) -routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles) -routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update) -routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole) +routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole); +routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles); +routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update); +routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole); -module.exports = routers +module.exports = routers; diff --git a/app/api/user-fields-display-settings/delete.js b/app/api/user-fields-display-settings/delete.js new file mode 100644 index 0000000..f1ec286 --- /dev/null +++ b/app/api/user-fields-display-settings/delete.js @@ -0,0 +1,25 @@ +'use strict' + +const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); +const logger = require('../../utils/format'); +const util = require('util'); +const {updateUserFieldsDisplaySettings} = require("./put"); + +const UserFieldsDisplaySettings = { + async delete(ctx) { + try { + ctx.body = await userFieldsDisplaySettingsService.delete(ctx.request.body); + ctx.status = 201; + logger.info('User fields display settings deleted.'); + } catch (err) { + ctx.body = err || 'An error occurred.'; + ctx.status = 500; + logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } + } +} + +module.exports = { + deleteUserFieldsDisplaySettings: UserFieldsDisplaySettings.delete, + UserFieldsDisplaySettings +}; diff --git a/app/api/user-fields-display-settings/get.js b/app/api/user-fields-display-settings/get.js new file mode 100644 index 0000000..18e04bb --- /dev/null +++ b/app/api/user-fields-display-settings/get.js @@ -0,0 +1,37 @@ +"use strict"; + +const logger = require('../../utils/format') +const util = require('util') +const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); + +const GetUserFieldsDisplaySettings = { + async find(ctx) { + try { + ctx.body = await userFieldsDisplaySettingsService.usersFieldsDisplaySettings(ctx.request.body); + ctx.status = 201; + logger.info('Users fields display settings retrieved.'); + } catch (err) { + ctx.body = err || 'An error occurred.'; + ctx.status = 500; + logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } + }, + + async findOne(ctx) { + try { + ctx.body = await userFieldsDisplaySettingsService.userFieldsDisplaySettings(ctx.request.body) + ctx.status = 201 + logger.info('User fields display settings retrieved.') + } catch (err) { + ctx.body = err || 'An error occurred.' + ctx.status = 500; + logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + } + }, +}; + +module.exports = { + findUsersFieldsDisplaySettings: GetUserFieldsDisplaySettings.find, + findUserFieldsDisplaySettings: GetUserFieldsDisplaySettings.findOne, + GetUserFieldsDisplaySettings +}; diff --git a/app/api/user-fields-display-settings/index.js b/app/api/user-fields-display-settings/index.js new file mode 100644 index 0000000..338b10b --- /dev/null +++ b/app/api/user-fields-display-settings/index.js @@ -0,0 +1,16 @@ +"use strict"; + +const { createUserFieldsDisplaySettings } = require('./post'); +const { findUsersFieldsDisplaySettings, findUserFieldsDisplaySettings } = require('./get'); +const { updateUserFieldsDisplaySettings } = require('./put'); +const { deleteUserFieldsDisplaySettings } = require('./delete'); + +const UserFieldsDisplaySettingsHandler = { + createUserFieldsDisplaySettings, + findUsersFieldsDisplaySettings, + findUserFieldsDisplaySettings, + updateUserFieldsDisplaySettings, + deleteUserFieldsDisplaySettings +} + +module.exports = UserFieldsDisplaySettingsHandler diff --git a/app/api/user-fields-display-settings/post.js b/app/api/user-fields-display-settings/post.js new file mode 100644 index 0000000..556304c --- /dev/null +++ b/app/api/user-fields-display-settings/post.js @@ -0,0 +1,24 @@ +'use strict' + +const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); +const logger = require('../../utils/format') +const util = require('util') + +const CreateUserFieldsDisplaySettings = { + async create(ctx) { + try { + ctx.body = await userFieldsDisplaySettingsService.create(ctx.request.body); + ctx.status = 201; + logger.info('User fields display settings created.'); + } catch (err) { + ctx.body = err || 'An error occurred.'; + ctx.status = 500; + logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } + }, +} + +module.exports = { + createUserFieldsDisplaySettings: CreateUserFieldsDisplaySettings.create, + CreateUserFieldsDisplaySettings +} diff --git a/app/api/user-fields-display-settings/put.js b/app/api/user-fields-display-settings/put.js new file mode 100644 index 0000000..1e2d7de --- /dev/null +++ b/app/api/user-fields-display-settings/put.js @@ -0,0 +1,24 @@ +'use strict' + +const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); +const logger = require('../../utils/format'); +const util = require('util'); + +const UpdateUserFieldsDisplaySettings = { + async update(ctx) { + try { + ctx.body = await userFieldsDisplaySettingsService.update(ctx.request.body); + ctx.status = 201; + logger.info('User fields display settings updated.'); + } catch (err) { + ctx.body = err || 'An error occurred.'; + ctx.status = 500; + logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } + } +} + +module.exports = { + updateUserFieldsDisplaySettings: UpdateUserFieldsDisplaySettings.update, + UpdateUserFieldsDisplaySettings +}; diff --git a/app/dal/groupService.js b/app/dal/groupService.js index cd141c3..6d27ca6 100644 --- a/app/dal/groupService.js +++ b/app/dal/groupService.js @@ -5,14 +5,12 @@ const userService = require('./userService') const db = require('../../db') const GroupService = { - async createGroup(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") + throw Error("kcId did not supported."); } const user = await userService.detail({ kcId: ctx.kcId }); if (user) { @@ -21,112 +19,103 @@ const GroupService = { name: ctx.name, user_id: user.id, } - }) + }); if (group) { - throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`) + throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`); } else { return await Group.create({ name: ctx.name, description: ctx.description, user_id: user.id, - }) + }); } } else { - throw Error('The user account could not found.') + throw Error('User account not found.'); } }, async createGroupPolicy(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - const groupPolicy = await GroupsPolicy.findOne({ where: { group_id: ctx.groupId, policy_id: ctx.policyId } - }) - + }); if (groupPolicy) { - throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`) + throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`); } else { return await GroupsPolicy.create({ group_id: ctx.groupId, policy_id: ctx.policyId - }) + }); } }, async createGroupUser(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") + throw Error("kcId did not supported."); } - - const user = await userService.detail({ kcId: ctx.kcId }) + const user = await userService.detail({ kcId: ctx.kcId }); if (user) { const groupUser = await GroupUser.findOne({ where: { group_id: ctx.groupId, user_id: user.id } - }) + }); if (groupUser) { - throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`) + throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`); } else { return await GroupUser.create({ group_id: ctx.groupId, user_id: user.id - }) + }); } } else { - throw Error('The user account could not found.') + throw Error('The user account could not found.'); } }, async updateGroup(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - return await Group.update({ name: ctx.name, description: ctx.description, }, { where: {id: ctx.id, user_id: ctx.userId} - }) - + }); }, async updateGroupPolicy(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - return await GroupsPolicy.update({ group_id: ctx.groupId, policy_id: ctx.policyId - }, {where: {id: ctx.id}}) + }, {where: {id: ctx.id}}); }, async updateGroupUser(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - - const user = await userService.detail({ kcId: ctx.kcId }) + const user = await userService.detail({ kcId: ctx.kcId }); if (user) { return await GroupUser.update({ group_id: ctx.groupId, user_id: user.id - }, {where: {id: ctx.id}}) - + }, {where: {id: ctx.id}}); } else { - throw Error('The user account could not found.') + throw Error('The user account could not found.'); } }, @@ -139,58 +128,53 @@ const GroupService = { where: { id: ctx.id } - }) + }); } }, async deleteGroupPolicy(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - return await GroupsPolicy.destroy({ where: { id: ctx.id } - }) + }); }, async deleteGroupUser(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - - const params = { groupId: ctx.groupId, userId: ctx.userId } - + const params = { groupId: ctx.groupId, userId: ctx.userId }; const groupUser = await db.raw(` delete from group_users where group_id = :groupId and user_id = :userId - `, params) - - return groupUser + `, params); + return groupUser; }, async groups() { - return await Group.findAll({}) - + return await Group.findAll({}); }, async groupPolicies() { - return await GroupsPolicy.findAll({}) + return await GroupsPolicy.findAll({}); }, async groupUsers(ctx) { if (!ctx) { - throw Error("The request body is empty!") + throw Error("The request body is empty!"); } - const params = { groupId: ctx.groupId } + const params = { groupId: ctx.groupId }; const groupUsers = await db.raw(` select g.id as groupId, u.id as userId, u.username, g.name, g.description from group_users gu inner join users u on u.id = gu.user_id inner join groups g on gu.group_id = g.id where g.id = :groupId - `, params) - return groupUsers.rows + `, params); + return groupUsers.rows; } } diff --git a/app/dal/userFieldsDisplaySettingsService.js b/app/dal/userFieldsDisplaySettingsService.js new file mode 100644 index 0000000..49ef158 --- /dev/null +++ b/app/dal/userFieldsDisplaySettingsService.js @@ -0,0 +1,139 @@ +"use strict" + +const {UserFieldsDisplaySettings} = require("../models/UserFieldsDisplaySettings"); +const userService = require("./userService"); + +/* + userFieldsDisplaySettingsService + Manage all users fields display settings + Used in search tool for results table columns +*/ +const userFieldsDisplaySettingsService = { + + // POST create fields settings for a specific user + // userId: id of the user + // stdFieldsIds: array of ids of fields selected by user + async create(ctx) { + try { + if (!ctx) { + throw Error("Empty request body."); + } else if (!ctx.userId) { + throw Error("Required parameter userId is missing."); + } else if (!ctx.stdFieldsIds) { + throw Error("Required parameter stdFieldsIds is missing."); + } + // Check if user exists + const user = await userService.user({id: userId}); + console.log(user); + if (!user) { + throw Error("User does not exists."); + } + // Check if all fields ids exists + if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) { + throw new Error("One or more std_field_id do not exists."); + } + // Insert new row in user settings table + const [newUserFieldsSettings, isCreated] = await UserFieldsDisplaySettings.findOrCreate({ + where: { user_id: ctx.userId }, // Unique field(s) to check for existence + defaults: { + std_fields_ids: ctx.stdFieldsIds, + }, + }); + console.log(isCreated); + console.log(newUserFieldsSettings); + if (!isCreated) { + throw new Error("User settings row already exists."); + } + return { userFieldsDisplaySettings: newUserFieldsSettings, status: 201 }; + } catch (error) { + throw new Error(error); + } + }, + + // GET all users fields settings + async usersFieldsDisplaySettings(ctx) { + try { + return await UserFieldsDisplaySettings.findAll({}); + } + catch (err) { + ctx.status = err.status || 500; + ctx.body = err.message; + throw Error(err); + } + }, + + // GET single user settings + // userId: id of the user + async userFieldsDisplaySettings(ctx) { + try { + if (!ctx) { + throw Error("Empty request body."); + } else if (!ctx.userId) { + throw Error("Required parameter userId is missing."); + } + return await UserFieldsDisplaySettings.findOne({ where: { user_id: ctx.userId } }); + } catch (err) { + ctx.status = err.status || 500; + ctx.body = err.message; + throw Error(err); + } + }, + + // PUT update a user settings + // userId: id of the user + // stdFieldsIds: new array of all fields ids + async update(ctx) { + if (!ctx) { + throw Error("Empty request body."); + } else if (!ctx.userId) { + throw Error("Required parameter userId is missing."); + } else if (!ctx.stdFieldsIds) { + throw Error("Required parameter stdFieldsIds is missing."); + } + // Check if user exists + const user = await userService.user({id: userId}); + console.log(user); + if (!user) { + throw Error("User does not exists."); + } + // Check if all fields ids exists + if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) { + throw new Error("One or more std_field_id do not exists."); + } + return await UserFieldsDisplaySettings.update({ + std_fields_ids: ctx.stdFieldsIds, + }, { + where: { + user_id: userId + } + }); + }, + + // DELETE the user settings + async delete(ctx) { + try { + if (!ctx) { + throw Error("Empty request body."); + } else if (!ctx.userId) { + throw Error("Required parameter userId is missing."); + } + return await UserFieldsDisplaySettings.destroy({ + where: { + user_id: userId + } + }); + } catch (error) { + ctx.status = error.status || 500; + ctx.body = error.message; + throw Error(error); + } + }, +} + +module.exports = { + create: userFieldsDisplaySettingsService.create, + usersFieldsDisplaySettings: userFieldsDisplaySettingsService.usersFieldsDisplaySettings, + userFieldsDisplaySettings: userFieldsDisplaySettingsService.userFieldsDisplaySettings, + delete: userFieldsDisplaySettingsService.delete, + update: userFieldsDisplaySettingsService.update, +}; diff --git a/app/models/UserFieldsDisplaySettings.js b/app/models/UserFieldsDisplaySettings.js new file mode 100644 index 0000000..98b7ccb --- /dev/null +++ b/app/models/UserFieldsDisplaySettings.js @@ -0,0 +1,48 @@ +'use strict' + +const { Model, DataTypes, Deferrable} = require('sequelize'); +const { postgresSeq } = require('../config/db'); +const { User } = require('./User'); +const {StdField} = require("./StdField"); + +class UserFieldsDisplaySettings extends Model { } + +UserFieldsDisplaySettings.init({ + user_id: { + type: DataTypes.INTEGER, + allowNull: false, + unique: true, + references: { + model: User, + key: "id", + deferrable: Deferrable.INITIALLY_IMMEDIATE, + } + }, + std_fields_ids: { + type: DataTypes.ARRAY(DataTypes.INTEGER), + allowNull: false, + references: { + model: StdField, + key: 'id', + deferrable: Deferrable.INITIALLY_IMMEDIATE + }, + } +}, { + underscored: true, + sequelize: postgresSeq, + modelName: "user_fields_display_settings" +}); + +// Verify if all standard fields exists in database +UserFieldsDisplaySettings.validateStdFieldIds = async (stdFieldIds) => { + // Count the number of existing IDs in std_fields + const validIds = await StdField.count({ + where: { id: stdFieldIds }, + }); + // Check if it matches the length of stdFieldIds + return validIds === stdFieldIds.length; +}; + +module.exports = { + UserFieldsDisplaySettings, +}; -- GitLab From 79be25e6def38467f0a56f8faa3de84b33dfae12 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Thu, 21 Nov 2024 10:57:10 +0100 Subject: [PATCH 04/13] [UserFieldsDisplaySettings] Corrected endpoints workflow [ErrorHandler] Added a global error handler to avoid code duplication and improve readability --- app/api/group/delete.js | 8 +- app/api/group/get.js | 6 +- app/api/group/post.js | 8 +- app/api/group/update.js | 2 +- app/api/index.js | 4 +- app/api/policy/delete.js | 4 +- app/api/policy/get.js | 4 +- app/api/policy/post.js | 4 +- app/api/policy/update.js | 4 +- app/api/realm/delete.js | 2 +- app/api/realm/get.js | 2 +- app/api/realm/post.js | 2 +- app/api/realm/put.js | 2 +- app/api/role-user/delete.js | 2 +- app/api/role-user/get.js | 2 +- app/api/role-user/post.js | 2 +- app/api/role-user/put.js | 2 +- app/api/roles/delete.js | 2 +- app/api/roles/get.js | 2 +- app/api/roles/post.js | 2 +- app/api/roles/put.js | 2 +- .../user-fields-display-settings/delete.js | 12 +- app/api/user-fields-display-settings/get.js | 23 ++-- app/api/user-fields-display-settings/post.js | 9 +- app/api/user-fields-display-settings/put.js | 9 +- app/api/user-requests/delete.js | 2 +- app/api/user-requests/get.js | 2 +- app/api/user-requests/post.js | 2 +- app/api/user-search-history/delete.js | 2 +- app/api/user-search-history/get.js | 2 +- app/api/user-search-history/post.js | 2 +- app/api/users/delete.js | 2 +- app/api/users/get.js | 2 +- app/api/users/post.js | 2 +- app/api/users/put.js | 2 +- app/dal/userFieldsDisplaySettingsService.js | 128 ++++++++---------- app/middlewares/errorHandler.js | 20 +++ app/utils/{format.js => logger.js} | 4 +- server.js | 52 +++---- 39 files changed, 154 insertions(+), 191 deletions(-) create mode 100644 app/middlewares/errorHandler.js rename app/utils/{format.js => logger.js} (99%) diff --git a/app/api/group/delete.js b/app/api/group/delete.js index 90521fb..7a0949f 100644 --- a/app/api/group/delete.js +++ b/app/api/group/delete.js @@ -1,8 +1,7 @@ 'use strict' const groupService = require('../../dal/groupService') - -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Group = { @@ -43,9 +42,8 @@ const Group = { }, } - module.exports = { - deleteGroup : Group.deleteGroup, + deleteGroup : Group.deleteGroup, deleteGroupPolicy: Group.deleteGroupPolicy, deleteGroupUser: Group.deleteGroupUser -} \ No newline at end of file +} diff --git a/app/api/group/get.js b/app/api/group/get.js index d380c10..c5ff2eb 100644 --- a/app/api/group/get.js +++ b/app/api/group/get.js @@ -2,7 +2,7 @@ const groupService = require('../../dal/groupService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Group = { @@ -45,7 +45,7 @@ const Group = { } module.exports = { - groups: Group.groups, + groups: Group.groups, groupPolicies: Group.groupPolicies, groupUsers: Group.groupUsers, -} \ No newline at end of file +} diff --git a/app/api/group/post.js b/app/api/group/post.js index 76f4e17..8643637 100644 --- a/app/api/group/post.js +++ b/app/api/group/post.js @@ -2,7 +2,7 @@ const groupService = require('../../dal/groupService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Group = { @@ -43,6 +43,6 @@ const Group = { module.exports = { createGroup: Group.createGroup, - createGroupPolicy: Group.createGroupPolicy, - createGroupUser: Group.createGroupUser, -} \ No newline at end of file + createGroupPolicy: Group.createGroupPolicy, + createGroupUser: Group.createGroupUser, +} diff --git a/app/api/group/update.js b/app/api/group/update.js index 880fffb..09ea4d1 100644 --- a/app/api/group/update.js +++ b/app/api/group/update.js @@ -2,7 +2,7 @@ const groupService = require('../../dal/groupService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Group = { diff --git a/app/api/index.js b/app/api/index.js index e93fb17..1c73cac 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -47,10 +47,10 @@ routers.delete('/user/delete-history', searchHistoryHandler.deleteH); // User fields display settings routers.post('/user/fields-display-settings/', /* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.createUserFieldsDisplaySettings); -routers.get('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUsersFieldsDisplaySettings); routers.get('/user/fields-display-settings/:userId',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUserFieldsDisplaySettings); +routers.get('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUsersFieldsDisplaySettings); routers.put('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.updateUserFieldsDisplaySettings); -routers.delete('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.deleteUserFieldsDisplaySettings); +routers.delete('/user/fields-display-settings/:userId',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.deleteUserFieldsDisplaySettings); // User requests routers.post('/user/create-request', userRequestHandler.createRequest); diff --git a/app/api/policy/delete.js b/app/api/policy/delete.js index 5b7b3e3..2865466 100644 --- a/app/api/policy/delete.js +++ b/app/api/policy/delete.js @@ -2,7 +2,7 @@ const policyService = require('../../dal/policyService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Policy = { @@ -35,4 +35,4 @@ const Policy = { module.exports = { deletePolicy: Policy.deletePolicy, deletePolicyField: Policy.deletePolicyField -} \ No newline at end of file +} diff --git a/app/api/policy/get.js b/app/api/policy/get.js index b73c29d..9a77a0e 100644 --- a/app/api/policy/get.js +++ b/app/api/policy/get.js @@ -2,7 +2,7 @@ const policyService = require('../../dal/policyService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Policy = { @@ -74,4 +74,4 @@ module.exports = { assignedPolicies: Policy.assignedPolicies, getPoliciesWithSources: Policy.getPoliciesWithSources, getGroupDetailsByPolicy: Policy.getGroupDetailsByPolicy -} \ No newline at end of file +} diff --git a/app/api/policy/post.js b/app/api/policy/post.js index 41a26e1..ba78615 100644 --- a/app/api/policy/post.js +++ b/app/api/policy/post.js @@ -2,7 +2,7 @@ const policyService = require('../../dal/policyService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const Policy = { @@ -74,4 +74,4 @@ module.exports = { createPolicy: Policy.createPolicy, createPolicyField: Policy.createPolicyField, createPolicySource: Policy.createPolicySource -} \ No newline at end of file +} diff --git a/app/api/policy/update.js b/app/api/policy/update.js index de97cfe..141bb6f 100644 --- a/app/api/policy/update.js +++ b/app/api/policy/update.js @@ -2,7 +2,7 @@ const policyService = require('../../dal/policyService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') @@ -36,4 +36,4 @@ const Policy = { module.exports = { updatePolicy: Policy.updatePolicy, updatePolicyField: Policy.updatePolicyField, -} \ No newline at end of file +} diff --git a/app/api/realm/delete.js b/app/api/realm/delete.js index 7549275..b6b49ba 100644 --- a/app/api/realm/delete.js +++ b/app/api/realm/delete.js @@ -1,7 +1,7 @@ 'use strict' const realmService = require('../../dal/realmService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const DeleteRealm = { diff --git a/app/api/realm/get.js b/app/api/realm/get.js index e360853..cdef5b9 100644 --- a/app/api/realm/get.js +++ b/app/api/realm/get.js @@ -1,7 +1,7 @@ 'use strict' const realmService = require('../../dal/realmService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const GetRealm = { diff --git a/app/api/realm/post.js b/app/api/realm/post.js index b27dd6e..d60ac09 100644 --- a/app/api/realm/post.js +++ b/app/api/realm/post.js @@ -1,7 +1,7 @@ "use strict" const realmService = require("../../dal/realmService") -const logger = require("../../utils/format") +const logger = require("../../utils/logger") const util = require('util') const AddRealm = { diff --git a/app/api/realm/put.js b/app/api/realm/put.js index 8a4b28b..adfa37c 100644 --- a/app/api/realm/put.js +++ b/app/api/realm/put.js @@ -1,7 +1,7 @@ 'use strict' const realmService = require("../../dal/realmService"); -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const UpdateRealm = { diff --git a/app/api/role-user/delete.js b/app/api/role-user/delete.js index 618849b..5189913 100644 --- a/app/api/role-user/delete.js +++ b/app/api/role-user/delete.js @@ -1,7 +1,7 @@ 'use strict' const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/format") +const logger = require("../../utils/logger") const util = require('util') diff --git a/app/api/role-user/get.js b/app/api/role-user/get.js index cc3d513..19d7ee5 100644 --- a/app/api/role-user/get.js +++ b/app/api/role-user/get.js @@ -1,7 +1,7 @@ 'use strict' const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/format") +const logger = require("../../utils/logger") const util = require('util') const GetAllocatedRole = { diff --git a/app/api/role-user/post.js b/app/api/role-user/post.js index 26313ab..11dbccb 100644 --- a/app/api/role-user/post.js +++ b/app/api/role-user/post.js @@ -1,7 +1,7 @@ 'use strict' const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/format") +const logger = require("../../utils/logger") const util = require('util') const AllocateRoleToUser = { diff --git a/app/api/role-user/put.js b/app/api/role-user/put.js index dbd82d8..f7d7ef0 100644 --- a/app/api/role-user/put.js +++ b/app/api/role-user/put.js @@ -1,7 +1,7 @@ 'use strict' const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/format") +const logger = require("../../utils/logger") const util = require('util') const UpdateAllocatedRole = { diff --git a/app/api/roles/delete.js b/app/api/roles/delete.js index a1c80fc..de2c2c3 100644 --- a/app/api/roles/delete.js +++ b/app/api/roles/delete.js @@ -1,7 +1,7 @@ 'use strict' const roleService = require('../../dal/roleService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const DeleteRole = { diff --git a/app/api/roles/get.js b/app/api/roles/get.js index b92913d..9f38b47 100644 --- a/app/api/roles/get.js +++ b/app/api/roles/get.js @@ -1,7 +1,7 @@ 'use strict' const roleService = require("../../dal/roleService") -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const GetRole = { diff --git a/app/api/roles/post.js b/app/api/roles/post.js index 230c2ff..19f1311 100644 --- a/app/api/roles/post.js +++ b/app/api/roles/post.js @@ -1,7 +1,7 @@ 'use strict' const roleService = require("../../dal/roleService") -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const AddRole = { diff --git a/app/api/roles/put.js b/app/api/roles/put.js index 5338694..4996aa9 100644 --- a/app/api/roles/put.js +++ b/app/api/roles/put.js @@ -1,7 +1,7 @@ 'use strict' const roleService = require('../../dal/roleService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const UpdateRole = { diff --git a/app/api/user-fields-display-settings/delete.js b/app/api/user-fields-display-settings/delete.js index f1ec286..743ae4a 100644 --- a/app/api/user-fields-display-settings/delete.js +++ b/app/api/user-fields-display-settings/delete.js @@ -1,20 +1,16 @@ 'use strict' const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); -const logger = require('../../utils/format'); -const util = require('util'); -const {updateUserFieldsDisplaySettings} = require("./put"); +const logger = require('../../utils/logger'); const UserFieldsDisplaySettings = { async delete(ctx) { try { - ctx.body = await userFieldsDisplaySettingsService.delete(ctx.request.body); + ctx.body = await userFieldsDisplaySettingsService.delete(ctx.request.params); ctx.status = 201; logger.info('User fields display settings deleted.'); - } catch (err) { - ctx.body = err || 'An error occurred.'; - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } catch (error) { + throw error; } } } diff --git a/app/api/user-fields-display-settings/get.js b/app/api/user-fields-display-settings/get.js index 18e04bb..e8b08ef 100644 --- a/app/api/user-fields-display-settings/get.js +++ b/app/api/user-fields-display-settings/get.js @@ -1,31 +1,26 @@ "use strict"; -const logger = require('../../utils/format') -const util = require('util') +const logger = require('../../utils/logger') const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); const GetUserFieldsDisplaySettings = { async find(ctx) { try { - ctx.body = await userFieldsDisplaySettingsService.usersFieldsDisplaySettings(ctx.request.body); + ctx.body = await userFieldsDisplaySettingsService.usersFieldsDisplaySettings(); ctx.status = 201; logger.info('Users fields display settings retrieved.'); - } catch (err) { - ctx.body = err || 'An error occurred.'; - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } catch (error) { + throw error; } }, async findOne(ctx) { try { - ctx.body = await userFieldsDisplaySettingsService.userFieldsDisplaySettings(ctx.request.body) - ctx.status = 201 - logger.info('User fields display settings retrieved.') - } catch (err) { - ctx.body = err || 'An error occurred.' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userFieldsDisplaySettingsService.userFieldsDisplaySettings(ctx.request.params); + ctx.status = 201; + logger.info('User fields display settings retrieved.'); + } catch (error) { + throw error; } }, }; diff --git a/app/api/user-fields-display-settings/post.js b/app/api/user-fields-display-settings/post.js index 556304c..2b0075b 100644 --- a/app/api/user-fields-display-settings/post.js +++ b/app/api/user-fields-display-settings/post.js @@ -1,8 +1,7 @@ 'use strict' const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); -const logger = require('../../utils/format') -const util = require('util') +const logger = require('../../utils/logger') const CreateUserFieldsDisplaySettings = { async create(ctx) { @@ -10,10 +9,8 @@ const CreateUserFieldsDisplaySettings = { ctx.body = await userFieldsDisplaySettingsService.create(ctx.request.body); ctx.status = 201; logger.info('User fields display settings created.'); - } catch (err) { - ctx.body = err || 'An error occurred.'; - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } catch (error) { + throw error; } }, } diff --git a/app/api/user-fields-display-settings/put.js b/app/api/user-fields-display-settings/put.js index 1e2d7de..066f593 100644 --- a/app/api/user-fields-display-settings/put.js +++ b/app/api/user-fields-display-settings/put.js @@ -1,8 +1,7 @@ 'use strict' const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService"); -const logger = require('../../utils/format'); -const util = require('util'); +const logger = require('../../utils/logger'); const UpdateUserFieldsDisplaySettings = { async update(ctx) { @@ -10,10 +9,8 @@ const UpdateUserFieldsDisplaySettings = { ctx.body = await userFieldsDisplaySettingsService.update(ctx.request.body); ctx.status = 201; logger.info('User fields display settings updated.'); - } catch (err) { - ctx.body = err || 'An error occurred.'; - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`); + } catch (error) { + throw error; } } } diff --git a/app/api/user-requests/delete.js b/app/api/user-requests/delete.js index 3723d10..170ecf5 100644 --- a/app/api/user-requests/delete.js +++ b/app/api/user-requests/delete.js @@ -1,7 +1,7 @@ 'use strict' const userRequestService = require('../../dal/userRequestService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const UserRequest = { diff --git a/app/api/user-requests/get.js b/app/api/user-requests/get.js index 18bd98c..cd0e420 100644 --- a/app/api/user-requests/get.js +++ b/app/api/user-requests/get.js @@ -1,7 +1,7 @@ 'use strict' const userRequestService = require('../../dal/userRequestService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const UserRequest = { diff --git a/app/api/user-requests/post.js b/app/api/user-requests/post.js index c1b3ef2..3644ebf 100644 --- a/app/api/user-requests/post.js +++ b/app/api/user-requests/post.js @@ -1,7 +1,7 @@ 'use strict' const userRequestService = require('../../dal/userRequestService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const UserRequest = { diff --git a/app/api/user-search-history/delete.js b/app/api/user-search-history/delete.js index fb2ad03..e483e80 100644 --- a/app/api/user-search-history/delete.js +++ b/app/api/user-search-history/delete.js @@ -1,7 +1,7 @@ 'use strict' const searchHistoryService = require('../../dal/searchHistoryService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const SearchHistory = { diff --git a/app/api/user-search-history/get.js b/app/api/user-search-history/get.js index 33e150e..7ecb996 100644 --- a/app/api/user-search-history/get.js +++ b/app/api/user-search-history/get.js @@ -1,7 +1,7 @@ 'use strict' const searchHistoryService = require('../../dal/searchHistoryService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const SearchHistory = { diff --git a/app/api/user-search-history/post.js b/app/api/user-search-history/post.js index c31879d..30b21c4 100644 --- a/app/api/user-search-history/post.js +++ b/app/api/user-search-history/post.js @@ -1,7 +1,7 @@ 'use strict' const searchHistoryService = require('../../dal/searchHistoryService') -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const SearchHistory = { diff --git a/app/api/users/delete.js b/app/api/users/delete.js index ceaf0ad..609c696 100644 --- a/app/api/users/delete.js +++ b/app/api/users/delete.js @@ -1,7 +1,7 @@ 'use strict' const userService = require("../../dal/userService") -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const DeleteUser = { diff --git a/app/api/users/get.js b/app/api/users/get.js index 7f73c7c..d998078 100644 --- a/app/api/users/get.js +++ b/app/api/users/get.js @@ -1,7 +1,7 @@ "use strict"; const userService = require("../../dal/userService"); -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const GetUser = { diff --git a/app/api/users/post.js b/app/api/users/post.js index 5679838..9acf501 100644 --- a/app/api/users/post.js +++ b/app/api/users/post.js @@ -1,7 +1,7 @@ 'use strict' const userService = require("../../dal/userService") -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const AddUser = { diff --git a/app/api/users/put.js b/app/api/users/put.js index 74a19f1..b7b7322 100644 --- a/app/api/users/put.js +++ b/app/api/users/put.js @@ -1,7 +1,7 @@ 'use strict' const userService = require("../../dal/userService") -const logger = require('../../utils/format') +const logger = require('../../utils/logger') const util = require('util') const UpdateUser = { diff --git a/app/dal/userFieldsDisplaySettingsService.js b/app/dal/userFieldsDisplaySettingsService.js index 49ef158..9bdb345 100644 --- a/app/dal/userFieldsDisplaySettingsService.js +++ b/app/dal/userFieldsDisplaySettingsService.js @@ -1,7 +1,6 @@ "use strict" const {UserFieldsDisplaySettings} = require("../models/UserFieldsDisplaySettings"); -const userService = require("./userService"); /* userFieldsDisplaySettingsService @@ -14,23 +13,16 @@ const userFieldsDisplaySettingsService = { // userId: id of the user // stdFieldsIds: array of ids of fields selected by user async create(ctx) { - try { - if (!ctx) { - throw Error("Empty request body."); - } else if (!ctx.userId) { - throw Error("Required parameter userId is missing."); - } else if (!ctx.stdFieldsIds) { - throw Error("Required parameter stdFieldsIds is missing."); - } - // Check if user exists - const user = await userService.user({id: userId}); - console.log(user); - if (!user) { - throw Error("User does not exists."); + if (!ctx || !ctx.userId || !ctx.stdFieldsIds) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } // Check if all fields ids exists if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) { - throw new Error("One or more std_field_id do not exists."); + const error = new Error("One or more std_field_id do not exists."); + error.status = 400; + throw error; } // Insert new row in user settings table const [newUserFieldsSettings, isCreated] = await UserFieldsDisplaySettings.findOrCreate({ @@ -39,94 +31,80 @@ const userFieldsDisplaySettingsService = { std_fields_ids: ctx.stdFieldsIds, }, }); - console.log(isCreated); - console.log(newUserFieldsSettings); if (!isCreated) { - throw new Error("User settings row already exists."); + const error = new Error("User fields display settings already exists."); + error.status = 400; + throw error; } - return { userFieldsDisplaySettings: newUserFieldsSettings, status: 201 }; - } catch (error) { - throw new Error(error); - } + return { newUserFieldsSettings, status: 201 }; }, // GET all users fields settings - async usersFieldsDisplaySettings(ctx) { - try { - return await UserFieldsDisplaySettings.findAll({}); - } - catch (err) { - ctx.status = err.status || 500; - ctx.body = err.message; - throw Error(err); - } + async usersFieldsDisplaySettings() { + return await UserFieldsDisplaySettings.findAll({}); }, // GET single user settings // userId: id of the user async userFieldsDisplaySettings(ctx) { - try { - if (!ctx) { - throw Error("Empty request body."); - } else if (!ctx.userId) { - throw Error("Required parameter userId is missing."); - } - return await UserFieldsDisplaySettings.findOne({ where: { user_id: ctx.userId } }); - } catch (err) { - ctx.status = err.status || 500; - ctx.body = err.message; - throw Error(err); + if (!ctx || !ctx.userId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + const result = await UserFieldsDisplaySettings.findOne({ where: { user_id: ctx.userId } }); + if (!result) { + const error = new Error("No settings found for this userId."); + error.status = 404; + throw error; } + return result; }, // PUT update a user settings // userId: id of the user // stdFieldsIds: new array of all fields ids async update(ctx) { - if (!ctx) { - throw Error("Empty request body."); - } else if (!ctx.userId) { - throw Error("Required parameter userId is missing."); - } else if (!ctx.stdFieldsIds) { - throw Error("Required parameter stdFieldsIds is missing."); - } - // Check if user exists - const user = await userService.user({id: userId}); - console.log(user); - if (!user) { - throw Error("User does not exists."); + if (!ctx || !ctx.userId || !ctx.stdFieldsIds) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } // Check if all fields ids exists if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) { - throw new Error("One or more std_field_id do not exists."); + const error = new Error("One or more std_field_id do not exists."); + error.status = 400; + throw error; } - return await UserFieldsDisplaySettings.update({ + const [updatedCount, updatedRows] = await UserFieldsDisplaySettings.update({ std_fields_ids: ctx.stdFieldsIds, - }, { - where: { - user_id: userId - } - }); + }, { where: { user_id: ctx.userId }}); + if (updatedCount === 0) { + const error = new Error("No settings found for this userId."); + error.status = 404; + throw error; + } + return updatedRows ? updatedRows[0] : 'User fields display settings updated.'; }, // DELETE the user settings async delete(ctx) { - try { - if (!ctx) { - throw Error("Empty request body."); - } else if (!ctx.userId) { - throw Error("Required parameter userId is missing."); + if (!ctx || !ctx.userId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + const deletedCount = await UserFieldsDisplaySettings.destroy({ + where: { + user_id: ctx.userId } - return await UserFieldsDisplaySettings.destroy({ - where: { - user_id: userId - } - }); - } catch (error) { - ctx.status = error.status || 500; - ctx.body = error.message; - throw Error(error); + }); + if (deletedCount === 0) { + const error = new Error("No settings found for this userId."); + error.status = 404; + throw error; } + return 'User fields display settings deleted.'; }, } diff --git a/app/middlewares/errorHandler.js b/app/middlewares/errorHandler.js new file mode 100644 index 0000000..f360c03 --- /dev/null +++ b/app/middlewares/errorHandler.js @@ -0,0 +1,20 @@ +const logger = require("../utils/logger"); + +/* + * Global error handler middleware + * + * - Catches and handles all errors thrown within services, handlers, and routes. + * - Logs error details for debugging and monitoring. + * - Ensures the application does not crash on unhandled errors. + */ +const errorHandler = async (ctx, next) => { + try { + await next(); + } catch (err) { + logger.error(err.message); + ctx.status = err.status || 500; + ctx.body = err.message || "Internal Server Error"; + } +}; + +module.exports = errorHandler; diff --git a/app/utils/format.js b/app/utils/logger.js similarity index 99% rename from app/utils/format.js rename to app/utils/logger.js index 118da74..9d10265 100644 --- a/app/utils/format.js +++ b/app/utils/logger.js @@ -27,7 +27,5 @@ const logger = createLogger({ ) ] }); -module.exports = logger; - - +module.exports = logger; diff --git a/server.js b/server.js index b41eca1..62fdcb4 100644 --- a/server.js +++ b/server.js @@ -1,55 +1,39 @@ 'use strict' -const Koa = require('koa') -const logger = require('winston') -const api = require('./app/api') -const koaLogger = require('koa-logger') -const cors = require('koa2-cors') +const Koa = require('koa'); +const api = require('./app/api'); +const koaLogger = require('koa-logger'); +const cors = require('koa2-cors'); const { keycloak } = require('./init-keycloak'); +const errorHandler = require('./app/middlewares/errorHandler'); -async function responseTime(ctx, next) { +const responseTime = async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; ctx.set('X-Response-Time', `${ms}ms`); } -const app = new Koa() +const app = new Koa(); -app.proxy = false +app.use(errorHandler); const middlewares = keycloak.middleware({ logout: '/logout', admin: '/', protected: '/protected/resource' -}) - +}); middlewares.forEach(function (middleware) { app.use(middleware); }) -app - .use(cors({ - origin: '*' - })) - .use(koaLogger()) - .use(function (ctx, next) { - return next().catch((err) => { - if (err) { - // Protected resource, use Authorization header to get access\n - console.log(err) - ctx.status = 401 - ctx.body = err - } - }) - }) - .use(api.routes()) - .use(api.allowedMethods()) - .use(responseTime) - -app.on('error', (err) => { - logger.error('Server error', { error: err.message }) - throw err -}) +app.proxy = false; +app.use(cors({origin: '*'})); +app.use(koaLogger()); +app.use(responseTime); + +// Register routes +app.use(api.routes()); +app.use(api.allowedMethods()); -module.exports = app +module.exports = app; -- GitLab From 802170eff2cddd8a0e0e8b8351a9a85c54f24fd1 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Thu, 21 Nov 2024 11:02:31 +0100 Subject: [PATCH 05/13] [web.js] corrected logger import --- web.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/web.js b/web.js index f714d79..2ed23e2 100644 --- a/web.js +++ b/web.js @@ -1,21 +1,17 @@ 'use strict' -const { promisify } = require('util') -const http = require('http') -const logger = require('winston') -const app = require('./server') -const config = require('./app/config/server') +const { promisify } = require('util'); +const http = require('http'); +const app = require('./server'); +const config = require('./app/config/server'); +const logger = require("./app/utils/logger"); -logger.level = config.logger.level +const server = http.createServer(app.callback()); +const serverListen = promisify(server.listen).bind(server); -const server = http.createServer(app.callback()) -const serverListen = promisify(server.listen).bind(server) - -serverListen(config.port) - .then(() => { - logger.info(`in-sylva.gatekeeper service is up and running on localhost:${config.port}`) - }) - .catch((err) => { - logger.error(err) - process.exit(1) - }) +serverListen(config.port).then(() => { + logger.info(`in-sylva.gatekeeper service is up and running on localhost:${config.port}`); + }).catch((error) => { + logger.error(error); + process.exit(1); + }); -- GitLab From 5a052ed67eb8c7cb5f58e34681d7752940ab1379 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Thu, 21 Nov 2024 16:43:41 +0100 Subject: [PATCH 06/13] [groups] now following new error handling ; improved some logic --- app/api/group/delete.js | 39 +++++------ app/api/group/get.js | 41 +++++------ app/api/group/index.js | 13 ++-- app/api/group/post.js | 42 +++++------ app/api/group/update.js | 40 +++++------ app/dal/groupService.js | 151 ++++++++++++++++++++++------------------ 6 files changed, 157 insertions(+), 169 deletions(-) diff --git a/app/api/group/delete.js b/app/api/group/delete.js index 7a0949f..5a8c7cd 100644 --- a/app/api/group/delete.js +++ b/app/api/group/delete.js @@ -1,49 +1,42 @@ 'use strict' -const groupService = require('../../dal/groupService') -const logger = require('../../utils/logger') -const util = require('util') +const groupService = require('../../dal/groupService'); +const logger = require('../../utils/logger'); const Group = { async deleteGroup(ctx) { try { - ctx.body = await groupService.deleteGroup(ctx.request.body) - ctx.status = 201 - logger.info('group is deleted successfully!') + ctx.body = await groupService.deleteGroup(ctx.request.body); + ctx.status = 201; + logger.info('Group deleted.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async deleteGroupPolicy(ctx) { try { - ctx.body = await groupService.deleteGroupPolicy(ctx.request.body) - ctx.status = 201 - logger.info('GroupPolicy is deleted successfully!') + ctx.body = await groupService.deleteGroupPolicy(ctx.request.body); + ctx.status = 201; + logger.info('Group policy deleted.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async deleteGroupUser(ctx) { try { - ctx.body = await groupService.deleteGroupUser(ctx.request.body) - ctx.status = 201 - logger.info('GroupUser is deleted successfully!') + ctx.body = await groupService.deleteGroupUser(ctx.request.body); + ctx.status = 201; + logger.info('Group user deleted.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, -} +}; module.exports = { deleteGroup : Group.deleteGroup, deleteGroupPolicy: Group.deleteGroupPolicy, deleteGroupUser: Group.deleteGroupUser -} +}; diff --git a/app/api/group/get.js b/app/api/group/get.js index c5ff2eb..8a99ad0 100644 --- a/app/api/group/get.js +++ b/app/api/group/get.js @@ -1,51 +1,42 @@ 'use strict' -const groupService = require('../../dal/groupService') - -const logger = require('../../utils/logger') -const util = require('util') +const groupService = require('../../dal/groupService'); +const logger = require('../../utils/logger'); const Group = { - async groups(ctx) { try { - ctx.body = await groupService.groups(ctx.request.body) - ctx.status = 201 - logger.info('groups are fetched successfully!') + ctx.body = await groupService.groups(); + ctx.status = 201; + logger.info('Groups fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async groupPolicies(ctx) { try { - ctx.body = await groupService.groupPolicies(ctx.request.body) - ctx.status = 201 - logger.info('groupPolicies are fetched successfully!') + ctx.body = await groupService.groupPolicies(); + ctx.status = 201; + logger.info('Group policies fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async groupUsers(ctx) { try { - ctx.body = await groupService.groupUsers(ctx.request.body) - ctx.status = 201 - logger.info('groupUsers are fetched successfully!') + ctx.body = await groupService.groupUsers(ctx.request.body); + ctx.status = 201; + logger.info('Group users fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { groups: Group.groups, groupPolicies: Group.groupPolicies, groupUsers: Group.groupUsers, -} +}; diff --git a/app/api/group/index.js b/app/api/group/index.js index bb15fd2..32fb066 100644 --- a/app/api/group/index.js +++ b/app/api/group/index.js @@ -1,9 +1,10 @@ 'use strict' -const { groups, groupUsers, groupPolicies } = require('./get') -const { createGroup, createGroupPolicy, createGroupUser } = require('./post') -const { deleteGroup, deleteGroupPolicy, deleteGroupUser } = require('./delete') -const { updateGroup, updateGroupPolicy, updateGroupUser } = require('./update') +const { groups, groupUsers, groupPolicies } = require('./get'); +const { createGroup, createGroupPolicy, createGroupUser } = require('./post'); +const { deleteGroup, deleteGroupPolicy, deleteGroupUser } = require('./delete'); +const { updateGroup, updateGroupPolicy, updateGroupUser } = require('./update'); + const GroupHandler = { groups, groupUsers, @@ -17,6 +18,6 @@ const GroupHandler = { updateGroup, updateGroupPolicy, updateGroupUser -} +}; -module.exports = GroupHandler \ No newline at end of file +module.exports = GroupHandler; diff --git a/app/api/group/post.js b/app/api/group/post.js index 8643637..dd0a5b5 100644 --- a/app/api/group/post.js +++ b/app/api/group/post.js @@ -1,48 +1,42 @@ 'use strict' -const groupService = require('../../dal/groupService') - -const logger = require('../../utils/logger') -const util = require('util') +const groupService = require('../../dal/groupService'); +const logger = require('../../utils/logger'); const Group = { async createGroup(ctx) { try { - ctx.body = await groupService.createGroup(ctx.request.body) - ctx.status = 201 - logger.info('group created successfully!') + ctx.body = await groupService.createGroup(ctx.request.body); + ctx.status = 201; + logger.info('Group created.'); } catch (error) { - ctx.body = error || 'error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, + async createGroupPolicy(ctx) { try { - ctx.body = await groupService.createGroupPolicy(ctx.request.body) - ctx.status = 201 - logger.info('GroupPolicy created successfully!') + ctx.body = await groupService.createGroupPolicy(ctx.request.body); + ctx.status = 201; + logger.info('Assigned policy to group.'); } catch (error) { - ctx.body = error || 'error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, + async createGroupUser(ctx) { try { - ctx.body = await groupService.createGroupUser(ctx.request.body) - ctx.status = 201 - logger.info('GroupUser created successfully!') + ctx.body = await groupService.createGroupUser(ctx.request.body); + ctx.status = 201; + logger.info('Assigned user to group.'); } catch (error) { - ctx.body = error || 'error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { createGroup: Group.createGroup, createGroupPolicy: Group.createGroupPolicy, createGroupUser: Group.createGroupUser, -} +}; diff --git a/app/api/group/update.js b/app/api/group/update.js index 09ea4d1..6241040 100644 --- a/app/api/group/update.js +++ b/app/api/group/update.js @@ -1,50 +1,42 @@ 'use strict' -const groupService = require('../../dal/groupService') - -const logger = require('../../utils/logger') -const util = require('util') +const groupService = require('../../dal/groupService'); +const logger = require('../../utils/logger'); const Group = { async updateGroup(ctx) { try { - ctx.body = await groupService.updateGroup(ctx.request.body) - ctx.status = 201 - logger.info('group is updated successfully!') + ctx.body = await groupService.updateGroup(ctx.request.body); + ctx.status = 201; + logger.info('Group updated.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async updateGroupPolicy(ctx) { try { - ctx.body = await groupService.updateGroupPolicy(ctx.request.body) - ctx.status = 201 - logger.info('GroupPolicy is updated successfully!') + ctx.body = await groupService.updateGroupPolicy(ctx.request.body); + ctx.status = 201; + logger.info('Group policy updated.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async updateGroupUser(ctx) { try { - ctx.body = await groupService.updateGroupUser(ctx.request.body) - ctx.status = 201 - logger.info('GroupUser is updated successfully!') + ctx.body = await groupService.updateGroupUser(ctx.request.body); + ctx.status = 201; + logger.info('Group user updated.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, -} +}; module.exports = { updateGroup: Group.updateGroup, updateGroupPolicy: Group.updateGroupPolicy, updateGroupUser: Group.updateGroupUser, -} +}; diff --git a/app/dal/groupService.js b/app/dal/groupService.js index 6d27ca6..d2a6b17 100644 --- a/app/dal/groupService.js +++ b/app/dal/groupService.js @@ -6,37 +6,40 @@ const db = require('../../db') const GroupService = { async createGroup(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); - } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported."); + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const user = await userService.detail({ kcId: ctx.kcId }); - if (user) { - const group = await Group.findOne({ - where: { - name: ctx.name, - user_id: user.id, - } - }); - if (group) { - throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`); - } else { - return await Group.create({ - name: ctx.name, - description: ctx.description, - user_id: user.id, - }); - } - } else { - throw Error('User account not found.'); + if (!user) { + const error = new Error("User account not found."); + error.status = 400; + throw error; } + const [newGroup, isCreated] = await Group.findOrCreate( + { + where: { + name: ctx.name, + user_id: user.id, + }, + defaults: { + description: ctx.description, + }, + }); + if (!isCreated) { + const error = new Error(`Group:${ctx.name} already exists.`); + error.status = 400; + throw error; + } + return newGroup; }, async createGroupPolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.groupId || !ctx.policyId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const groupPolicy = await GroupsPolicy.findOne({ where: { @@ -45,7 +48,9 @@ const GroupService = { } }); if (groupPolicy) { - throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`); + const error = new Error(`GroupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other.`); + error.status = 400; + throw error; } else { return await GroupsPolicy.create({ group_id: ctx.groupId, @@ -55,11 +60,10 @@ const GroupService = { }, async createGroupUser(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); - } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported."); + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const user = await userService.detail({ kcId: ctx.kcId }); if (user) { @@ -70,7 +74,9 @@ const GroupService = { } }); if (groupUser) { - throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`); + const error = new Error(`GroupId:${ctx.groupId} and userId:${user.id} already assigned to each other.`); + error.status = 400; + throw error; } else { return await GroupUser.create({ group_id: ctx.groupId, @@ -78,13 +84,17 @@ const GroupService = { }); } } else { - throw Error('The user account could not found.'); + const error = new Error('User account not found.'); + error.status = 400; + throw error; } }, async updateGroup(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.name || !ctx.description || !ctx.id || !ctx.userId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await Group.update({ name: ctx.name, @@ -95,8 +105,10 @@ const GroupService = { }, async updateGroupPolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.groupId || !ctx.policyId || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await GroupsPolicy.update({ group_id: ctx.groupId, @@ -105,36 +117,41 @@ const GroupService = { }, async updateGroupUser(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const user = await userService.detail({ kcId: ctx.kcId }); - if (user) { - return await GroupUser.update({ - group_id: ctx.groupId, - user_id: user.id - }, {where: {id: ctx.id}}); - } else { - throw Error('The user account could not found.'); + if (!user) { + const error = new Error("User account not found."); + error.status = 400; + throw error; } + return await GroupUser.update({ + group_id: ctx.groupId, + user_id: user.id + }, {where: {id: ctx.id}}); }, async deleteGroup(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.id) { - return await Group.destroy({ - where: { - id: ctx.id - } - }); + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + return await Group.destroy({ + where: { + id: ctx.id + } + }); }, async deleteGroupPolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await GroupsPolicy.destroy({ where: { @@ -144,15 +161,13 @@ const GroupService = { }, async deleteGroupUser(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.groupId || !ctx.userId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const params = { groupId: ctx.groupId, userId: ctx.userId }; - const groupUser = await db.raw(` - delete from group_users - where group_id = :groupId and user_id = :userId - `, params); - return groupUser; + return db.raw(`delete from group_users where group_id = :groupId and user_id = :userId`, params); }, async groups() { @@ -164,8 +179,10 @@ const GroupService = { }, async groupUsers(ctx) { - if (!ctx) { - throw Error("The request body is empty!"); + if (!ctx || !ctx.groupId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const params = { groupId: ctx.groupId }; const groupUsers = await db.raw(` @@ -195,4 +212,4 @@ module.exports = { groups: GroupService.groups, groupPolicies: GroupService.groupPolicies, groupUsers: GroupService.groupUsers, -} +}; -- GitLab From d5242545f6f94d25bff1278bfd41efafc66e5871 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Fri, 22 Nov 2024 10:48:31 +0100 Subject: [PATCH 07/13] [policies] now following new error handling ; improved some logic --- app/api/policy/delete.js | 31 +++--- app/api/policy/get.js | 61 +++++------ app/api/policy/post.js | 61 +++++------ app/api/policy/update.js | 32 +++--- app/dal/policyService.js | 227 ++++++++++++++++++++------------------- 5 files changed, 186 insertions(+), 226 deletions(-) diff --git a/app/api/policy/delete.js b/app/api/policy/delete.js index 2865466..4a75dce 100644 --- a/app/api/policy/delete.js +++ b/app/api/policy/delete.js @@ -1,38 +1,31 @@ 'use strict' -const policyService = require('../../dal/policyService') - -const logger = require('../../utils/logger') -const util = require('util') +const policyService = require('../../dal/policyService'); +const logger = require('../../utils/logger'); const Policy = { - async deletePolicy(ctx) { try { - ctx.body = await policyService.deletePolicy(ctx.request.body) - ctx.status = 201 - logger.info('Policy is listed successfully!') + ctx.body = await policyService.deletePolicy(ctx.request.body); + ctx.status = 201; + logger.info('Policy deleted.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async deletePolicyField(ctx) { try { - ctx.body = await policyService.deletePolicyField(ctx.request.body) - ctx.status = 201 - logger.info('PolicyField is listed successfully!') + ctx.body = await policyService.deletePolicyField(ctx.request.body); + ctx.status = 201; + logger.info('PolicyField deleted.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { deletePolicy: Policy.deletePolicy, deletePolicyField: Policy.deletePolicyField -} +}; diff --git a/app/api/policy/get.js b/app/api/policy/get.js index 9a77a0e..61abfad 100644 --- a/app/api/policy/get.js +++ b/app/api/policy/get.js @@ -1,72 +1,59 @@ 'use strict' -const policyService = require('../../dal/policyService') - -const logger = require('../../utils/logger') -const util = require('util') +const policyService = require('../../dal/policyService'); +const logger = require('../../utils/logger'); const Policy = { - async policies(ctx) { try { - ctx.body = await policyService.policies(ctx.request.body) - ctx.status = 201 - logger.info('Policy is listed successfully!') + ctx.body = await policyService.policies(); + ctx.status = 201; + logger.info('Policies fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async policyFields(ctx) { try { - ctx.body = await policyService.policyFields(ctx.request.body) - ctx.status = 201 - logger.info('PolicyField is listed successfully!') + ctx.body = await policyService.policyFields(); + ctx.status = 201; + logger.info('Policy fields fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async assignedPolicies(ctx) { try { - ctx.body = await policyService.getAssignedPolicies(ctx.request.body) - ctx.status = 201 - logger.info('assignedPolicies are listed successfully!') + ctx.body = await policyService.getAssignedPolicies(ctx.request.body); + ctx.status = 201; + logger.info('Assigned policies fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async getPoliciesWithSources(ctx) { try { - ctx.body = await policyService.getPoliciesWithSources(ctx.request.body) - ctx.status = 201 - logger.info('PoliciesWithSources are listed successfully!') + ctx.body = await policyService.getPoliciesWithSources(); + ctx.status = 201; + logger.info('Policies with sources fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async getGroupDetailsByPolicy(ctx) { try { - ctx.body = await policyService.getGroupDetailsByPolicy(ctx.request.body) - ctx.status = 201 - logger.info('Group Details by policy are listed successfully!') + ctx.body = await policyService.getGroupDetailsByPolicy(ctx.request.body); + ctx.status = 201; + logger.info('Group details by policy fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { policies: Policy.policies, @@ -74,4 +61,4 @@ module.exports = { assignedPolicies: Policy.assignedPolicies, getPoliciesWithSources: Policy.getPoliciesWithSources, getGroupDetailsByPolicy: Policy.getGroupDetailsByPolicy -} +}; diff --git a/app/api/policy/post.js b/app/api/policy/post.js index ba78615..a04c6bb 100644 --- a/app/api/policy/post.js +++ b/app/api/policy/post.js @@ -1,72 +1,59 @@ 'use strict' -const policyService = require('../../dal/policyService') - -const logger = require('../../utils/logger') -const util = require('util') +const policyService = require('../../dal/policyService'); +const logger = require('../../utils/logger'); const Policy = { - async createPolicy(ctx) { try { - ctx.body = await policyService.createPolicy(ctx.request.body) - ctx.status = 201 - logger.info('Policy is created successfully!') + ctx.body = await policyService.createPolicy(ctx.request.body); + ctx.status = 201; + logger.info('Policy created.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async createPolicyField(ctx) { try { - ctx.body = await policyService.createPolicyField(ctx.request.body) - ctx.status = 201 - logger.info('PolicyField is created successfully!') + ctx.body = await policyService.createPolicyField(ctx.request.body); + ctx.status = 201; + logger.info('PolicyField created.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async createPolicySource(ctx) { try { - ctx.body = await policyService.createPolicySource(ctx.request.body) - ctx.status = 201 - logger.info('PolicySource is created successfully!') + ctx.body = await policyService.createPolicySource(ctx.request.body); + ctx.status = 201; + logger.info('PolicySource created.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async policiesByUser(ctx) { try { - ctx.body = await policyService.policiesByUser(ctx.request.body) - ctx.status = 201 - logger.info('Policies by user listed successfully!') + ctx.body = await policyService.policiesByUser(ctx.request.body); + ctx.status = 201; + logger.info('Policies by user listed.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async getPoliciesWithSourcesByUser(ctx) { try { - ctx.body = await policyService.getPoliciesWithSourcesByUser(ctx.request.body) - ctx.status = 201 - logger.info('Policies with sources by user listed successfully!') + ctx.body = await policyService.getPoliciesWithSourcesByUser(ctx.request.body); + ctx.status = 201; + logger.info('Policies with sources by user listed.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { policiesByUser: Policy.policiesByUser, @@ -74,4 +61,4 @@ module.exports = { createPolicy: Policy.createPolicy, createPolicyField: Policy.createPolicyField, createPolicySource: Policy.createPolicySource -} +}; diff --git a/app/api/policy/update.js b/app/api/policy/update.js index 141bb6f..9afd22e 100644 --- a/app/api/policy/update.js +++ b/app/api/policy/update.js @@ -1,39 +1,31 @@ 'use strict' -const policyService = require('../../dal/policyService') - -const logger = require('../../utils/logger') -const util = require('util') - +const policyService = require('../../dal/policyService'); +const logger = require('../../utils/logger'); const Policy = { - async updatePolicy(ctx) { try { - ctx.body = await policyService.updatePolicy(ctx.request.body) - ctx.status = 201 - logger.info('Policy is updated successfully!') + ctx.body = await policyService.updatePolicy(ctx.request.body); + ctx.status = 201; + logger.info('Policy updated.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async updatePolicyField(ctx) { try { - ctx.body = await policyService.updatePolicyField(ctx.request.body) - ctx.status = 201 - logger.info('PolicyField is updated successfully!') + ctx.body = await policyService.updatePolicyField(ctx.request.body); + ctx.status = 201; + logger.info('Policy field updated.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { updatePolicy: Policy.updatePolicy, updatePolicyField: Policy.updatePolicyField, -} +}; diff --git a/app/dal/policyService.js b/app/dal/policyService.js index 7488169..a101a67 100644 --- a/app/dal/policyService.js +++ b/app/dal/policyService.js @@ -1,95 +1,87 @@ 'use strict' const { Policy, PolicyField, PolicySource } = require('../models/Policy') - const db = require('../../db'); const userService = require('./userService') const PolicyService = { - async createPolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") + const user = await userService.detail({ kcId: ctx.kcId }); + if (!user) { + const error = new Error("User account not found."); + error.status = 400; + throw error; } - const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - const policy = await Policy.findOne({ + const [newPolicy, isCreated] = await Policy.findOrCreate( + { where: { name: ctx.name, - // source_id: ctx.sourceId, - user_id: user.id, - is_default: false - } - }) - if (policy) { - throw Error(`This Policy name:${ctx.name} and sourceId:${ctx.sourceId} already inserted to database!`) - } else { - return await Policy.create({ - name: ctx.name, - // source_id: ctx.sourceId, user_id: user.id, + }, + defaults: { is_default: false - }) - } - } else { - throw Error('The user account could not found.') + }, + }); + if (!isCreated) { + const error = new Error(`Policy:${ctx.name} already exists.`); + error.status = 400; + throw error; } + return newPolicy; }, async createPolicyField(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.policyId || !ctx.stdFieldId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const { policyId, stdFieldId } = ctx - - if (policyId && stdFieldId) { - const policyField = await PolicyField.findOne({ + const [newPolicyField, isCreated] = await PolicyField.findOrCreate( + { where: { - policy_id: policyId, - std_field_id: stdFieldId, - } - }) - if (policyField) { - throw Error(`This policyId:${policyId} and stdFieldId:${stdFieldId} already assigned to each other in the database!`) - } else { - return await PolicyField.create({ - policy_id: policyId, - std_field_id: stdFieldId, - }) - } + policy_id: ctx.policyId, + std_field_id: ctx.stdFieldId, + }, + }); + if (!isCreated) { + const error = new Error("Policy and stdField already assigned to each other."); + error.status = 400; + throw error; } + return newPolicyField; }, async createPolicySource(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.policyId || !ctx.sourceId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const { policyId, sourceId } = ctx - - if (policyId && sourceId) { - const policySource = await PolicySource.findOne({ + const [newPolicySource, isCreated] = await PolicySource.findOrCreate( + { where: { - policy_id: policyId, - source_id: sourceId, - } - }) - if (policySource) { - throw Error(`This policyId:${policyId} and sourceId:${sourceId} already assigned to each other in the database!`) - } else { - return await PolicySource.create({ - policy_id: policyId, - source_id: sourceId, - }) - } + policy_id: ctx.policyId, + source_id: ctx.sourceId, + }, + }); + if (!isCreated) { + const error = new Error("Policy and source already assigned to each other."); + error.status = 400; + throw error; } + return newPolicySource; }, async updatePolicySource(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id || !ctx.sourceId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await PolicySource.update({ source_id: ctx.sourceId, @@ -101,10 +93,12 @@ const PolicyService = { }, async deletePolicySource(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - return await PolicySource.destroyi({ + return await PolicySource.destroy({ where: { id: ctx.id } @@ -112,13 +106,15 @@ const PolicyService = { }, async updatePolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id || !ctx.name || !ctx.sourceId || !ctx.isDefault) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await Policy.update({ name: ctx.name, source_id: ctx.sourceId, - is_default: ctx.isDeafault + is_default: ctx.isDefault }, { where: { id: ctx.id, @@ -127,8 +123,10 @@ const PolicyService = { }, async updatePolicyField(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id || !ctx.policyId || !ctx.stdFieldId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await PolicyField.update({ policy_id: ctx.policyId, @@ -141,62 +139,67 @@ const PolicyService = { }, async deletePolicyField(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await PolicyField.destroy({ where: { id: ctx.id } - }) + }); }, async deletePolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const policyField = await PolicyField.destroy({ where: { policy_id: ctx.id } - }) + }); await Policy.destroy({ where: { id: ctx.id } - }) - return policyField + }); + return policyField; }, async policies() { - return await Policy.findAll({}) + return await Policy.findAll({}); }, async policiesByUser(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } try { - const params = { userId: ctx.kcId } - const policiesByUser = await db.raw( - `select DISTINCT p.id, p.name, p.user_id, p.source_id, u.kc_id from policies p - inner join users u on p.user_id = u.id - where u.kc_id = :userId`, params) - return policiesByUser.rows + const params = { userId: ctx.kcId }; + const policiesByUser = await db.raw(`select DISTINCT p.id, p.name, p.user_id, p.source_id, u.kc_id from policies p inner join users u on p.user_id = u.id where u.kc_id = :userId`, params); + return policiesByUser.rows; } catch (error) { - throw new Error(error) + throw new Error(error); } }, async policyFields() { - return await PolicyField.findAll({}) + return await PolicyField.findAll({}); }, async getAssignedPolicies(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.policyId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const params = { policyId: ctx.policyId } + const params = { policyId: ctx.policyId }; const assignedPolicies = await db.raw(` select pf.id, sf.field_name, sf.definition_and_comment, sf.field_type, sf.values from policies p inner join policy_fields pf on p.id = pf.policy_id @@ -204,15 +207,11 @@ const PolicyService = { inner join policy_sources ps on p.id = ps.policy_id inner join sources s on ps.source_id = s.id where p.id = :policyId - `, params) - return assignedPolicies.rows + `, params); + return assignedPolicies.rows; }, - async getPoliciesWithSources(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - // remark: list all policies as usual, domain free + async getPoliciesWithSources() { const policiesWIthSource = await db.raw(` select p.id, p.name as policyName, s.name as sourceName from policies p left join policy_sources ps on p.id = ps.policy_id @@ -222,28 +221,32 @@ const PolicyService = { }, async getPoliciesWithSourcesByUser(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } try { - const params = { userId: ctx.kcId } + const params = { userId: ctx.kcId }; const policiesByUser = await db.raw(` select p.id, p.name as policyName, s.name as sourceName, p.user_id, p.source_id, u.kc_id from policies p inner join users u on p.user_id = u.id left join policy_sources ps on p.id = ps.policy_id left join sources s on ps.source_id = s.id where u.kc_id = :userId`, params) - return policiesByUser.rows + return policiesByUser.rows; } catch (error) { - throw new Error(error) + throw new Error(error); } }, async getGroupDetailsByPolicy(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.policyId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const params = { policyId: ctx.policyId } + const params = { policyId: ctx.policyId }; const groupDetailsByPolicy = await db.raw(` select p.id as policyId, g.id as groupId, gp.id groupPolicyId, g.name as group_name, g.description as group_description, s.name as source_name, s.description as source_description from policies p inner join groups_policies gp on p.id = gp.policy_id @@ -251,12 +254,10 @@ const PolicyService = { left join policy_sources ps on p.id = ps.policy_id left join sources s on ps.source_id = s.id where p.id = :policyId - `, params) - return groupDetailsByPolicy.rows + `, params); + return groupDetailsByPolicy.rows; } - -} - +}; module.exports = { createPolicy: PolicyService.createPolicy, @@ -276,4 +277,4 @@ module.exports = { getPoliciesWithSources: PolicyService.getPoliciesWithSources, getPoliciesWithSourcesByUser: PolicyService.getPoliciesWithSourcesByUser, getGroupDetailsByPolicy: PolicyService.getGroupDetailsByPolicy, -} +}; -- GitLab From 80d6c48be371b2d2a5bfe7264f0fc7d6ff705b18 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Fri, 22 Nov 2024 14:20:33 +0100 Subject: [PATCH 08/13] [roleAllocation] now following new error handling ; improved some logic --- app/api/index.js | 2 +- app/api/role-user/delete.js | 26 ++++----- app/api/role-user/get.js | 23 ++++---- app/api/role-user/index.js | 14 ++--- app/api/role-user/post.js | 25 ++++----- app/api/role-user/put.js | 21 ++++---- app/dal/roleAllocationService.js | 93 ++++++++++++++++---------------- 7 files changed, 94 insertions(+), 110 deletions(-) diff --git a/app/api/index.js b/app/api/index.js index 1c73cac..43be607 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -98,7 +98,7 @@ routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole); routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update); // Role allocation to users -routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole); +routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.create); routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles); routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update); routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole); diff --git a/app/api/role-user/delete.js b/app/api/role-user/delete.js index 5189913..ef7c9d1 100644 --- a/app/api/role-user/delete.js +++ b/app/api/role-user/delete.js @@ -1,25 +1,21 @@ 'use strict' -const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/logger") -const util = require('util') - +const roleAllocationService = require("../../dal/roleAllocationService"); +const logger = require("../../utils/logger"); const DeleteAllocatedRole = { - async deleteAllocatedRole(ctx) { + async delete(ctx) { try { - ctx.body = await roleAllocationService.delete(ctx.request.body) - ctx.status = 201 - logger.info('Allocated role is deleted successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleAllocationService.delete(ctx.request.body); + ctx.status = 201; + logger.info('Role allocated to user deleted.'); + } catch (error) { + throw error; } } -} +}; module.exports = { - deleteAllocatedRole: DeleteAllocatedRole.deleteAllocatedRole, + deleteAllocatedRole: DeleteAllocatedRole.delete, DeleteAllocatedRole -} +}; diff --git a/app/api/role-user/get.js b/app/api/role-user/get.js index 19d7ee5..9936076 100644 --- a/app/api/role-user/get.js +++ b/app/api/role-user/get.js @@ -1,26 +1,21 @@ 'use strict' -const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/logger") -const util = require('util') +const roleAllocationService = require("../../dal/roleAllocationService"); +const logger = require("../../utils/logger"); const GetAllocatedRole = { async find(ctx) { try { - const allocatedRoles = await roleAllocationService.allocatedRoles(ctx.request.body) - ctx.body = allocatedRoles.rows - ctx.status = 201 - logger.info('Allocated roles are listed by kc_id') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleAllocationService.allocatedRoles(ctx.request.body); + ctx.status = 201; + logger.info('User allocated roles fetched.'); + } catch (error) { + throw error; } } -} - +}; module.exports = { allocatedRoles: GetAllocatedRole.find, GetAllocatedRole -} +}; diff --git a/app/api/role-user/index.js b/app/api/role-user/index.js index f927a56..19a8e52 100644 --- a/app/api/role-user/index.js +++ b/app/api/role-user/index.js @@ -1,15 +1,15 @@ 'use strict' -const { allocateRole } = require("./post") -const { allocatedRoles } = require('./get') -const { update } = require('./put') -const { deleteAllocatedRole } = require('./delete') +const { create } = require("./post"); +const { allocatedRoles } = require('./get'); +const { update } = require('./put'); +const { deleteAllocatedRole } = require('./delete'); const AllocationRoleHandler = { - allocateRole, + create, allocatedRoles, update, deleteAllocatedRole, -} +}; -module.exports = AllocationRoleHandler \ No newline at end of file +module.exports = AllocationRoleHandler; diff --git a/app/api/role-user/post.js b/app/api/role-user/post.js index 11dbccb..0e1c04b 100644 --- a/app/api/role-user/post.js +++ b/app/api/role-user/post.js @@ -1,24 +1,21 @@ 'use strict' -const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/logger") -const util = require('util') +const roleAllocationService = require("../../dal/roleAllocationService"); +const logger = require("../../utils/logger"); const AllocateRoleToUser = { - async allocateRoleToUser(ctx) { + async create(ctx) { try { - ctx.body = await roleAllocationService.create(ctx.request.body) - ctx.status = 201 - logger.info('role is allocated to user successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleAllocationService.create(ctx.request.body); + ctx.status = 201; + logger.info('Role allocated to user.'); + } catch (error) { + throw error; } } -} +}; module.exports = { - allocateRole: AllocateRoleToUser.allocateRoleToUser, + create: AllocateRoleToUser.create, AllocateRoleToUser -} +}; diff --git a/app/api/role-user/put.js b/app/api/role-user/put.js index f7d7ef0..9cebeae 100644 --- a/app/api/role-user/put.js +++ b/app/api/role-user/put.js @@ -1,24 +1,21 @@ 'use strict' -const roleAllocationService = require("../../dal/roleAllocationService") -const logger = require("../../utils/logger") -const util = require('util') +const roleAllocationService = require("../../dal/roleAllocationService"); +const logger = require("../../utils/logger"); const UpdateAllocatedRole = { async update(ctx) { try { - ctx.body = await roleAllocationService.update(ctx.request.body) - ctx.status = 201 - logger.info('Allocated role is updated successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleAllocationService.update(ctx.request.body); + ctx.status = 201; + logger.info('Role allocated to user updated.'); + } catch (error) { + throw error; } } -} +}; module.exports = { update: UpdateAllocatedRole.update, UpdateAllocatedRole -} +}; diff --git a/app/dal/roleAllocationService.js b/app/dal/roleAllocationService.js index acf784e..09af151 100644 --- a/app/dal/roleAllocationService.js +++ b/app/dal/roleAllocationService.js @@ -1,78 +1,77 @@ 'use strict' -const db = require('../../db') - -const { RoleUser } = require('../models/Role') +const db = require('../../db'); +const { RoleUser } = require('../models/Role'); const RoleAllocationService = { - - // It allocates the role to user. + // Allocates a role to a user. If a role is already allocated to this user, updates it. async create(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.kc_id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const roleUser = RoleUser.findOne({ - where: { - kc_id: ctx.kc_id - } - }) - if (!roleUser) { - return await RoleUser.create({ - role_id: ctx.role_id, - kc_id: ctx.kc_id - }) - } else { + const [roleUser, created] = await RoleUser.findOrCreate({ + where: { kc_id: ctx.kc_id }, + defaults: { role_id: ctx.role_id } + }); + if (!created) { return await RoleUser.update({ role_id: ctx.role_id, }, { where: { kc_id: ctx.kc_id } - }) + }); } + return roleUser; }, - // It updates allocated user. + // Updates roles allocated to a user. async update(ctx) { - return await db('roles_users').where('id', ctx.id) - .update({ + if (!ctx || !ctx.kc_id || !ctx.role_id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + return await RoleUser.update({ role_id: ctx.role_id, }, { + where: { kc_id: ctx.kc_id - }).returning('*').then((result) => result[0]) + } + }); }, + // Deletes roles allocated to a user. async delete(ctx) { - return db.delete().from('roles_users').where('id', ctx.id).timeout(1000, {cancel: true}); + if (!ctx || !ctx.kc_id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + return await RoleUser.destroy({ + where: { + kc_id: ctx.kc_id + } + }); }, - // It returns allocated roles by kc_id. + // Get allocated roles by user kc_id. async allocatedRolesByKcId(ctx) { - try { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.kc_id) { - return await db.raw(` + if (!ctx || !ctx.kc_id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + const allocatedRoles = await db.raw(` select roles.id, u.username as user, roles.name as role , roles.description from roles inner join roles_users ru on roles.id = ru.role_id inner join users u on ru.kc_id = u.kc_id - where u.kc_id = ?`, [ctx.kc_id]) - } - } catch (err) { - throw new Error(err) - } - }, - async allocatedRoles(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - return db.raw(` - select u.username as user,r.name as role from roles r - inner join roles_users ru on r.id = ru.role_id - inner join users u on ru.kc_id = u.kc_id`); + where u.kc_id = ?`, [ctx.kc_id]); + return allocatedRoles.rows; }, -} +}; module.exports = { create: RoleAllocationService.create, allocatedRoles: RoleAllocationService.allocatedRolesByKcId, update: RoleAllocationService.update, delete: RoleAllocationService.delete -} +}; -- GitLab From 2bce9e79e2e3206d2b756d604fbb78faee8c92e7 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Fri, 22 Nov 2024 14:20:56 +0100 Subject: [PATCH 09/13] [Policy] Removed useless model in file --- app/models/Policy.js | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/app/models/Policy.js b/app/models/Policy.js index 5f79304..7b2a923 100644 --- a/app/models/Policy.js +++ b/app/models/Policy.js @@ -26,15 +26,6 @@ Policy.init( deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE, } }, - /*source_id: { - type: Sequelize.INTEGER, - allowNull: false, - references: { - model: Source, - key: "id", - deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE, - }, - },*/ }, { underscored: true, @@ -99,40 +90,6 @@ PolicySource.init({ modelName: "policy_sources", }) -// StdField.belongsTo(Policy, { through: PolicyField, foreignKey: "policy_field_policy_id_fkey", constraints: true }) -// Policy.belongsToMany(StdField, { through: PolicyField, foreignKey: "std_fields_id_fkkey", constraints: true }) -// Policy.belongsTo(StdField, { foreignKey: "std_fields_id_fkkey" }) -// StdField.belongsTo(Policy, { foreignKey: "policy_field_policy_id_fkey" }) -// Policy.belongsTo(StdField, { through: PolicyField, foreignKey: "std_fields_id_fkkey", constraints: false }) -// StdField.belongsTo(Policy, { through: PolicyField, foreignKey: "policy_field_policy_id_fkey", constraints: false }) -/* -Policy.belongsToMany(StdField, { - through: PolicyField, - uniqueKey: "policy_field_policy_id_fkey", -}); - -Policy.belongsToMany(Source, { - through: PolicyField, - uniqueKey: "policy_source_id_fkey", -}); - -StdField.belongsToMany(Policy, { - through: PolicyField, - uniqueKey: "std_fields_id_fkkey", -}); */ - - -class UserProfile extends Sequelize.Model { } - -UserProfile.init( - {}, - { - underscored: true, - sequelize: postgresSeq, - modelName: "user_profile", - } -); - module.exports = { Policy, PolicyField, -- GitLab From e96de405cfc2f2a4a595b487c6e61f500d8b346c Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Mon, 25 Nov 2024 07:45:56 +0100 Subject: [PATCH 10/13] [roles] now following new error handling ; improved some logic --- app/api/index.js | 2 +- app/api/roles/delete.js | 21 ++++++-------- app/api/roles/get.js | 33 ++++++++++------------ app/api/roles/index.js | 16 +++++------ app/api/roles/post.js | 25 ++++++++--------- app/api/roles/put.js | 21 ++++++-------- app/dal/roleService.js | 62 ++++++++++++++++++++++------------------- 7 files changed, 86 insertions(+), 94 deletions(-) diff --git a/app/api/index.js b/app/api/index.js index 43be607..3328c06 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -91,7 +91,7 @@ routers.get('/policyField/list', policyHandler.policyFields); routers.post('/policySource/add', policyHandler.createPolicySource); // Roles -routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole); +routers.post('/role',/* keycloak.protect(),*/ roleHandler.createRole); routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles); routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role); routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole); diff --git a/app/api/roles/delete.js b/app/api/roles/delete.js index de2c2c3..cd63774 100644 --- a/app/api/roles/delete.js +++ b/app/api/roles/delete.js @@ -1,24 +1,21 @@ 'use strict' -const roleService = require('../../dal/roleService') -const logger = require('../../utils/logger') -const util = require('util') +const roleService = require('../../dal/roleService'); +const logger = require('../../utils/logger'); const DeleteRole = { async deleteRole(ctx) { try { - ctx.body = await roleService.delete(ctx.request.body) - ctx.status = 201 - logger.info('role is deleted successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleService.delete(ctx.request.body); + ctx.status = 201; + logger.info('Role deleted.'); + } catch (error) { + throw error; } } -} +}; module.exports = { deleteRole: DeleteRole.deleteRole, DeleteRole, -} +}; diff --git a/app/api/roles/get.js b/app/api/roles/get.js index 9f38b47..9ae5a0f 100644 --- a/app/api/roles/get.js +++ b/app/api/roles/get.js @@ -1,37 +1,32 @@ 'use strict' -const roleService = require("../../dal/roleService") -const logger = require('../../utils/logger') -const util = require('util') +const roleService = require("../../dal/roleService"); +const logger = require('../../utils/logger'); const GetRole = { async find(ctx) { try { - ctx.body = await roleService.roles() - ctx.status = 201 - logger.info('roles are listed successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleService.roles(); + ctx.status = 201; + logger.info('Roles fetched.'); + } catch (error) { + throw error; } }, async findOne(ctx) { try { - ctx.body = await roleService.role(ctx.request.body) - ctx.status = 201 - logger.info('role is found successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleService.role(ctx.request.body); + ctx.status = 201; + logger.info('Role fetched.'); + } catch (error) { + throw error; } } -} +}; module.exports = { roles: GetRole.find, role: GetRole.findOne, GetRole -} +}; diff --git a/app/api/roles/index.js b/app/api/roles/index.js index 8e24e08..0cc31da 100644 --- a/app/api/roles/index.js +++ b/app/api/roles/index.js @@ -1,17 +1,17 @@ 'use strict' -const { addNewRole } = require('./post') -const { roles } = require('./get') -const { role } = require('./get') -const { deleteRole } = require('./delete') -const { update } = require('./put') +const { createRole } = require('./post'); +const { roles } = require('./get'); +const { role } = require('./get'); +const { deleteRole } = require('./delete'); +const { update } = require('./put'); const RoleHandler = { - addNewRole, + createRole, roles, role, deleteRole, update, -} +}; -module.exports = RoleHandler \ No newline at end of file +module.exports = RoleHandler; diff --git a/app/api/roles/post.js b/app/api/roles/post.js index 19f1311..58c83a5 100644 --- a/app/api/roles/post.js +++ b/app/api/roles/post.js @@ -1,24 +1,21 @@ 'use strict' -const roleService = require("../../dal/roleService") -const logger = require('../../utils/logger') -const util = require('util') +const roleService = require("../../dal/roleService"); +const logger = require('../../utils/logger'); const AddRole = { - async addNewRole(ctx) { + async create(ctx) { try { - ctx.body = await roleService.create(ctx.request.body) - ctx.status = 201 - logger.info('role is created successfully!') - } catch (err) { - ctx.body = err.response.data || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleService.create(ctx.request.body); + ctx.status = 201; + logger.info('Role created.'); + } catch (error) { + throw error; } } -} +}; module.exports = { - addNewRole: AddRole.addNewRole, + createRole: AddRole.create, AddRole -} +}; diff --git a/app/api/roles/put.js b/app/api/roles/put.js index 4996aa9..9ed289b 100644 --- a/app/api/roles/put.js +++ b/app/api/roles/put.js @@ -1,24 +1,21 @@ 'use strict' -const roleService = require('../../dal/roleService') -const logger = require('../../utils/logger') -const util = require('util') +const roleService = require('../../dal/roleService'); +const logger = require('../../utils/logger'); const UpdateRole = { async update(ctx) { try { - ctx.body = await roleService.update(ctx.request.body) - ctx.status = 201 - logger.info('role is updated successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await roleService.update(ctx.request.body); + ctx.status = 201; + logger.info('Role updated.'); + } catch (error) { + throw error; } } -} +}; module.exports = { update: UpdateRole.update, UpdateRole -} +}; diff --git a/app/dal/roleService.js b/app/dal/roleService.js index 036c97e..8589381 100644 --- a/app/dal/roleService.js +++ b/app/dal/roleService.js @@ -1,31 +1,38 @@ "use strict" -const db = require('../../db') +const db = require('../../db'); +const { Role, RoleUser } = require('../models/Role'); -const { Role, RoleUser } = require('../models/Role') const RoleService = { // Get all roles - async roles(ctx) { - return db.select().from('roles').timeout(1000, {cancel: true}); + async roles() { + return await Role.findAll(); }, // Get a role - role: async function (ctx) { - return db.select().from('roles').where('id', ctx.id).timeout(1000, {cancel: true}); + async role(ctx) { + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + return await Role.findAll({where: {'id': ctx.id}}); }, - // Delete role by id - async delete(ctx) { - return db.delete().from('roles').where('id', ctx.id).timeout(1000, {cancel: true}) - }, // Update role by id async update(ctx) { - return await db('roles').where('id', ctx.id) - .update({ - name: ctx.name, - description: ctx.description - }).returning('*').then((result) => result[0]) + if (!ctx || !ctx.id || !ctx.name || !ctx.description) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + return await Role.update({ + 'name': ctx.name, + 'description': ctx.description + }, { + where: {'id': ctx.id} + }); }, // Create a role @@ -33,24 +40,23 @@ const RoleService = { return await db('roles').insert({ name: ctx.name, description: ctx.description - }).returning('*').then((result) => result[0]) + }).returning('*').then((result) => result[0]); }, - // Delete a role - async deleteRole(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + + // Delete role + async delete(ctx) { + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } await RoleUser.destroy({ where: { role_id: ctx.id } - }) - return await Role.destroy({ - where: { - id: ctx.id - } - }) + }); + return await Role.destroy({where: {'id': ctx.id}}); }, } @@ -58,6 +64,6 @@ module.exports = { create: RoleService.create, roles: RoleService.roles, role: RoleService.role, - delete: RoleService.deleteRole, + delete: RoleService.delete, update: RoleService.update, -} +}; -- GitLab From 84d27368d28d7d1b96de8be20d1f0ced6e326d3a Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Mon, 25 Nov 2024 08:14:23 +0100 Subject: [PATCH 11/13] [userRequests] now following new error handling ; improved some logic --- app/api/user-requests/delete.js | 21 ++++----- app/api/user-requests/get.js | 29 +++++-------- app/api/user-requests/index.js | 10 ++--- app/api/user-requests/post.js | 43 ++++++++---------- app/dal/userRequestService.js | 77 +++++++++++++++++---------------- 5 files changed, 83 insertions(+), 97 deletions(-) diff --git a/app/api/user-requests/delete.js b/app/api/user-requests/delete.js index 170ecf5..d1be7f9 100644 --- a/app/api/user-requests/delete.js +++ b/app/api/user-requests/delete.js @@ -1,24 +1,21 @@ 'use strict' -const userRequestService = require('../../dal/userRequestService') -const logger = require('../../utils/logger') -const util = require('util') +const userRequestService = require('../../dal/userRequestService'); +const logger = require('../../utils/logger'); const UserRequest = { async delete(ctx) { try { - ctx.body = await userRequestService.delete(ctx.request.body) - ctx.status = 201 - logger.info('user request deleted successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userRequestService.delete(ctx.request.body); + ctx.status = 201; + logger.info('User request deleted.'); + } catch (error) { + throw error; } } -} +}; module.exports = { deleteRequest: UserRequest.delete, UserRequest -} +}; diff --git a/app/api/user-requests/get.js b/app/api/user-requests/get.js index cd0e420..b62ee08 100644 --- a/app/api/user-requests/get.js +++ b/app/api/user-requests/get.js @@ -1,37 +1,32 @@ 'use strict' -const userRequestService = require('../../dal/userRequestService') -const logger = require('../../utils/logger') -const util = require('util') +const userRequestService = require('../../dal/userRequestService'); +const logger = require('../../utils/logger'); const UserRequest = { async list(ctx) { try { - ctx.body = await userRequestService.fetch(ctx.request.body) - ctx.status = 201 - logger.info('user requests fetched successfully!') + ctx.body = await userRequestService.fetch(); + ctx.status = 201; + logger.info('User requests fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } }, async listPending(ctx) { try { - ctx.body = await userRequestService.fetchPending(ctx.request.body) - ctx.status = 201 - logger.info('user requests fetched successfully!') + ctx.body = await userRequestService.fetchPending(); + ctx.status = 201; + logger.info('Pending user requests fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { fetchRequests: UserRequest.list, fetchPendingRequests: UserRequest.listPending, UserRequest -} +}; diff --git a/app/api/user-requests/index.js b/app/api/user-requests/index.js index 310ac8d..8d0a9ea 100644 --- a/app/api/user-requests/index.js +++ b/app/api/user-requests/index.js @@ -1,8 +1,8 @@ 'use strict' -const { createRequest, processRequest, fetchRequestsByUser } = require('./post') -const { fetchRequests, fetchPendingRequests } = require('./get') -const { deleteRequest } = require('./delete') +const { createRequest, processRequest, fetchRequestsByUser } = require('./post'); +const { fetchRequests, fetchPendingRequests } = require('./get'); +const { deleteRequest } = require('./delete'); const UserRequestHandler = { createRequest, @@ -11,6 +11,6 @@ const UserRequestHandler = { fetchPendingRequests, fetchRequestsByUser, deleteRequest -} +}; -module.exports = UserRequestHandler \ No newline at end of file +module.exports = UserRequestHandler; diff --git a/app/api/user-requests/post.js b/app/api/user-requests/post.js index 3644ebf..d0b90af 100644 --- a/app/api/user-requests/post.js +++ b/app/api/user-requests/post.js @@ -1,50 +1,43 @@ 'use strict' -const userRequestService = require('../../dal/userRequestService') -const logger = require('../../utils/logger') -const util = require('util') +const userRequestService = require('../../dal/userRequestService'); +const logger = require('../../utils/logger'); const UserRequest = { async create(ctx) { try { - ctx.body = await userRequestService.create(ctx.request.body) - ctx.status = 201 - logger.info('user request created successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userRequestService.create(ctx.request.body); + ctx.status = 201; + logger.info('User request created.'); + } catch (error) { + throw error; } }, async process(ctx) { try { - ctx.body = await userRequestService.process(ctx.request.body) - ctx.status = 201 - logger.info('user request processed successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userRequestService.process(ctx.request.body); + ctx.status = 201; + logger.info('User request processed.'); + } catch (error) { + throw error; } }, async listByUser(ctx) { try { - ctx.body = await userRequestService.fetchByUser(ctx.request.body) - ctx.status = 201 - logger.info('user requests fetched successfully!') + ctx.body = await userRequestService.fetchByUser(ctx.request.body); + ctx.status = 201; + logger.info('User requests fetched by user.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { createRequest: UserRequest.create, processRequest: UserRequest.process, fetchRequestsByUser: UserRequest.listByUser, UserRequest -} +}; diff --git a/app/dal/userRequestService.js b/app/dal/userRequestService.js index 9e7518c..d0c0c10 100644 --- a/app/dal/userRequestService.js +++ b/app/dal/userRequestService.js @@ -1,73 +1,74 @@ 'use strict' const userService = require("./userService"); - const { UserRequest } = require('../models/UserRequest'); -const db = require('../../db'); - const UserRequestService = { async create(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") + if (!ctx || !ctx.kcId || !ctx.message) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - return await UserRequest.create({ - user_id: user.id, - request_message: ctx.message, - is_processed: false, - }) - } else { - throw Error('The user account could not found.') + const user = await userService.detail({ kcId: ctx.kcId }); + if (!user) { + const error = new Error("User account not found."); + error.status = 400; + throw error; } + return await UserRequest.create({ + user_id: user.id, + request_message: ctx.message, + is_processed: false, + }); }, async getAllRequests() { - return await UserRequest.findAll({}) + return await UserRequest.findAll({}); }, async getUserRequests(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } const user = await userService.detail({ kcId: ctx.kcId }) if (user) { - return db.select("*").from('user_requests').where('user_id', user.id).timeout(1000, {cancel: true}); + return await UserRequest.findAll({ + where: { + user_id: user.id + } + }); } }, - async getPendingRequests(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } + async getPendingRequests() { return await UserRequest.findAll({ where: { is_processed: false } - }) + }); }, - async update(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + async process(ctx) { + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await UserRequest.update({ is_processed: true, }, { where: {id: ctx.id} - }) + }); }, async delete(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } return await UserRequest.destroy({ where: { @@ -79,9 +80,9 @@ const UserRequestService = { module.exports = { create: UserRequestService.create, - process: UserRequestService.update, - delete: UserRequestService.delete, fetch: UserRequestService.getAllRequests, fetchPending: UserRequestService.getPendingRequests, - fetchByUser: UserRequestService.getUserRequests + fetchByUser: UserRequestService.getUserRequests, + process: UserRequestService.process, + delete: UserRequestService.delete, } -- GitLab From b4ca83753715d3351cd55db9a58a823968a7b82a Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Mon, 25 Nov 2024 13:35:52 +0100 Subject: [PATCH 12/13] [userSearchHistory] now following new error handling ; improved some logic --- app/api/index.js | 5 +- app/api/user-search-history/delete.js | 21 +++---- app/api/user-search-history/get.js | 19 +++---- app/api/user-search-history/index.js | 14 ++--- app/api/user-search-history/post.js | 23 ++++---- app/dal/searchHistoryService.js | 80 +++++++++++++-------------- 6 files changed, 75 insertions(+), 87 deletions(-) diff --git a/app/api/index.js b/app/api/index.js index 3328c06..ee7c2fb 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -13,6 +13,7 @@ const userRequestHandler = require('./user-requests'); const groupHandler = require('./group'); const policyHandler = require('./policy'); const UserFieldsDisplaySettingsHandler = require("./user-fields-display-settings"); +const {deleteUserSearchHistory} = require("./user-search-history/delete"); const routers = new Router(); @@ -41,9 +42,9 @@ routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole); routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole); // Search history -routers.post('/user/add-history', searchHistoryHandler.add); +routers.post('/user/add-history', searchHistoryHandler.create); routers.post('/user/fetch-history', searchHistoryHandler.fetch); -routers.delete('/user/delete-history', searchHistoryHandler.deleteH); +routers.delete('/user/delete-history', searchHistoryHandler.deleteUserSearchHistory); // User fields display settings routers.post('/user/fields-display-settings/', /* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.createUserFieldsDisplaySettings); diff --git a/app/api/user-search-history/delete.js b/app/api/user-search-history/delete.js index e483e80..a1f7ef9 100644 --- a/app/api/user-search-history/delete.js +++ b/app/api/user-search-history/delete.js @@ -1,24 +1,21 @@ 'use strict' -const searchHistoryService = require('../../dal/searchHistoryService') -const logger = require('../../utils/logger') -const util = require('util') +const searchHistoryService = require('../../dal/searchHistoryService'); +const logger = require('../../utils/logger'); const SearchHistory = { async delete(ctx) { try { - ctx.body = await searchHistoryService.delete(ctx.request.body) - ctx.status = 201 - logger.info('search history is deleted successfully!') + ctx.body = await searchHistoryService.delete(ctx.request.body); + ctx.status = 201; + logger.info('User search history deleted.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { - deleteH: SearchHistory.delete, + deleteUserSearchHistory: SearchHistory.delete, SearchHistory -} +}; diff --git a/app/api/user-search-history/get.js b/app/api/user-search-history/get.js index 7ecb996..e8cc7b7 100644 --- a/app/api/user-search-history/get.js +++ b/app/api/user-search-history/get.js @@ -1,24 +1,21 @@ 'use strict' -const searchHistoryService = require('../../dal/searchHistoryService') -const logger = require('../../utils/logger') -const util = require('util') +const searchHistoryService = require('../../dal/searchHistoryService'); +const logger = require('../../utils/logger'); const SearchHistory = { async list(ctx) { try { - ctx.body = await searchHistoryService.fetch(ctx.request.body) - ctx.status = 201 - logger.info('search history is fetched successfully!') + ctx.body = await searchHistoryService.fetch(ctx.request.body); + ctx.status = 201; + logger.info('User search history fetched.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { fetch: SearchHistory.list, SearchHistory -} +}; diff --git a/app/api/user-search-history/index.js b/app/api/user-search-history/index.js index ec1d92b..7dab270 100644 --- a/app/api/user-search-history/index.js +++ b/app/api/user-search-history/index.js @@ -1,13 +1,13 @@ 'use strict' -const { add } = require('./post') -const { fetch } = require('./get') -const { deleteH } = require('./delete') +const { create } = require('./post'); +const { fetch } = require('./get'); +const { deleteUserSearchHistory } = require('./delete'); const SearchHistoryHandler = { - add, + create, fetch, - deleteH -} + deleteUserSearchHistory +}; -module.exports = SearchHistoryHandler \ No newline at end of file +module.exports = SearchHistoryHandler; diff --git a/app/api/user-search-history/post.js b/app/api/user-search-history/post.js index 30b21c4..5739977 100644 --- a/app/api/user-search-history/post.js +++ b/app/api/user-search-history/post.js @@ -1,24 +1,21 @@ 'use strict' -const searchHistoryService = require('../../dal/searchHistoryService') -const logger = require('../../utils/logger') -const util = require('util') +const searchHistoryService = require('../../dal/searchHistoryService'); +const logger = require('../../utils/logger'); const SearchHistory = { - async add(ctx) { + async create(ctx) { try { - ctx.body = await searchHistoryService.create(ctx.request.body) - ctx.status = 201 - logger.info('search history is created successfully!') + ctx.body = await searchHistoryService.create(ctx.request.body); + ctx.status = 201; + logger.info('Search history created.'); } catch (error) { - ctx.body = error.response || 'erroror occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`) + throw error; } } -} +}; module.exports = { - add: SearchHistory.add, + create: SearchHistory.create, SearchHistory -} +}; diff --git a/app/dal/searchHistoryService.js b/app/dal/searchHistoryService.js index e3f1b0e..0fb9df3 100644 --- a/app/dal/searchHistoryService.js +++ b/app/dal/searchHistoryService.js @@ -1,73 +1,69 @@ 'use strict' const userService = require("./userService"); - const { SearchHistory } = require('../models/UserHistory'); const SearchHistoryService = { async create(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") + if (!ctx || !ctx.kcId || !ctx.query || !ctx.name || !ctx.uiStructure || !ctx.description) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - return await SearchHistory.create({ - kc_id: user.kc_id, - query: ctx.query, - name: ctx.name, - ui_structure: ctx.uiStructure, - description: ctx.description - }) - } else { - throw Error('The user account could not found.') + const user = await userService.detail({ kcId: ctx.kcId }); + if (!user) { + const error = new Error("User account not found."); + error.status = 400; + throw error; } + return await SearchHistory.create({ + kc_id: user.kc_id, + query: ctx.query, + name: ctx.name, + ui_structure: ctx.uiStructure, + description: ctx.description + }) }, - async getSearchHistories(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.kcId === undefined) { - throw Error("kcId did not supported.") - } - const user = await userService.detail({ kcId: ctx.kcId }) - if (user) { - return await SearchHistory.findAll({ - where: { - kc_id: user.kc_id - } - }) + async fetchUserSearchHistory(ctx) { + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + return await SearchHistory.findAll({ + where: { + kc_id: ctx.kcId + } + }); }, async update(ctx) { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.kc_id === undefined) { - throw Error("kcId did not supported.") + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + // Not finished ? I don't know why there is no method call to update db. }, async delete(ctx) { - if (!ctx) { - throw Error("The request body is empty!") + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - return await SearchHistory.destroy({ where: { id: ctx.id } }); } -} +}; module.exports = { create: SearchHistoryService.create, update: SearchHistoryService.update, delete: SearchHistoryService.delete, - fetch: SearchHistoryService.getSearchHistories -} + fetch: SearchHistoryService.fetchUserSearchHistory +}; -- GitLab From eac5ea552c31b4eb0362ba62bb4d054c6d8a7574 Mon Sep 17 00:00:00 2001 From: rbisson <remi.bisson@inrae.fr> Date: Tue, 26 Nov 2024 15:52:08 +0100 Subject: [PATCH 13/13] [users] now following new error handling ; improved some logic --- app/api/index.js | 3 +- app/api/users/delete.js | 19 +- app/api/users/get.js | 64 ++-- app/api/users/index.js | 16 +- app/api/users/post.js | 64 ++-- app/api/users/put.js | 21 +- app/dal/userService.js | 685 ++++++++++++++++++---------------------- 7 files changed, 380 insertions(+), 492 deletions(-) diff --git a/app/api/index.js b/app/api/index.js index ee7c2fb..a69d35f 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -13,7 +13,6 @@ const userRequestHandler = require('./user-requests'); const groupHandler = require('./group'); const policyHandler = require('./policy'); const UserFieldsDisplaySettingsHandler = require("./user-fields-display-settings"); -const {deleteUserSearchHistory} = require("./user-search-history/delete"); const routers = new Router(); @@ -25,7 +24,7 @@ routers.get('/healthcheck', (ctx) => { }); // Users -routers.post('/user', userHandler.addNewUser); +routers.post('/user', userHandler.create); routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user); routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users); routers.delete('/user/delete',/* keycloak.protect(),*/ userHandler.deleteUser); diff --git a/app/api/users/delete.js b/app/api/users/delete.js index 609c696..ebe5496 100644 --- a/app/api/users/delete.js +++ b/app/api/users/delete.js @@ -1,22 +1,19 @@ 'use strict' -const userService = require("../../dal/userService") -const logger = require('../../utils/logger') -const util = require('util') +const userService = require("../../dal/userService"); +const logger = require('../../utils/logger'); const DeleteUser = { async deleteUser(ctx) { try { - ctx.body = await userService.delete(ctx.request.body) - ctx.status = 201 - logger.info('user is deleted successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userService.delete(ctx.request.body); + ctx.status = 201; + logger.info('User deleted.'); + } catch (error) { + throw error; } } -} +}; module.exports = { deleteUser: DeleteUser.deleteUser, diff --git a/app/api/users/get.js b/app/api/users/get.js index d998078..f35efd2 100644 --- a/app/api/users/get.js +++ b/app/api/users/get.js @@ -1,44 +1,36 @@ "use strict"; const userService = require("../../dal/userService"); -const logger = require('../../utils/logger') -const util = require('util') +const logger = require('../../utils/logger'); const GetUser = { async find(ctx) { try { - ctx.body = await userService.users() - ctx.status = 201 - logger.info('users is listed successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) - + ctx.body = await userService.users(); + ctx.status = 201; + logger.info('Users fetched.'); + } catch (error) { + throw error; } }, async findOne(ctx) { try { - ctx.body = await userService.user(ctx.request.body) - ctx.status = 201 - logger.info('user is found successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userService.user(ctx.request.body); + ctx.status = 201; + logger.info('User fetched.'); + } catch (error) { + throw error; } }, async kcId(ctx) { try { ctx.body = await userService.kcId(ctx.request.body); - ctx.status = 201 - logger.info('kcId is found successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.status = 201; + logger.info('User kc_id fetched.'); + } catch (error) { + throw error; } }, @@ -46,11 +38,9 @@ const GetUser = { try { ctx.body = await userService.detail(ctx.request.body); ctx.status = 201; - logger.info('user_detail is found successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + logger.info('User details fetched.'); + } catch (error) { + throw error; } }, @@ -58,23 +48,19 @@ const GetUser = { try { ctx.body = await userService.getAssignedUserByRole(ctx.request.body); ctx.status = 201; - logger.info('Assigned users listed successfully by Role!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + logger.info('Users fetched by role.'); + } catch (error) { + throw error; } }, async usersWithGroupAndRole(ctx) { try { - ctx.body = await userService.usersWithGroupAndRole(ctx.request.body); + ctx.body = await userService.usersWithGroupAndRole(); ctx.status = 201; - logger.info('Users listed with groups and roles successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + logger.info('Users with groups and roles fetched.'); + } catch (error) { + throw error; } } }; diff --git a/app/api/users/index.js b/app/api/users/index.js index 7def803..c228799 100644 --- a/app/api/users/index.js +++ b/app/api/users/index.js @@ -1,14 +1,12 @@ "use strict"; -const { addNewUser, createSystemUser, sendMail, userWithGroupAndRole, resetPassword } = require('./post') -const { user, detail, getAssignedUserByRole, usersWithGroupAndRole } = require('./get') -const { users } = require('./get') -const { deleteUser } = require('./delete') -const { update } = require('./put') -const { kcId } = require('./get') +const { create, createSystemUser, sendMail, userWithGroupAndRole, resetPassword } = require('./post'); +const { user, users, kcId, detail, getAssignedUserByRole, usersWithGroupAndRole } = require('./get'); +const { deleteUser } = require('./delete'); +const { update } = require('./put'); const UserHandler = { - addNewUser, + create, user, users, deleteUser, @@ -21,6 +19,6 @@ const UserHandler = { userWithGroupAndRole, sendMail, resetPassword -} +}; -module.exports = UserHandler +module.exports = UserHandler; diff --git a/app/api/users/post.js b/app/api/users/post.js index 9acf501..87e5d64 100644 --- a/app/api/users/post.js +++ b/app/api/users/post.js @@ -1,46 +1,36 @@ 'use strict' -const userService = require("../../dal/userService") -const logger = require('../../utils/logger') -const util = require('util') +const userService = require("../../dal/userService"); +const logger = require('../../utils/logger'); const AddUser = { - /** - * @param {username,email} ctx - */ - async addNewUser(ctx) { + async create(ctx) { try { - ctx.body = await userService.create(ctx.request.body) - ctx.status = 201 - logger.info('user is created successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userService.create(ctx.request.body); + ctx.status = 201; + logger.info('User created.'); + } catch (error) { + throw error; } }, async createSystemUser(ctx) { try { - ctx.body = await userService.createSystemUser(ctx.request.body) - ctx.status = 201 - logger.info('System user (admin) is created successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userService.createSystemUser(); + ctx.status = 201; + logger.info('System user (admin) created.'); + } catch (error) { + throw error; } }, async sendMail(ctx) { try { - ctx.body = await userService.sendMail(ctx.request.body) - ctx.status = 201 - logger.info('mail sent successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userService.sendMail(ctx.request.body); + ctx.status = 201; + logger.info('Mail sent.'); + } catch (error) { + throw error; } }, @@ -48,11 +38,9 @@ const AddUser = { try { ctx.body = await userService.userWithGroupAndRole(ctx.request.body); ctx.status = 201; - logger.info('Found user with groups and roles successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + logger.info('User with groups and roles fetched.'); + } catch (error) { + throw error; } }, @@ -60,17 +48,15 @@ const AddUser = { try { ctx.body = await userService.resetPassword(ctx.request.body); ctx.status = 201; - logger.info('Reset password successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500; - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + logger.info('Password reset.'); + } catch (error) { + throw error; } } } module.exports = { - addNewUser: AddUser.addNewUser, + create: AddUser.create, createSystemUser: AddUser.createSystemUser, sendMail: AddUser.sendMail, userWithGroupAndRole: AddUser.userWithGroupAndRole, diff --git a/app/api/users/put.js b/app/api/users/put.js index b7b7322..3d5db10 100644 --- a/app/api/users/put.js +++ b/app/api/users/put.js @@ -1,24 +1,21 @@ 'use strict' -const userService = require("../../dal/userService") -const logger = require('../../utils/logger') -const util = require('util') +const userService = require("../../dal/userService"); +const logger = require('../../utils/logger'); const UpdateUser = { async update(ctx) { try { - ctx.body = await userService.update(ctx.request.body) - ctx.status = 201 - logger.info('user is updated successfully!') - } catch (err) { - ctx.body = err || 'Error occurred!' - ctx.status = 500 - logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`) + ctx.body = await userService.update(ctx.request.body); + ctx.status = 201; + logger.info('User updated.'); + } catch (error) { + throw error; } } -} +}; module.exports = { update: UpdateUser.update, UpdateUser -} +}; diff --git a/app/dal/userService.js b/app/dal/userService.js index 5741920..aed849e 100644 --- a/app/dal/userService.js +++ b/app/dal/userService.js @@ -1,469 +1,394 @@ "use strict" -const KcAdminClient = require("keycloak-admin").default -const { Issuer } = require("openid-client") -const db = require('../../db') -const { User } = require('../models/User') -const { RoleUser } = require('../models/Role') -const { postgresSeq } = require('../config/db') -const { BotService, MailService } = require('@in-sylva/common') +const KcAdminClient = require("keycloak-admin").default; +const db = require('../../db'); +const { User } = require('../models/User'); +const { RoleUser } = require('../models/Role'); +const { postgresSeq } = require('../config/db'); +const { BotService, MailService } = require('@in-sylva/common'); const { Op } = require("sequelize"); -const bcrypt = require('bcrypt') +const bcrypt = require('bcrypt'); -const mailService = new MailService() +const mailService = new MailService(); +mailService.auth_user = process.env.IN_SYLVA_EMAIL; +mailService.auth_pass = process.env.IN_SYLVA_EMAIL_PASSWORD; +mailService.smtp_host = process.env.IN_SYLVA_SMTP_HOST; +mailService.smtp_port = process.env.IN_SYLVA_SMTP_PORT; +mailService.smtp_secure = true; -mailService.auth_user = process.env.IN_SYLVA_EMAIL -mailService.auth_pass = process.env.IN_SYLVA_EMAIL_PASSWORD -mailService.smtp_host = process.env.IN_SYLVA_SMTP_HOST -mailService.smtp_port = process.env.IN_SYLVA_SMTP_PORT -mailService.smtp_secure = true - -const botService = new BotService() - -botService.token = process.env.BOT_SERVICE_TOKEN -botService.channel = process.env.BOT_SERVICE_CHANNEL +const botService = new BotService(); +botService.token = process.env.BOT_SERVICE_TOKEN; +botService.channel = process.env.BOT_SERVICE_CHANNEL; const keycloakAdmin = new KcAdminClient({ baseUrl: `${process.env.IN_SYLVA_KEYCLOAK_HOST}:${process.env.IN_SYLVA_KEYCLOAK_PORT}/keycloak/auth`, realmName: "master" -}) +}); -async function auth() { +const auth = async () => { await keycloakAdmin.auth({ username: process.env.KEYCLOAK_USERNAME, password: process.env.KEYCLOAK_PASSWORD, grantType: process.env.KEYCLOAK_GRANT_TYPE, clientId: process.env.KEYCLOAK_CLIENT_ID, - }) + }); } -async function generatePassword(length) { - const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", - retVal = [] +const generatePassword = async (length) => { + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", retVal = []; for (let i = 0, n = charset.length; i < length; ++i) { - retVal.push(charset.charAt(Math.floor(Math.random() * n))) + retVal.push(charset.charAt(Math.floor(Math.random() * n))); } - return retVal.join("") -} - -async function tokenRefresher() { - const keycloakIssuer = await Issuer.discover( - `${process.env.IN_SYLVA_KEYCLOAK_HOST}:${process.env.IN_SYLVA_KEYCLOAK_PORT}/auth/realms/master` - ) - - const client = new keycloakIssuer.Client({ - client_id: "admin-cli" // Same as `clientId` passed to client.auth() - }) - - // Periodically using refresh_token grant flow to get new access token here - setInterval(async () => { - const refreshToken = tokenSet.refresh_token - tokenSet = await client.refresh(keycloakAdmin.accessToken) - kcAdminClient.setAccessToken(tokenSet.access_token) - }, 58 * 1000) // 58 seconds + const password = retVal.join(""); + const salt = bcrypt.genSaltSync(); + return bcrypt.hashSync(password, salt); } const UserService = { - async resetPassword(ctx) { + // POST Create a user account + async create(ctx) { + if (!ctx || !ctx.username || !ctx.email || !ctx.password) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + // Check roleId or assign to default role "normal-user" + const roleId = ctx.roleId || 3; + // TODO fetch roles ids and verify that ctx.roleId is included + // TODO assign roleId of normal-user dynamically ? instead of hard-coded value 3 + if (![1, 2, 3].includes(roleId)) { + const error = new Error("RoleId must be either 1, 2 or 3."); + error.status = 400; + throw error; + } const t = await postgresSeq.transaction(); - try { - if (!ctx) { - throw Error("The request body is empty!"); - } - await auth(); - const users = await keycloakAdmin.users.find({ + await auth(); + const [newUser, isCreated] = await User.findOrCreate({ + where: { + username: ctx.username, email: ctx.email, - realm: process.env.KEYCLOAK_REALM, - }); - if (users.length > 0) { - const user = users[0]; - const password = await generatePassword(10); - const salt = bcrypt.genSaltSync() - const hashedPassword = bcrypt.hashSync(password, salt) - // Update user in insylva db. - const [updatedRows, _] = await User.update({ - password: hashedPassword, - }, { - where: { - kc_id: user.id, - }, - }); - if (updatedRows > 0) { - // Update user in keycloak db. - await keycloakAdmin.users.resetPassword({ - id: user.id, - credential: { - temporary: false, - type: 'password', - value: password, - }, - realm: process.env.KEYCLOAK_REALM, - }); - this.sendMail({ ...ctx, subject: "Password reset", message: `Your new password is ${password}` }); - t.commit(); - return { status: 200, message: "Password reset successfully" }; - } - else { - t.rollback(); - return { status: 500, message: "Password reset failed" }; - } - } + }, + defaults: { + password: ctx.password + }, + }); + if (!isCreated) { + const error = new Error(`User ${ctx.email} or ${ctx.username} already exists.`); + error.status = 400; + throw error; } - catch (err) { - t.rollback(); - ctx.status = err.status || 500 - ctx.body = err.message - throw Error(err) + // Insert new user into keycloak db + const kcUser = await keycloakAdmin.users.create({ + username: ctx.username, + email: ctx.email, + emailVerified: true, + enabled: true, + realm: process.env.KEYCLOAK_REALM, + }); + if (!kcUser.id) { + await t.rollback(); } + // Set new user's password in kc + await keycloakAdmin.users.resetPassword({ + id: kcUser.id, + credential: { + temporary: false, + type: 'password', + value: ctx.password + }, + realm: process.env.KEYCLOAK_REALM, + }); + // Set user kc_id in db + await User.update({ + kc_id: kcUser.id + }, { + where: { + id: newUser.id + } + }); + // User Role allocation, default user is normal-user + await RoleUser.create({ + role_id: roleId, + kc_id: kcUser.id + }) + await t.commit(); + const date = new Date().toLocaleDateString(); + const message = `[INFO]:[User ${ctx.username} is created with this email address: ${ctx.email} successfully.]:[${date}]`; + const subject = "In-Sylva new user added"; + await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, process.env.IN_SYLVA_EMAIL_TO, subject, "", message); + await botService.message(message); + return newUser; }, // GET list users - // Backlog: security vulnerability - // Realm structure should implement here. - async users(ctx) { - try { - await auth() + // Backlog: security vulnerability. Realm structure should implement here. + async users(){ + await auth(); return await keycloakAdmin.users.find({ realm: process.env.KEYCLOAK_REALM - }) - } - catch (err) { - ctx.status = err.status || 500 - ctx.body = err.message - throw Error(err) - } - }, - - // PUT update the user. - async update(ctx) { - await auth() - const userId = ctx.id - keycloakAdmin.setConfig({ - realmName: process.env.KEYCLOAK_REALM - }) - - await keycloakAdmin.users.update( - { id: userId }, - { - firstName: ctx.firstName, - lastName: ctx.lastName, - // email: ctx.email, - //requiredActions: [RequiredActionAlias.UPDATE_PASSWORD], - emailVerified: true, - }) - - const user = await keycloakAdmin.users.findOne({ - id: userId, realm: process.env.KEYCLOAK_REALM, - }) - - await db('users').where('kc_id', userId) - .update({ - firstname: ctx.firstName, - lastname: ctx.lastName - }).returning('*').then((result) => result[0]) - return user - }, - - // DELETE the user - async delete(ctx) { - try { - if (!ctx) { - throw Error("The request body is empty!") - } - await auth() - const userId = ctx.userId - if (userId) { - const deleted = await User.destroy({ - where: { - kc_id: userId - } - }) - if (deleted) { - return await keycloakAdmin.users.del({ - id: userId, - realm: process.env.KEYCLOAK_REALM - }) - } - } - } catch (error) { - ctx.status = error.status || 500 - ctx.body = error.message - throw Error(error) - } + }); }, - // GET single user + // GET Fetch single user async user(ctx) { - try { - await auth() - return await keycloakAdmin.users.findOne({ - id: ctx.id, realm: process.env.KEYCLOAK_REALM, - }) - } catch (err) { - ctx.status = err.status || 500 - ctx.body = err.message - throw Error(err) + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + await auth(); + return await keycloakAdmin.users.findOne({ + id: ctx.id, realm: process.env.KEYCLOAK_REALM, + }); }, + // GET kc_id from email async kcId(ctx) { - try { - if (!ctx) { - throw Error("The request body is empty!") - } - if (!ctx.email) { - throw Error("The email field is empty!") - } - const { kc_id } = await db.select('kc_id').from('users').where('email', ctx.email).timeout(1000, { cancel: true }).then((result) => result[0]) - const role = await RoleUser.findOne({ - attributes: ['role_id'], - where: { - kc_id: kc_id - } - }) - return { kcId: kc_id, role: role } - } catch (err) { - ctx.status = err.status || 500 - ctx.body = err.message - throw Error(err) + if (!ctx || !ctx.email) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + const { kc_id } = await db.select('kc_id').from('users').where('email', ctx.email).timeout(1000, { cancel: true }).then((result) => result[0]); + const role = await RoleUser.findOne({ + attributes: ['role_id'], + where: { + kc_id: kc_id + } + }); + return { kcId: kc_id, role: role }; }, + // GET user account details + // TODO return user details such as roles and policies async detail(ctx) { - try { - if (!ctx) { - throw Error("The request body is empty!") - } - return await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, {cancel: true}).then((result) => result[0]) - // TODO return user details such as roles and policies - } catch (error) { - ctx.status = error.status || 500 - ctx.body = error.message - throw Error(error) + if (!ctx || !ctx.kcId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + return await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, {cancel: true}).then((result) => result[0]); }, - async create(ctx) { - const t = await postgresSeq.transaction() - try { - await auth() - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.username && ctx.email && ctx.password) { - const checkUser = await User.findAndCountAll({ - where: { - [Op.or]: [ - { username: ctx.username }, - { email: ctx.email } - ] - } - }) - if (checkUser.count > 0) { - return { user: null, status: 409, message: `"${ctx.email}" or "${ctx.username}" already exist, please try again with different credentials.` } - } - const roleId = (ctx.roleId === 0 || ctx.roleId === undefined) ? 3 : ctx.roleId - if (!!roleId && roleId === 0) { - throw Error("The roleId is empty!") - } - // Insert this new user into insylva db. - const newUser = await User.create({ - username: ctx.username, - email: ctx.email, - password: ctx.password - }) - if (newUser.id) { - // Insert new user into keycloak db - const kcUser = await keycloakAdmin.users.create({ - username: ctx.username, - email: ctx.email, - emailVerified: true, - enabled: true, - realm: process.env.KEYCLOAK_REALM, - }) - if (kcUser.id) { - // Set new user's password - await keycloakAdmin.users.resetPassword({ - id: kcUser.id, - credential: { - temporary: false, - type: 'password', - value: ctx.password - }, - realm: process.env.KEYCLOAK_REALM, - }) - const update = await User.update({ - kc_id: kcUser.id - }, { - where: { - id: newUser.id - } - }) - if (update) { - // User Role allocation, default user is normal-user - await RoleUser.create({ - role_id: roleId, - kc_id: kcUser.id - }) - } - } - } else { - await t.rollback() - } - await t.commit() - const date = new Date().toLocaleDateString() - const message = `[INFO]:[User ${ctx.username} is created with this email address: ${ctx.email} successfully.]:[${date}]` - const subject = "In-Sylva new user added" - await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, process.env.IN_SYLVA_EMAIL_TO, subject, "", message) - await botService.message(message) - return { user: newUser, status: 201 } - } - } catch (error) { - await t.rollback() - throw new Error(error) + // GET users assigned to a role + async getAssignedUserByRole(ctx) { + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } + const params = { roleId: ctx.id }; + const assignedUserByRole = await db.raw(` + select u.username as username,u.email as useremail, r.name as rolename from roles r + inner join roles_users ru on r.id = ru.role_id + inner join users u on ru.kc_id = u.kc_id + where r.id = :roleId + `, params); + return assignedUserByRole.rows; }, - async sendMail(ctx) { - try { - if (!ctx) { - throw Error("The request body is empty!") - } - if (ctx.subject && ctx.message) { - const subject = ctx.subject - const message = ctx.message - await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, ctx.email, subject, "", message) - await botService.message(message) - return { status: 201 } - } else { - throw Error("The message is missing!") - } - } catch (error) { - ctx.status = error.status || 500 - ctx.body = error.message - throw Error(error) + // PUT update the user. + async update(ctx) { + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - + await auth(); + const userId = ctx.id + keycloakAdmin.setConfig({ + realmName: process.env.KEYCLOAK_REALM + }); + await keycloakAdmin.users.update( + { id: userId }, + { + firstName: ctx.firstName, + lastName: ctx.lastName, + // email: ctx.email, + emailVerified: true, + }); + const user = await keycloakAdmin.users.findOne({ + id: userId, realm: process.env.KEYCLOAK_REALM, + }); + await db('users').where('kc_id', userId).update({ + firstname: ctx.firstName, + lastname: ctx.lastName + }).returning('*').then((result) => result[0]); + return user; }, - async getAssignedUserByRole(ctx) { - try { - if (!ctx) { - throw Error("The request body is empty!") - } - const params = { roleId: ctx.id } - const assignedUserByRole = await db.raw(` - select u.username as username,u.email as useremail, r.name as rolename from roles r - inner join roles_users ru on r.id = ru.role_id - inner join users u on ru.kc_id = u.kc_id - where r.id = :roleId - `, params) - return assignedUserByRole.rows - } catch (error) { - throw new Error(error) + // DELETE a user + async delete(ctx) { + if (!ctx || !ctx.userId) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + await auth(); + const deleted = await User.destroy({ + where: { kc_id: ctx.userId } + }); + if (deleted) { + return await keycloakAdmin.users.del({ + id: ctx.userId, + realm: process.env.KEYCLOAK_REALM + }) } }, + // POST create the system admin. + // It should be used once at system start-up. async createSystemUser() { - try { - await auth() - const checkUser = await User.findAndCountAll({ - where: { - [Op.or]: [ - { username: "admin" }, - { email: "admin@inrae.fr" } - ] - } - }) - - if (checkUser.count) { - return { user: null, status: 409 } + await auth(); + const checkUser = await User.findAndCountAll({ + where: { + [Op.or]: [ + { username: "admin" }, + { email: "admin@inrae.fr" } + ] } - - // Insert new user into keycloak db - const kc_user = await keycloakAdmin.users.create({ - username: "admin", - email: process.env.IN_SYLVA_ADMIN_USERNAME, - emailVerified: true, - enabled: true, + }); + if (checkUser.count) { + return { user: null, status: 409 }; + } + // Insert new user into keycloak db + const kc_user = await keycloakAdmin.users.create({ + username: "admin", + email: process.env.IN_SYLVA_ADMIN_USERNAME, + emailVerified: true, + enabled: true, + realm: process.env.KEYCLOAK_REALM, + }); + // Set new user's password + if (kc_user) { + await keycloakAdmin.users.resetPassword({ + id: kc_user.id, + credential: { + temporary: false, + type: 'password', + value: process.env.IN_SYLVA_ADMIN_PASSWORD + }, realm: process.env.KEYCLOAK_REALM, - }) - // Set new user's password - if (kc_user) { - await keycloakAdmin.users.resetPassword({ - id: kc_user.id, - credential: { - temporary: false, - type: 'password', - value: process.env.IN_SYLVA_ADMIN_PASSWORD - }, - realm: process.env.KEYCLOAK_REALM, - }) - } - - const pg_user = await User.create({ - kc_id: kc_user.id, - username: "admin", - email: process.env.IN_SYLVA_ADMIN_USERNAME, - password: process.env.IN_SYLVA_ADMIN_PASSWORD - }) - - await RoleUser.create({ - role_id: 1, - kc_id: kc_user.id - }) - - return { user: pg_user, status: 201 } - } catch (error) { - throw new Error(error) + }); } + const pg_user = await User.create({ + kc_id: kc_user.id, + username: "admin", + email: process.env.IN_SYLVA_ADMIN_USERNAME, + password: process.env.IN_SYLVA_ADMIN_PASSWORD + }); + await RoleUser.create({ + role_id: 1, + kc_id: kc_user.id + }); + return { user: pg_user, status: 201 }; }, + // GET Fetch all users and their group and role async usersWithGroupAndRole() { - try { - const usersWithGroupsAndRole = await db.raw( + const usersWithGroupsAndRole = await db.raw( `select DISTINCT u.id, u.kc_id, u.username, u.email, g.name as groupName, g.description as groupDescription, r.name as roleName, r.description as roleDescription from users u inner join roles_users ru on u.kc_id = ru.kc_id inner join roles r on ru.role_id = r.id left join group_users gu on u.id = gu.user_id - left join groups g on g.id = gu.group_id`) - return usersWithGroupsAndRole.rows - } catch (error) { - throw new Error(error) - } + left join groups g on g.id = gu.group_id`); + return usersWithGroupsAndRole.rows; }, + // GET Fetch a user and their group and role async userWithGroupAndRole(ctx) { - try { - const params = { userId: ctx.id } - const userWithGroupAndRole = await db.raw( + if (!ctx || !ctx.id) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + const params = { userId: ctx.id }; + const userWithGroupAndRole = await db.raw( `select DISTINCT u.id, u.kc_id, u.username, u.email, g.id as groupId, g.name as groupName, g.description as groupDescription, r.name as roleName, r.id as roleId, r.description as roleDescription from users u inner join roles_users ru on u.kc_id = ru.kc_id inner join roles r on ru.role_id = r.id left join group_users gu on u.id = gu.user_id left join groups g on g.id = gu.group_id - where u.kc_id = :userId`, params) - return userWithGroupAndRole.rows - } catch (error) { - throw new Error(error) + where u.kc_id = :userId`, params); + return userWithGroupAndRole.rows; + }, + + // POST Email a user + async sendMail(ctx) { + if (!ctx || !ctx.subject || !ctx.message) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; } - } + await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, ctx.email, ctx.subject, "", ctx.message); + await botService.message(ctx.message); + return "Mail sent."; + }, + + // POST Reset a user password. + async resetPassword(ctx) { + if (!ctx || !ctx.email) { + const error = new Error("Required parameters are missing."); + error.status = 400; + throw error; + } + const t = await postgresSeq.transaction(); + await auth(); + const users = await keycloakAdmin.users.find({ + email: ctx.email, + realm: process.env.KEYCLOAK_REALM, + }); + if (!users || users.length === 0) { + const error = new Error("User account not found."); + error.status = 400; + throw error; + } + const user = users[0]; + const hashedPassword = await generatePassword(10); + // Update user in insylva db. + const [updatedRowsCount, updatedRows] = await User.update({ + password: hashedPassword, + }, { + where: { + kc_id: user.id, + }, + }); + if (!updatedRowsCount || updatedRowsCount <= 0) { + t.rollback(); + const error = new Error("Reset password failed."); + error.status = 500; + throw error; + } + // Update user in keycloak db. + await keycloakAdmin.users.resetPassword({ + id: user.id, + credential: { + temporary: false, + type: 'password', + value: password, + }, + realm: process.env.KEYCLOAK_REALM, + }); + await this.sendMail({...ctx, subject: "Password reset", message: `Your new password is ${password}`}); + t.commit(); + return "Password reset successfully"; + }, } module.exports = { create: UserService.create, - users: UserService.users, user: UserService.user, - delete: UserService.delete, - update: UserService.update, + users: UserService.users, kcId: UserService.kcId, + update: UserService.update, detail: UserService.detail, + delete: UserService.delete, getAssignedUserByRole: UserService.getAssignedUserByRole, createSystemUser: UserService.createSystemUser, usersWithGroupAndRole: UserService.usersWithGroupAndRole, userWithGroupAndRole: UserService.userWithGroupAndRole, sendMail: UserService.sendMail, resetPassword: UserService.resetPassword -} +}; -- GitLab