4794-mdb_block #1170

Merged
vicent merged 17 commits from 4794-mdb_block into dev 2022-12-22 09:19:16 +00:00
13 changed files with 264 additions and 7 deletions

View File

@ -0,0 +1,11 @@
CREATE TABLE `vn`.`mdbApp` (
`app` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL,
`baselineBranchFk` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
`userFk` int(10) unsigned DEFAULT NULL,
`locked` datetime DEFAULT NULL,
PRIMARY KEY (`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

View File

@ -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');

View File

@ -2745,6 +2745,10 @@ INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`
VALUES 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'); (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
('foo', 'master', NULL, NULL),
('bar', 'test', 9, util.VN_NOW());
INSERT INTO `vn`.`ticketLog` (`id`, `originFk`, `userFk`, `action`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`) INSERT INTO `vn`.`ticketLog` (`id`, `originFk`, `userFk`, `action`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`)
VALUES VALUES
(1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1); (1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1);

View File

@ -143,6 +143,7 @@
"Email verify": "Email verify", "Email verify": "Email verify",
"Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) merged with [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})", "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) merged with [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
"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}}",
"The sales of the receiver ticket can't be modified": "The sales of the receiver ticket can't be modified", "The sales of the receiver ticket can't be modified": "The sales of the receiver ticket can't be modified",
"Receipt's bank was not found": "Receipt's bank was not found", "Receipt's bank was not found": "Receipt's bank was not found",
"This receipt was not compensated": "This receipt was not compensated", "This receipt was not compensated": "This receipt was not compensated",

View File

@ -246,9 +246,11 @@
"Already has this status": "Ya tiene este estado", "Already has this status": "Ya tiene este estado",
"There aren't records for this week": "No existen registros para esta semana", "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",
vicent marked this conversation as resolved Outdated

bloqueada

bloqueada
"App locked": "Aplicación bloqueada por el usuario {{userId}}",
"Email verify": "Correo de verificación", "Email verify": "Correo de verificación",
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment", "Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
"Receipt's bank was not found": "No se encontró el banco del recibo", "Receipt's bank was not found": "No se encontró el banco del recibo",
"This receipt was not compensated": "Este recibo no ha sido compensado", "This receipt was not compensated": "Este recibo no ha sido compensado",
"Client's email was not found": "No se encontró el email del cliente" "Client's email was not found": "No se encontró el email del cliente",
"Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9"
} }

View File

@ -0,0 +1,66 @@
const UserError = require('vn-loopback/util/user-error');
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 = {};
const $t = ctx.req.__; // $translate
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
vicent marked this conversation as resolved
Review

hay que comprobar que no este bloqueado previamente

hay que comprobar que no este bloqueado previamente
try {
const mdbApp = await models.MdbApp.findById(appName, {fields: ['app', 'locked', 'userFk']}, myOptions);
vicent marked this conversation as resolved Outdated

traer solo los campos necesarios ejemplo:
{fields: ['locked','userFk']}

traer solo los campos necesarios ejemplo: `{fields: ['locked','userFk']}`
if (mdbApp.locked) {
throw new UserError($t('App locked', {
userId: mdbApp.userFk
}));
vicent marked this conversation as resolved Outdated

si se usa dentro del if crearla dentro del if.
En este caso se puede poner todo el codigo dentro de los parentesis, sin crear la variable

si se usa dentro del if crearla dentro del if. En este caso se puede poner todo el codigo dentro de los parentesis, sin crear la variable
}
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;
}
};
};

View File

@ -0,0 +1,51 @@
const models = require('vn-loopback/server/server').models;
describe('MdbApp lock()', () => {
it('should throw an error if the app is already locked', async() => {
const tx = await models.MdbApp.beginTransaction({});
let error;
try {
const options = {transaction: tx};
vicent marked this conversation as resolved Outdated

foo

foo
const appName = 'bar';
const developerId = 9;
const ctx = {
req: {
accessToken: {userId: developerId},
__: () => {}
}
};
const result = await models.MdbApp.lock(ctx, appName, options);
expect(result.locked).not.toBeNull();
await tx.rollback();
} catch (e) {
error = e;
await tx.rollback();
}
expect(error).toBeDefined();
});
it(`should lock a mdb `, async() => {
const tx = await models.MdbApp.beginTransaction({});
try {
const options = {transaction: tx};
const appName = 'foo';
const developerId = 9;
const ctx = {req: {accessToken: {userId: developerId}}};
const result = await models.MdbApp.lock(ctx, appName, options);
expect(result.locked).not.toBeNull();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
});
});

View File

@ -0,0 +1,22 @@
const models = require('vn-loopback/server/server').models;
describe('MdbApp unlock()', () => {
it(`should unlock a mdb `, async() => {
const tx = await models.MdbApp.beginTransaction({});
try {
const options = {transaction: tx};
const appName = 'bar';
const developerId = 9;
const ctx = {req: {accessToken: {userId: developerId}}};
const result = await models.MdbApp.unlock(ctx, appName, options);
expect(result.locked).toBeNull();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
});
});

View File

@ -0,0 +1,40 @@
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(ctx, appName, options) => {
const models = Self.app.models;
const myOptions = {};
if (typeof options == 'object')
vicent marked this conversation as resolved
Review

Llevar tot lo referent a tx i try-catch

Llevar tot lo referent a tx i try-catch
Object.assign(myOptions, options);
const mdbApp = await models.MdbApp.findById(appName, null, myOptions);
const updatedMdbApp = await mdbApp.updateAttributes({
userFk: null,
vicent marked this conversation as resolved Outdated
Outdated
Review

En este caso no es necesario transaccionar si no se te pasa una transacción

En este caso no es necesario transaccionar si no se te pasa una transacción
locked: null
}, myOptions);
return updatedMdbApp;
};
};

View File

@ -23,6 +23,12 @@ module.exports = Self => {
type: 'string', type: 'string',
required: true, required: true,
description: `The branch name` description: `The branch name`
},
{
arg: 'unlock',
type: 'boolean',
required: false,
description: `It allows unlock the app`
} }
], ],
returns: { 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 models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {}; const myOptions = {};
const $t = ctx.req.__; // $translate
const TempContainer = models.TempContainer; const TempContainer = models.TempContainer;
const AccessContainer = models.AccessContainer; const AccessContainer = models.AccessContainer;
@ -55,6 +63,14 @@ module.exports = Self => {
let srcFile; let srcFile;
try { try {
const mdbApp = await models.MdbApp.findById(appName, null, myOptions);
if (mdbApp.locked && mdbApp.userFk != userId) {
throw new UserError($t('App locked', {
userId: mdbApp.userFk
vicent marked this conversation as resolved Outdated

mensaje dentro del if como arriba.

mensaje dentro del if como arriba.
}));
}
const tempContainer = await TempContainer.container('access'); const tempContainer = await TempContainer.container('access');
const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions); const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
const files = Object.values(uploaded.files).map(file => { const files = Object.values(uploaded.files).map(file => {
@ -79,7 +95,7 @@ module.exports = Self => {
const existBranch = await models.MdbBranch.findOne({ const existBranch = await models.MdbBranch.findOne({
where: {name: branch} where: {name: branch}
}); }, myOptions);
if (!existBranch) if (!existBranch)
throw new UserError('Not exist this branch'); throw new UserError('Not exist this branch');
@ -108,7 +124,9 @@ module.exports = Self => {
app: appName, app: appName,
branchFk: branch, branchFk: branch,
version: newVersion version: newVersion
}); }, myOptions);
if (unlock) await models.MdbApp.unlock(ctx, appName, myOptions);
if (tx) await tx.commit(); if (tx) await tx.commit();
} catch (e) { } catch (e) {

View File

@ -1,4 +1,7 @@
{ {
"MdbApp": {
"dataSource": "vn"
},
"MdbBranch": { "MdbBranch": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -0,0 +1,4 @@
module.exports = Self => {
require('../methods/mdbApp/lock')(Self);
require('../methods/mdbApp/unlock')(Self);
};

View File

@ -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"
}
}
}