From 7d047017f66e3025b157c27e423fd747cbe3f475 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 17 Dec 2024 14:52:53 +0100 Subject: [PATCH] feat: refs #8239 Added checkColumnPermission method --- .../application/checkColumnPermission.js | 65 +++++++++++++++++++ loopback/common/models/application.js | 1 + loopback/locale/en.json | 3 +- loopback/locale/es.json | 5 +- loopback/locale/fr.json | 3 +- loopback/locale/pt.json | 3 +- modules/item/back/models/item.js | 4 ++ 7 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 loopback/common/methods/application/checkColumnPermission.js diff --git a/loopback/common/methods/application/checkColumnPermission.js b/loopback/common/methods/application/checkColumnPermission.js new file mode 100644 index 000000000..309fc375f --- /dev/null +++ b/loopback/common/methods/application/checkColumnPermission.js @@ -0,0 +1,65 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethod('checkColumnPermission', { + description: 'Return enum values of column', + accessType: 'EXECUTE', + accepts: [{ + arg: 'schema', + type: 'string', + description: 'The schema of db', + required: true, + }, { + arg: 'table', + type: 'string', + description: 'The table of schema', + required: true, + }, { + arg: 'column', + type: 'string', + description: 'The column of table', + required: true, + }, { + arg: 'privilegeType', + type: 'string', + description: 'Privilege type (SELECT|UPDATE|INSERT|DELETE)', + required: true, + }, { + arg: 'userId', + type: 'number', + description: 'The user id', + required: true, + } + ], + returns: { + type: 'any', + root: true + }, + http: { + path: `/check-column-permission`, + verb: 'GET' + } + }); + + Self.checkColumnPermission = async(schema, table, column, privilegeType, userId) => { + const models = Self.app.models; + const $t = ((msg, vars) => // Me falta hacer funcionar el $t, ya que probando con ctx no funciona + msg.replace(/\{(\w+)\}/g, (_, key) => vars[key] || '') + ); + + const user = await models.VnUser.findById(userId); + const role = await models.VnRole.findById(user.roleFk); + const permissions = await Self.rawSql(` + SELECT TRUE + FROM information_schema.COLUMN_PRIVILEGES + WHERE TABLE_SCHEMA = ? + AND TABLE_NAME = ? + AND COLUMN_NAME = ? + AND PRIVILEGE_TYPE = ? + AND REGEXP_SUBSTR(GRANTEE, '[a-zA-Z]+') = ? + `, [schema, table, column, privilegeType, role.name]); + + if (!permissions.length) + throw new UserError($t(`You don't have enough privileges to modify`, {column})); + }; +}; diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index 80c58ddc1..725c332d4 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -5,4 +5,5 @@ module.exports = function(Self) { require('../methods/application/executeProc')(Self); require('../methods/application/executeFunc')(Self); require('../methods/application/getEnumValues')(Self); + require('../methods/application/checkColumnPermission')(Self); }; diff --git a/loopback/locale/en.json b/loopback/locale/en.json index e6ec52d63..f1df14f7d 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -249,5 +249,6 @@ "Sales already moved": "Sales already moved", "Holidays to past days not available": "Holidays to past days not available", "Price cannot be blank": "Price cannot be blank", - "There are tickets to be invoiced": "There are tickets to be invoiced" + "There are tickets to be invoiced": "There are tickets to be invoiced", + "You don't have enough privileges to modify": "You don't have enough privileges to modify: {{column}}" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index fcee0e111..43a127fdb 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -398,5 +398,6 @@ "Holidays to past days not available": "Las vacaciones a días pasados no están disponibles", "All tickets have a route order": "Todos los tickets tienen orden de ruta", "Price cannot be blank": "Price cannot be blank", - "There are tickets to be invoiced": "La zona tiene tickets por facturar" -} + "There are tickets to be invoiced": "La zona tiene tickets por facturar", + "You don't have enough privileges to modify": "No tienes suficientes permisos para modificar la columna: {{column}}" +} \ No newline at end of file diff --git a/loopback/locale/fr.json b/loopback/locale/fr.json index 9941358be..14c2bcd79 100644 --- a/loopback/locale/fr.json +++ b/loopback/locale/fr.json @@ -366,5 +366,6 @@ "The quantity claimed cannot be greater than the quantity of the line": "Le montant réclamé ne peut pas être supérieur au montant de la ligne", "You do not have permission to modify the booked field": "Vous n'avez pas la permission de modifier le champ comptabilisé", "ticketLostExpedition": "Le ticket [{{ticketId}}]({{{ticketUrl}}}) a l'expédition perdue suivante : {{expeditionId}}", - "The web user's email already exists": "L'email de l'internaute existe déjà" + "The web user's email already exists": "L'email de l'internaute existe déjà", + "You don't have enough privileges to modify": "Vous n'avez pas suffisamment de privilèges pour modifier: {{column}}" } diff --git a/loopback/locale/pt.json b/loopback/locale/pt.json index e84b30f3d..569f47a96 100644 --- a/loopback/locale/pt.json +++ b/loopback/locale/pt.json @@ -365,5 +365,6 @@ "Cannot send mail": "Não é possível enviar o email", "The quantity claimed cannot be greater than the quantity of the line": "O valor reclamado não pode ser superior ao valor da linha", "ticketLostExpedition": "O ticket [{{ticketId}}]({{{ticketUrl}}}) tem a seguinte expedição perdida: {{expeditionId}}", - "The web user's email already exists": "O e-mail do utilizador da web já existe." + "The web user's email already exists": "O e-mail do utilizador da web já existe.", + "You don't have enough privileges to modify": "Você não tem privilégios suficientes para modificar: {{column}}" } diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index 44a51594c..4065fb8b1 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -1,4 +1,5 @@ let UserError = require('vn-loopback/util/user-error'); +const models = require('vn-loopback/server/server').models; module.exports = Self => { require('../methods/item/filter')(Self); @@ -22,6 +23,9 @@ module.exports = Self => { Self.observe('before save', async function(ctx) { await Self.availableId(ctx); + await models.Application.checkColumnPermission( + 'vn', 'item', 'packingOut', 'UPDATE', ctx.options.accessToken.userId + ); }); Self.availableId = async function(ctx) {