From 05f580512b3a38843d78591c7d4fa5d66bad7977 Mon Sep 17 00:00:00 2001 From: Pau Date: Tue, 1 Apr 2025 20:36:29 +0200 Subject: [PATCH] created all controllers for layering --- .../authorization/endpointsController.js | 181 ++++++++++++++++++ .../authorization/loginController.js | 86 +++++++++ .../authorization/permissionsController.js | 137 +++++++++++++ .../authorization/rolesController.js | 166 ++++++++++++++++ .../roles_has_permissionsController.js | 141 ++++++++++++++ .../authorization/userController.js | 145 ++++++++++++++ 6 files changed, 856 insertions(+) create mode 100644 src/controllers/authorization/endpointsController.js create mode 100644 src/controllers/authorization/loginController.js create mode 100644 src/controllers/authorization/permissionsController.js create mode 100644 src/controllers/authorization/rolesController.js create mode 100644 src/controllers/authorization/roles_has_permissionsController.js create mode 100644 src/controllers/authorization/userController.js diff --git a/src/controllers/authorization/endpointsController.js b/src/controllers/authorization/endpointsController.js new file mode 100644 index 0000000..cb1485f --- /dev/null +++ b/src/controllers/authorization/endpointsController.js @@ -0,0 +1,181 @@ +import { + getEndpointsModel, + countEndpointsModel, + insertEndpointsModel, + modifyEndpointsModel, + softDeleteEndpointsModel, + deleteEndpointsModel + } from "../../models/authorization/endpointsModel.js"; +import { error404, errorHandler } from "../../utils/errors.js"; +import { sendResponseNotFound } from "../../utils/responses.js"; +import { noResults } from "../../validators/result-validators.js"; + +const getEndpointsController = (req, res, next, config) => { + const conn = mysql.start(config) + + Promise.all([ + getEndpointsModel({ ...req.query, conn }), + countEndpointsModel({ ...req.query, conn }) + ]) + .then(([getResults, countResults]) => + next({ + _data: { endpoints: getResults }, + _page: { + totalElements: countResults, + limit: req.query.limit || 100, + page: req.query.page || (countResults && 1) || 0 + } + }) + ) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getEndpointsByUuidController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + getEndpointsModel({ uuid, conn }) + .then((endpointsInformation) => { + if (noResults(endpointsInformation)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + endpoints: endpointsInformation + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getEndpointsByRouteController = (req, res, next, config) => { + const conn = mysql.start(config) + const route = req.params.route + + getEndpointsModel({ route, conn }) + .then((response) => { + if (noResults(response)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + endpoints: response + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const postEndpointsController = (req, res, next, config) => { + const conn = mysql.start(config) + const created_by = req.headers['uuid_requester'] || null + + insertEndpointsModel({ ...req.body, created_by, conn }) + .then((endpoints) => { + const result = { + _data: { endpoints } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const putEndpointsController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + modifyEndpointsModel({ ...req.body, uuid, conn }) + .then((endpoints) => { + const result = { + _data: { endpoints } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const softDeleteEndpointsController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + const { deleted } = req.body + const deletedby = req.headers['uuid_requester'] || null + + softDeleteEndpointsModel({ uuid, deleted, deletedby, conn }) + .then(() => { + const result = {} + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const deleteEndpointsController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + deleteEndpointsModel({ uuid, conn }) + .then(() => { + const result = {} + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +export { + getEndpointsController, + getEndpointsByUuidController, + getEndpointsByRouteController, + postEndpointsController, + putEndpointsController, + softDeleteEndpointsController, + deleteEndpointsController +} diff --git a/src/controllers/authorization/loginController.js b/src/controllers/authorization/loginController.js new file mode 100644 index 0000000..16c4596 --- /dev/null +++ b/src/controllers/authorization/loginController.js @@ -0,0 +1,86 @@ +import { getUserListModel } from "../../models/authorization/userModel.js"; +import { noResults } from "../../validators/result-validators.js"; +import mysql from "../../adapters/mysql.js"; +import bcrypt from "bcrypt"; +import { error404, errorHandler } from "../../utils/errors.js"; +import { sendResponseNotFound, sendResponseUnauthorized } from "../../utils/responses.js"; +import { getRolesHasPermissionsModel } from "../../models/authorization/roles_has_permissionsModel.js"; + +const postLoginController = (req, res, next, config) => { + const { username, password } = req.body; + const conn = mysql.start(config); + + getUserListModel({ conn, loginUsername: username}) + .then((response) => { + if (noResults(response)) { + const error = errorHandler({code: 'UNAUTHORIZED'}, config.environment); + return sendResponseUnauthorized(res, error); + } + + return bcrypt + .compare(password, response[0].password) + .then((isMatch) => { + if (!isMatch) { + const error = errorHandler({code: 'UNAUTHORIZED'}, config.environment); + return sendResponseUnauthorized(res, error); + } + + const {uuid, username, email, role} = response[0]; + const roleUuid = role + + //obtain role permissions + return _getRolePermissions(config, roleUuid, conn) + .then(rolePermissions => { + const roleData = { + name: response[0].role_name || 'viewer', + roles_uuid: roleUuid + }; + + const result = { + _data: { + uuid, + username, + email, + role, + roleData: roleData, + role_permissions: rolePermissions + }, + }; + + next(result); + }); + }); + }) + .catch((err) => { + const error = errorHandler(err, config.environment); + res.status(error.code).json(error); + }) + .finally(() => { + mysql.end(conn); + }); +} + +const _getRolePermissions = (config, roleUuid, conn) => { + + return getRolesHasPermissionsModel({ uuid_role: roleUuid, conn }) + .then((response) => { + if (noResults(response)) { + const err = error404(); + const error = errorHandler(err, config.environment); + return sendResponseNotFound(res, error); + } + + return response.map(({ permission }) => permission); + }) + .catch((err) => { + const error = errorHandler(err, config.environment); + res.status(error.code).json(error); + }) + .finally(() => { + mysql.end(conn); + }); +} + +export { + postLoginController +} \ No newline at end of file diff --git a/src/controllers/authorization/permissionsController.js b/src/controllers/authorization/permissionsController.js new file mode 100644 index 0000000..43ef144 --- /dev/null +++ b/src/controllers/authorization/permissionsController.js @@ -0,0 +1,137 @@ +import { error404, errorHandler } from '../../utils/errors.js' +import { sendResponseNotFound } from '../../utils/responses.js' +import { noResults } from '../../validators/result-validators.js' +import mysql from '../../adapters/mysql.js' +import { + getPermissionModel, + countPermissionModel, + insertPermissionModel, + modifyPermissionModel, + softDeletePermissionModel +} from '../../models/authorization/permissionsModel.js' + +const getPermissionController = (req, res, next, config) => { + const conn = mysql.start(config) + + Promise.all([ + getPermissionModel({...req.query, conn}), + countPermissionModel({...req.query, conn}) + ]) + .then(([getResults, countResults]) => { + next({ + _data: {permissions: getResults}, + _page: { + totalElements: countResults, + limit: req.query.limit || 100, + page: req.query.page || (countResults && 1) || 0 + } + }) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getPermissionByUuidController = (req, res, next, config) => { + const uuid_permission = req.params.uuid + const conn = mysql.start(config) + + getPermissionModel({ uuid_permission, conn }) + .then((response) => { + if (noResults(response)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + permissions: response + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const postPermissionController = (req, res, next, config) => { + const conn = mysql.start(config) + const created_by = req.headers['uuid_requester'] || null + + insertPermissionModel({...req.body, created_by, conn}) + .then((response) => { + const result = { + _data: { + permissions: response + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const putPermissionController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid_permission = req.params.uuid + + modifyPermissionModel({...req.body, uuid_permission, conn}) + .then((response) => { + const result = { + _data: { + permissions: response + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const softDeletePermissionController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid_permission = req.params.uuid + const deletedBy = req.headers['uuid_requester'] || null + const {deleted} = req.body + + softDeletePermissionModel({uuid_permission, deleted, deletedBy, conn}) + .then(() => { + const result = {} + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +export { + getPermissionController, + getPermissionByUuidController, + postPermissionController, + putPermissionController, + softDeletePermissionController +} \ No newline at end of file diff --git a/src/controllers/authorization/rolesController.js b/src/controllers/authorization/rolesController.js new file mode 100644 index 0000000..d72bb38 --- /dev/null +++ b/src/controllers/authorization/rolesController.js @@ -0,0 +1,166 @@ +import mysql from '../../adapters/mysql.js' +import { + getRoleModel, + countRoleModel, + insertRoleModel, + modifyRoleModel, + softDeleteRoleModel + } from '../../models/authorization/roleModel.js' +import { error404, errorHandler } from '../../utils/errors.js' +import { sendResponseNotFound } from '../../utils/responses.js' +import { noResults } from '../../validators/result-validators.js' + +const getRoleController = (req, res, next, config) => { + const conn = mysql.start(config) + + Promise.all([ + getRoleModel({ ...req.query, conn }), + countRoleModel({ ...req.query, conn }) + ]) + .then(([getResults, countResults]) => + next({ + _data: { Role: getResults }, + _page: { + totalElements: countResults, + limit: req.query.limit || 100, + page: req.query.page || (countResults && 1) || 0 + } + }) + ) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getRoleInfoController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + getRoleModel({ uuid, conn }) + .then((RoleInformation) => { + if (noResults(RoleInformation)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + Role: RoleInformation + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getRoleByNameController = (req, res, next, config) => { + const conn = mysql.start(config) + const name = req.params.name + + getRoleModel({ name, conn }) + .then((RoleInformation) => { + if (noResults(RoleInformation)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + Role: RoleInformation + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const postRoleController = (req, res, next, config) => { + const conn = mysql.start(config) + const createdby = req.headers['uuid-requester'] || null + + insertRoleModel({ ...req.body, createdby, conn }) + .then((RoleInformation) => { + const result = { + _data: { Role: RoleInformation } + } + + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const putRoleController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + modifyRoleModel({ ...req.body, uuid, conn }) + .then((RoleInformation) => { + const result = { + _data: { + message: 'Role created', + Role: RoleInformation + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const deleteRoleController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + const { deleted } = req.body + const deletedby = req.headers['uuid-requester'] || null + + softDeleteRoleModel({ uuid, deleted, deletedby, conn }) + .then(() => { + const result = {} + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +export { + deleteRoleController, + getRoleController, + getRoleInfoController, + postRoleController, + putRoleController, + getRoleByNameController +} diff --git a/src/controllers/authorization/roles_has_permissionsController.js b/src/controllers/authorization/roles_has_permissionsController.js new file mode 100644 index 0000000..86d49ba --- /dev/null +++ b/src/controllers/authorization/roles_has_permissionsController.js @@ -0,0 +1,141 @@ +import mysql from '../../adapters/mysql' +import { + getRolesHasPermissionsModel, + countRolesHasPermissionsModel, + insertRolesHasPermissionsModel, + modifyRolesHasPermissionsModel, + softDeleteRolesHasPermissionsModel +} from '../../repositories/authorization/roles_has_permissionsRepository' +import { error404, errorHandler } from '../../utils/errors' +import { noResults } from '../../validators/result-validators' + +const getRolesHasPermissionsController = (req, res, next, config) => { + const conn = mysql.start(config) + + Promise.all([ + getRolesHasPermissionsModel({...req.query, uuidList, conn}), + countRolesHasPermissionsModel({...req.query, uuidList, conn}) + ]) + .then(([getResults, countResults]) => { + next({ + _data: {roles_has_permissions: getResults}, + _page: { + totalElements: countResults, + limit: req.query.limit || 100, + page: req.query.page || (countResults && 1) || 0 + } + }) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getRolesHasPermissionsControllerByRoleName = (req, res, next, config) => { + const conn = mysql.start(config) + const roleName = req.params.name + + getRolesHasPermissionsModel({ roleName, conn }) + .then((response) => { + if (noResults(response)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + roles_has_permissions: response + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getPermissionsByRoleController = (req, res, next, config) => { + const uuid_role = req.params.uuid + const conn = mysql.start(config) + + getRolesHasPermissionsModel({ uuid_role, conn }) + .then((response) => { + if (noResults(response)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + const result = { + _data: { + roles_has_permissions: response + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const postRolesHasPermissionsController = (req, res, next, config) => { + const conn = mysql.start(config) + const createdBy = req.headers['uuid-requester'] || null + const roleUuid = req.body.uuid + + insertRolesHasPermissionsModel({...req.body, roleUuid, createdBy, conn}) + .then((roles_has_permissions) => { + const result = { + _data: roles_has_permissions + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const softDeleteRolesHasPermissionsController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + const { deleted } = req.body + const deletedby = req.headers['uuid-requester'] || null + + softDeleteRolesHasPermissionsModel({ uuid, deleted, deletedby, conn }) + .then(() => { + const result = {} + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +export { + getRolesHasPermissionsController, + getPermissionsByRoleController, + postRolesHasPermissionsController, + softDeleteRolesHasPermissionsController, + getRolesHasPermissionsControllerByRoleName +} \ No newline at end of file diff --git a/src/controllers/authorization/userController.js b/src/controllers/authorization/userController.js new file mode 100644 index 0000000..e489f68 --- /dev/null +++ b/src/controllers/authorization/userController.js @@ -0,0 +1,145 @@ +import bcrypt from 'bcrypt' +import mysql from '../../adapters/mysql.js' +import { + getUserListModel, + countUserListModel, + insertUserModel, + modifyUserModel, + softDeleteUserModel +} from '../../models/authorization/userModel.js' +import { error404, errorHandler } from '../../utils/errors.js' +import { sendResponseNotFound } from '../../utils/responses.js' +import { noResults } from '../../validators/result-validators.js' + +const getUserListController = (req, res, next, config) => { + const uuidList = req.query.uuidList && req.query.uuidList.split(',') + const conn = mysql.start(config) + + Promise.all([ + getUserListModel({...req.query, uuidList, conn}), + countUserListModel({...req.query, uuidList, conn}) + ]) + .then(([getResults, countResults]) => { + //exclude password (confidential) + const users = getResults.map(({password, ...rest}) => rest) + + next({ + _data: {users}, + _page: { + totalElements: countResults, + limit: req.query.limit || 100, + page: req.query.page || (countResults && 1) || 0 + } + }) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const getUserInfoController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + getUserListModel({ uuid, conn }) + .then((response) => { + if (noResults(response)) { + const err = error404() + const error = errorHandler(err, config.environment) + return sendResponseNotFound(res, error) + } + + // exclude password (confidential) + const users = response.map(({ password, ...rest }) => rest) + + const result = { + _data: { + users + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const postUserController = (req, res, next, config) => { + const conn = mysql.start(config) + const createdby = req.headers['uuid-requester'] || null + const { username, password} = req.body + + //encrypt password + bcrypt + .hash(password, config.saltRounds) + .then(hash => insertUserModel({ username, password: hash, email, fk_role, createdby, conn })) + .then((users) => { + const result = { + _data: { + message: 'User created', + users + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const putUserController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + + modifyUserModel({ ...req.body, uuid, conn }) + .then((users) => { + const result = { + _data: { + message: 'User modified', + users + } + } + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +const softDeleteUserController = (req, res, next, config) => { + const conn = mysql.start(config) + const uuid = req.params.uuid + const { deleted } = req.body + const deletedby = req.headers['uuid-requester'] || null + + softDeleteUserModel({ uuid, deleted, deletedby, conn }) + .then(() => { + const result = {} + next(result) + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error) + }) + .finally(() => { + mysql.end(conn) + }) +} + +export { softDeleteUserController, getUserInfoController, getUserListController, postUserController, putUserController } \ No newline at end of file