From 32f28e91b53692df7817a8b058a501b08a91aaf0 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 22 Nov 2022 14:29:42 +0100 Subject: [PATCH] feat: sistema de bloque para ficheros mdb --- db/changes/10503-november/00-aclMdbApp.sql | 4 ++ db/changes/10503-november/00-mdbApp.sql | 11 ++++ db/dump/fixtures.sql | 5 ++ loopback/locale/en.json | 3 +- loopback/locale/es.json | 3 +- modules/mdb/back/methods/mdbApp/lock.js | 56 +++++++++++++++++++ modules/mdb/back/methods/mdbApp/unlock.js | 55 ++++++++++++++++++ modules/mdb/back/methods/mdbVersion/upload.js | 22 +++++++- modules/mdb/back/model-config.json | 3 + modules/mdb/back/models/mdbApp.js | 4 ++ modules/mdb/back/models/mdbApp.json | 31 ++++++++++ 11 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 db/changes/10503-november/00-aclMdbApp.sql create mode 100644 db/changes/10503-november/00-mdbApp.sql create mode 100644 modules/mdb/back/methods/mdbApp/lock.js create mode 100644 modules/mdb/back/methods/mdbApp/unlock.js create mode 100644 modules/mdb/back/models/mdbApp.js create mode 100644 modules/mdb/back/models/mdbApp.json diff --git a/db/changes/10503-november/00-aclMdbApp.sql b/db/changes/10503-november/00-aclMdbApp.sql new file mode 100644 index 000000000..b5b60546c --- /dev/null +++ b/db/changes/10503-november/00-aclMdbApp.sql @@ -0,0 +1,4 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('MdbApp', 'lock', 'WRITE', 'ALLOW', 'ROLE', 'developer'), + ('MdbApp', 'unlock', 'WRITE', 'ALLOW', 'ROLE', 'developer'); diff --git a/db/changes/10503-november/00-mdbApp.sql b/db/changes/10503-november/00-mdbApp.sql new file mode 100644 index 000000000..3b242c9ab --- /dev/null +++ b/db/changes/10503-november/00-mdbApp.sql @@ -0,0 +1,11 @@ +CREATE TABLE `vn`.`mdbApp` ( + `app` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `baselineBranchFk` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `locked` datetime DEFAULT NULL, + UNIQUE KEY `app_UN` (`app`), + KEY `mdbApp_FK` (`userFk`), + KEY `mdbApp_FK_1` (`baselineBranchFk`), + CONSTRAINT `mdbApp_FK` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `mdbApp_FK_1` FOREIGN KEY (`baselineBranchFk`) REFERENCES `mdbBranch` (`name`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 11e1453a9..43070b990 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2731,3 +2731,8 @@ UPDATE `account`.`user` INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`) VALUES (0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', 'open', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all'); + +INSERT INTO `vn`.`mdbApp` (`app`, `baselineBranchFk`, `userFk`, `locked`) + VALUES + ('com', 'master', NULL, NULL), + ('ent', 'test', NULL, NULL); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 36da9f661..0fce94d36 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -138,5 +138,6 @@ "You don't have grant privilege": "You don't have grant privilege", "You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user", "Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) merged with [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})", - "Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production" + "Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production", + "App locked": "App locked by user {{userId}}" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 747007713..801404eab 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -244,5 +244,6 @@ "Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) fusionado con [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})", "Already has this status": "Ya tiene este estado", "There aren't records for this week": "No existen registros para esta semana", - "Empty data source": "Origen de datos vacio" + "Empty data source": "Origen de datos vacio", + "App locked": "Aplicación bloquada por el usuario {{userId}}" } diff --git a/modules/mdb/back/methods/mdbApp/lock.js b/modules/mdb/back/methods/mdbApp/lock.js new file mode 100644 index 000000000..5fcd0604e --- /dev/null +++ b/modules/mdb/back/methods/mdbApp/lock.js @@ -0,0 +1,56 @@ +module.exports = Self => { + Self.remoteMethodCtx('lock', { + description: 'Lock an app for the user', + accessType: 'WRITE', + accepts: [ + { + arg: 'appName', + type: 'string', + required: true, + description: 'The app name', + http: {source: 'path'} + + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:appName/lock`, + verb: 'POST' + } + }); + + Self.lock = async(ctx, appName, options) => { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const myOptions = {}; + + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const mdbApp = await models.MdbApp.findById(appName, null, myOptions); + const updatedMdbApp = await mdbApp.updateAttributes({ + userFk: userId, + locked: new Date() + }, myOptions); + + if (tx) await tx.commit(); + + return updatedMdbApp; + } catch (e) { + if (tx) await tx.rollback(); + + throw e; + } + }; +}; diff --git a/modules/mdb/back/methods/mdbApp/unlock.js b/modules/mdb/back/methods/mdbApp/unlock.js new file mode 100644 index 000000000..7c6f88ec2 --- /dev/null +++ b/modules/mdb/back/methods/mdbApp/unlock.js @@ -0,0 +1,55 @@ +module.exports = Self => { + Self.remoteMethodCtx('unlock', { + description: 'Unlock an app for the user', + accessType: 'WRITE', + accepts: [ + { + arg: 'appName', + type: 'string', + required: true, + description: 'The app name', + http: {source: 'path'} + + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:appName/unlock`, + verb: 'POST' + } + }); + + Self.unlock = async(appName, options) => { + const models = Self.app.models; + const myOptions = {}; + + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const mdbApp = await models.MdbApp.findById(appName, null, myOptions); + const updatedMdbApp = await mdbApp.updateAttributes({ + userFk: null, + locked: null + }, myOptions); + + if (tx) await tx.commit(); + + return updatedMdbApp; + } catch (e) { + if (tx) await tx.rollback(); + + throw e; + } + }; +}; diff --git a/modules/mdb/back/methods/mdbVersion/upload.js b/modules/mdb/back/methods/mdbVersion/upload.js index 57df35ce7..489700dd1 100644 --- a/modules/mdb/back/methods/mdbVersion/upload.js +++ b/modules/mdb/back/methods/mdbVersion/upload.js @@ -23,6 +23,12 @@ module.exports = Self => { type: 'string', required: true, description: `The branch name` + }, + { + arg: 'unlock', + type: 'boolean', + required: false, + description: `It allows unlock the app` } ], returns: { @@ -35,9 +41,11 @@ module.exports = Self => { } }); - Self.upload = async(ctx, appName, newVersion, branch, options) => { + Self.upload = async(ctx, appName, newVersion, branch, unlock, options) => { const models = Self.app.models; + const userId = ctx.req.accessToken.userId; const myOptions = {}; + const $t = ctx.req.__; // $translate const TempContainer = models.TempContainer; const AccessContainer = models.AccessContainer; @@ -55,6 +63,12 @@ module.exports = Self => { let srcFile; try { + const mdbApp = await models.MdbApp.findById(appName, null, myOptions); + const message = $t('App locked', { + userId: userId + }); + if (mdbApp.locked && mdbApp.userFk != userId) throw new UserError(message); + const tempContainer = await TempContainer.container('access'); const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions); const files = Object.values(uploaded.files).map(file => { @@ -79,7 +93,7 @@ module.exports = Self => { const existBranch = await models.MdbBranch.findOne({ where: {name: branch} - }); + }, myOptions); if (!existBranch) throw new UserError('Not exist this branch'); @@ -108,7 +122,9 @@ module.exports = Self => { app: appName, branchFk: branch, version: newVersion - }); + }, myOptions); + + if (unlock) await models.MdbApp.unlock(appName, myOptions); if (tx) await tx.commit(); } catch (e) { diff --git a/modules/mdb/back/model-config.json b/modules/mdb/back/model-config.json index d5be8de87..6107f8790 100644 --- a/modules/mdb/back/model-config.json +++ b/modules/mdb/back/model-config.json @@ -1,4 +1,7 @@ { + "MdbApp": { + "dataSource": "vn" + }, "MdbBranch": { "dataSource": "vn" }, diff --git a/modules/mdb/back/models/mdbApp.js b/modules/mdb/back/models/mdbApp.js new file mode 100644 index 000000000..dce715573 --- /dev/null +++ b/modules/mdb/back/models/mdbApp.js @@ -0,0 +1,4 @@ +module.exports = Self => { + require('../methods/mdbApp/lock')(Self); + require('../methods/mdbApp/unlock')(Self); +}; diff --git a/modules/mdb/back/models/mdbApp.json b/modules/mdb/back/models/mdbApp.json new file mode 100644 index 000000000..868f8c1d0 --- /dev/null +++ b/modules/mdb/back/models/mdbApp.json @@ -0,0 +1,31 @@ +{ + "name": "MdbApp", + "base": "VnModel", + "options": { + "mysql": { + "table": "mdbApp" + } + }, + "properties": { + "app": { + "type": "string", + "description": "The app name", + "id": true + }, + "locked": { + "type": "date" + } + }, + "relations": { + "branch": { + "type": "belongsTo", + "model": "MdbBranch", + "foreignKey": "baselineBranchFk" + }, + "user": { + "type": "belongsTo", + "model": "MdbBranch", + "foreignKey": "userFk" + } + } +}