diff --git a/src/repositories/authorization/endpointsRepository.js b/src/repositories/authorization/endpointsRepository.js new file mode 100644 index 0000000..7529cd0 --- /dev/null +++ b/src/repositories/authorization/endpointsRepository.js @@ -0,0 +1,83 @@ +import { pagination } from "../../utils/pagination"; + +const _endpointsQuery = (_pagination) => ({ count }) => ({ uuid, route, method }) => { + const uuidCondition = uuid ? "AND uuid = :uuid " : ""; + const routeCondition = route ? "AND route = :route " : ""; + const methodCondition = method ? "AND method = :method " : ""; + return ` + SELECT + ${count || `*`} + FROM + mydb.endpoints as e + WHERE + e.created <= :now + AND + (e.created > :now OR e.deleted IS NULL) + AND + true + ${uuidCondition} + ${routeCondition} + ${methodCondition} + ${_pagination} + `; +} + +const getEndpointsQuery = ({ limit, page, ...rest }) => + _endpointsQuery(pagination({ limit, page }))({ count: false })(rest); +const countEndpointsQuery = rest => + _endpointsQuery()({ count: "COUNT(*) AS count" })(rest); + +const insertEndpointsQuery = () => { + return ` + INSERT INTO mydb.endpoints ( + uuid, + route, + created, + createdBy + ) + VALUES ( + :uuid, + :route, + :now, + :createdBy + ); + SELECT * FROM mydb.endpoints WHERE uuid = :uuid; + ` +} + +const updateEndpointsQuery = () => { + const routeCondition = route ? 'route = :route ' : ''; + return ` + UPDATE mydb.endpoints + SET + ${routeCondition} + WHERE uuid = :uuid; + SELECT * FROM mydb.endpoints WHERE uuid = :uuid; + ` +} + +const softDeleteEndpointsQuery = () => { + return ` + UPDATE mydb.endpoints + SET deleted = :now, deletedBy = :deletedBy + WHERE uuid = :uuid; + SELECT * FROM mydb.endpoints WHERE uuid = :uuid; + ` +} + +const deleteEndpointsQuery = () => { + return ` + DELETE FROM mydb.endpoints + WHERE uuid = :uuid; + SELECT * FROM mydb.endpoints WHERE uuid = :uuid; + ` +} + +export { + getEndpointsQuery, + countEndpointsQuery, + insertEndpointsQuery, + updateEndpointsQuery, + softDeleteEndpointsQuery, + deleteEndpointsQuery +}; \ No newline at end of file diff --git a/src/repositories/authorization/permissionsRepository.js b/src/repositories/authorization/permissionsRepository.js new file mode 100644 index 0000000..b6bbd32 --- /dev/null +++ b/src/repositories/authorization/permissionsRepository.js @@ -0,0 +1,99 @@ +import { pagination } from '../../utils/pagination.js' + +const _permissionsQuery = (_pagination) => ({count}) => ({uuid, name, action, endpoint}) => { + const uuidCondition = uuid ? 'AND uuid = :uuid ' : ''; + const nameCondition = name ? 'AND name = :name ' : ''; + const actionCondition = action ? 'AND action = :action ' : ''; + const endpointCondition = endpoint ? 'AND fk_endpoint = (SELECT id from mydb.endpoints WHERE route = :endpoint)' : ''; + return ` + SELECT + ${count || + `*`} + FROM + mydb.permissions as p + LEFT JOIN + mydb.endpoints as e ON p.fk_endpoint = e.id + AND e.created <= :now + AND (e.deleted > :now OR e.deleted IS NULL) + WHERE + p.created <= :now + WHERE + p.created <= :now + AND + (p.created > :now OR p.deleted IS NULL) + AND + true + ${uuidCondition} + ${nameCondition} + ${actionCondition} + ${endpointCondition} + ${_pagination} + `; +} + +const getPermissionsQuery = ({ limit, page, ...rest }) => + _permissionsQuery(pagination({ limit, page }))({ count: false })(rest); +const countPermissionsQuery = rest => + _permissionsQuery()({ count: 'COUNT(*) AS count' })(rest); + +const insertPermissionsQuery = () => { + return ` + INSERT INTO mydb.permissions ( + uuid, + name, + action, + fk_endpoint, + created, + createdBy + ) + VALUES ( + :uuid, + :name, + :action, + (SELECT id FROM mydb.endpoints WHERE route = :endpoint), + :now, + :createdBy + ); + SELECT * FROM mydb.permissions WHERE uuid = :uuid; + ` +} + +const modifyPermissionsQuery = () => { + const nameCondition = name ? 'name = :name ' : ''; + const actionCondition = action ? 'action = :action ' : ''; + const endpointCondition = endpoint ? 'fk_endpoint = (SELECT id from mydb.endpoints WHERE route = :endpoint)' : ''; + return ` + UPDATE mydb.permissions + SET + ${nameCondition} + ${actionCondition} + ${endpointCondition} + WHERE + permissions.uuid = :uuid + AND + permissions.deleted IS NULL + SELECT * FROM mydb.permissions WHERE uuid = :uuid; + ` +} + +const softDeletePermissionsQuery = () => { + return ` + UPDATE + mydb.permissions + SET + deleted = :now, deletedBy = :deletedBy + WHERE + permissions.uuid = :uuid + AND + permissions.deleted IS NULL + SELECT * FROM mydb.permissions WHERE uuid = :uuid; + ` +} + +export { + getPermissionsQuery, + countPermissionsQuery, + insertPermissionsQuery, + modifyPermissionsQuery, + softDeletePermissionsQuery +} \ No newline at end of file diff --git a/src/repositories/authorization/rolesRepository.js b/src/repositories/authorization/rolesRepository.js new file mode 100644 index 0000000..4d4af02 --- /dev/null +++ b/src/repositories/authorization/rolesRepository.js @@ -0,0 +1,122 @@ +import { pagination } from "../../utils/pagination.js"; + +/** + * Generic select query that may or may not include counting rows + * @param {Object} _pagination + * @param {Object} count If true, query is of type SELECT COUNT + * @param {Object} rest Rest of params involved on query + * @returns {String} SELECT query + */ +const _roleSelectQuery = (_pagination = '') => + ({ count }) => + ({ uuid, name }) => { + const uuidCondition = uuid ? 'AND uuid = :uuid ' : ''; + const nameCondition = name ? 'AND name = :name ' : ''; + return ` + SELECT + ${count || `*`} + FROM + mydb.roles as r + WHERE + r.created <= :now + AND + (r.created > :now OR r.deleted IS NULL) + AND + true + ${uuidCondition} + ${nameCondition} + `; + }; + + +/** + * Uses generic select query to return a simple query + * @returns {String} simple select query + */ +const getRoleQuery = ({ limit, page, ...rest }) => + _roleSelectQuery(pagination({ limit, page }))({ count: false })(rest); + +/** + * Uses generic select query to return a select count type of query + * @returns {String} SELECT COUNT(*) query + */ +const countRoleQuery = rest => + _roleSelectQuery()({ count: 'COUNT(*) AS count' })(rest); + +/** + * Insert query using parameters passed in request + * @returns {String} INSERT query + */ +const insertRoleQuery = () => { + return ` + INSERT INTO mydb.users ( + uuid, + name, + created, + createdBy + ) + VALUES ( + :uuid, + :name, + :now, + :createdBy + ); + SELECT * FROM mydb.roles WHERE uuid = :uuid; + ` +}; + +/** + * @param {Object} params All params involved in query to be modified in certain object matching uuid passed as req param + * @returns {String} UPDATE query + */ +const modifyRoleQuery = ({ name }) => { + const nameCondition = name ? 'name = :name, ' : ''; + + return ` + UPDATE + mydb.roles + SET + ${nameCondition} + uuid = :uuid + WHERE + roles.uuid = :uuid; + SELECT mydb.roles.* + FROM mydb.roles + WHERE roles.uuid = :uuid + `; +}; + +/** + * @returns {String} DELETE query + */ +const deleteRoleQuery = () => { + return ` + DELETE FROM mydb.roles + WHERE roles.uuid = :uuid + `; +}; + +/** + * + * @returns {String} SOFT DELETE query + */ +const softDeleteRoleQuery = () => { + return ` + UPDATE + mydb.roles + SET + deleted = :deleted, deletedby = :deletedBy + WHERE + roles.uuid = :uuid + AND + deleted is null` +} + +export { + countRoleQuery, + getRoleQuery, + insertRoleQuery, + modifyRoleQuery, + deleteRoleQuery, + softDeleteRoleQuery +}; diff --git a/src/repositories/authorization/roles_has_permissionsRepository.js b/src/repositories/authorization/roles_has_permissionsRepository.js new file mode 100644 index 0000000..61b2f45 --- /dev/null +++ b/src/repositories/authorization/roles_has_permissionsRepository.js @@ -0,0 +1,92 @@ +import { pagination } from '../../utils/pagination.js' + +const _rolesHasPermissionsQuery = (_pagination) => ({count}) => ({uuid, permission_uuid, roleName}) => { + const roleNameCondition = roleName ? 'AND fk_role = (SELECT id from mydb.roles WHERE name = :roleName)' : ''; + const uuidCondition = uuid ? 'AND fk_role = (SELECT id from mydb.roles WHERE uuid = :roleUuid)' : ''; + const permissionsUuidCondition = permission_uuid ? 'AND fk_permission = (SELECT id from mydb.permissions WHERE uuid = :permissionUuid)' : ''; + return ` + SELECT + ${count || + `r.*, + r2.name as role_name, + r2.uuid as role_uuid, + p.action as permission_action, + p.uuid as permission_uuid, + p.resource_type as permission_resource_type`} + FROM + mydb.roles_has_permissions as r + JOIN + mydb.roles as r2 ON r.fk_role = r2.id + AND r2.created <= :now + AND (r2.deleted > :now OR r2.deleted IS NULL) + JOIN + mydb.permissions as p ON r.fk_permission = p.id + AND p.created <= :now + AND (p.deleted > :now OR p.deleted IS NULL) + WHERE + r.created <= :now + AND + (r.created > :now OR r.deleted IS NULL) + AND + true + ${uuidCondition} + ${permissionsUuidCondition} + ${roleNameCondition} + ${_pagination} + `; + } + +const getRolesHasPermissionsQuery = ({ limit, page, ...rest }) => + _rolesHasPermissionsQuery(pagination({ limit, page }))({ count: false })(rest); +const countRolesHasPermissionsQuery = rest => + _rolesHasPermissionsQuery()({ count: 'COUNT(*) AS count' })(rest); + +const insertRolesHasPermissionsQuery = () => { + return ` + INSERT INTO mydb.roles_has_permissions ( + uuid, + fk_role, + fk_permission, + created, + createdBy + ) + VALUES ( + :uuid, + (SELECT id FROM mydb.roles WHERE uuid = :roleUuid), + (SELECT id FROM mydb.permissions WHERE uuid = :permissionUuid), + :now, + :createdBy + ); + SELECT permissions.*, + permissions.uuid as permission_uuid, + roles.uuid as role_uuid, + roles.name as role_name + FROM mydb.roles_has_permissions as rp + LEFT JOIN mydb.permissions as permissions ON rp.fk_permission = permissions.id + LEFT JOIN mydb.roles as roles ON rp.fk_role = roles.id + WHERE rp.uuid = :uuid; + ` +} + +const softDeleteRolesHasPermissionsQuery = () => { + return ` + UPDATE + mydb.roles_has_permissions as roles_has_permissions + SET + deleted = :now, deletedBy = :deletedBy + WHERE + roles_has_permissions.fk_role = (SELECT id FROM mydb.roles WHERE uuid = :roleUuid) + AND + roles_has_permissions.fk_permission = (SELECT id FROM mydb.permissions WHERE uuid = :permissionUuid) + AND + roles_has_permissions.deleted IS NULL + SELECT * FROM mydb.roles_has_permissions WHERE uuid = :uuid; + ` +} + +export{ + getRolesHasPermissionsQuery, + countRolesHasPermissionsQuery, + insertRolesHasPermissionsQuery, + softDeleteRolesHasPermissionsQuery +} \ No newline at end of file diff --git a/src/repositories/authorization/userRepository.js b/src/repositories/authorization/userRepository.js new file mode 100644 index 0000000..1dc7849 --- /dev/null +++ b/src/repositories/authorization/userRepository.js @@ -0,0 +1,150 @@ +import { pagination } from "../../utils/pagination.js"; + +/** + * Generic select query that may or may not include counting rows + * @param {Object} _pagination + * @param {Object} count If true, query is of type SELECT COUNT + * @param {Object} rest Rest of params involved on query + * @returns {String} SELECT query + */ +const _userListSelectQuery = (_pagination = '') => + ({ count }) => + ({ uuid, username, loginUsername, uuidList, email, role }) => { + const uuidCondition = uuid ? 'AND users.uuid = :uuid ' : ''; + //for uuidList, we use IN clause to check if the uuid is in the list of uuids passed + const uuidListCondition = uuidList ? 'AND users.uuid in(:uuidList)' : '' + const loginUsernameCondition = loginUsername ? ' AND users.username = :loginUsername ' : '' + const usernameCondition = username ? `AND users.username LIKE CONCAT('%',:username,'%')` : ''; + const emailCondition = email ? 'AND users.email = :email ' : ''; + const roleCondition = role ? 'AND users.fk_role = :role ' : ''; + return ` + SELECT + ${count || `users.*, r.name AS role`} + FROM + mydb.users as users + LEFT JOIN mydb.roles as r ON users.fk_role = r.id + WHERE + users.created <= :now + AND + (users.created > :now OR users.deleted IS NULL) + AND + true + ${uuidCondition} + ${uuidListCondition} + ${usernameCondition} + ${emailCondition} + ${roleCondition} + ${loginUsernameCondition} + ${_pagination} + `; + }; + + +/** + * Uses generic select query to return a simple query + * @returns {String} simple select query + */ +const getUserListQuery = ({ limit, page, ...rest }) => + _userListSelectQuery(pagination({ limit, page }))({ count: false })(rest); + +/** + * Uses generic select query to return a select count type of query + * @returns {String} SELECT COUNT(*) query + */ +const countUserListQuery = rest => + _userListSelectQuery()({ count: 'COUNT(DISTINCT(users.uuid)) AS count' })(rest); + +/** + * Insert query using parameters passed in request + * @returns {String} INSERT query + */ +const insertUserQuery = () => { + const emailCondition = email ? ':email ' : null; + return ` + INSERT INTO mydb.users ( + uuid, + username, + password, + email, + fk_role, + created, + createdBy + ) + VALUES ( + :uuid, + :username, + :password, + ${emailCondition}, + :role + :now, + :createdBy + ); + SELECT * FROM mydb.users WHERE uuid = :uuid; + ` +}; + +/** + * @param {Object} params All params involved in query to be modified in certain object matching uuid passed as req param + * @returns {String} UPDATE query + */ +const modifyUserQuery = ({ username, email, role }) => { + const usernameCondition = username ? 'username = :username, ' : ''; + const passwordCondition = password ? 'password = :password, ' : ''; + const emailCondition = email ? 'email = :email, ' : ''; + const roleCondition = role ? 'fk_role = (SELECT id FROM mydb.roles WHERE name = :role) ' : ''; + const lastLoginDateCondition = lastLoginDate ? 'last_login_date = :lastLoginDate, ' : ''; + const userStatusCondition = userStatus ? 'user_status = :userStatus, ' : ''; + + return ` + UPDATE + mydb.users + SET + ${usernameCondition} + ${passwordCondition} + ${emailCondition} + ${roleCondition} + ${lastLoginDateCondition} + ${userStatusCondition} + uuid = :uuid + WHERE + users.uuid = :uuid; + SELECT mydb.users.* + FROM mydb.users + WHERE users.uuid = :uuid + `; +}; + +/** + * @returns {String} DELETE query + */ +const deleteUserQuery = () => { + return ` + DELETE FROM mydb.users + WHERE users.uuid = :uuid + `; +}; + +/** + * + * @returns {String} SOFT DELETE query + */ +const softDeleteUserQuery = () => { + return ` + UPDATE + mydb.users + SET + deleted = :deleted, deletedby = :deletedBy + WHERE + users.uuid = :uuid + AND + deleted is null` +} + +export { + getUserListQuery, + countUserListQuery, + insertUserQuery, + modifyUserQuery, + deleteUserQuery, + softDeleteUserQuery +};