#6286 set right workerTimeControl acls #2557

Merged
jorgep merged 10 commits from 6286-setRightWorkerTimeControlAcls into dev 2024-06-27 08:50:10 +00:00
11 changed files with 93 additions and 47 deletions

View File

@ -0,0 +1,18 @@
UPDATE salix.ACL
SET principalId = 'teamBoss'
WHERE property IN ('addTimeEntry', 'deleteTimeEntry', 'updateTimeEntry', 'weeklyHourRecordEmail');
UPDATE salix.ACL SET principalId = 'developer' WHERE property = 'sendMail';
UPDATE salix.ACL
SET property = 'updateMailState'
WHERE property = 'updateWorkerTimeControlMail';
INSERT INTO salix.ACL(model, property, accessType, permission, principalType, principalId)
VALUES
('WorkerTimeControl', 'addTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'hr'),
('WorkerTimeControl', 'deleteTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'hr'),
('WorkerTimeControl', 'updateTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'hr'),
('WorkerTimeControl', 'weeklyHourRecordEmail', 'WRITE', 'ALLOW', 'ROLE', 'hr'),
('WorkerTimeControl', 'sendMail', 'WRITE', 'ALLOW', 'ROLE', 'hr'),
('WorkerTimeControl', 'updateMailState', 'WRITE', 'ALLOW', 'ROLE', 'hr');

View File

@ -1,3 +1,5 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('getMailStates', { Self.remoteMethodCtx('getMailStates', {
description: 'Get the states of a month about time control mail', description: 'Get the states of a month about time control mail',
@ -36,6 +38,8 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
if (!await models.Worker.isSubordinate(ctx, workerId)) throw new UserError(`You don't have enough privileges`);
const times = await models.Time.find({ const times = await models.Time.find({
fields: ['week'], fields: ['week'],
where: { where: {

View File

@ -1,4 +1,5 @@
const moment = require('moment'); const moment = require('moment');
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('resendWeeklyHourEmail', { Self.remoteMethodCtx('resendWeeklyHourEmail', {
@ -34,6 +35,11 @@ module.exports = Self => {
const yearNumber = dated.getFullYear(); const yearNumber = dated.getFullYear();
const weekNumber = moment(dated).isoWeek(); const weekNumber = moment(dated).isoWeek();
const isSubordinate = await models.Worker.isSubordinate(ctx, workerId, myOptions);
const isTeamBoss = await models.ACL.checkAccessAcl(ctx, 'Worker', 'isTeamBoss', 'WRITE');
if (!isSubordinate || (workerId === ctx.req.accessToken.userId && !isTeamBoss))
jgallego marked this conversation as resolved
Review

Aquí uno se puede autoenviar sus fichadas, se quiere eso?

Aquí uno se puede autoenviar sus fichadas, se quiere eso?
Review

Aquí solo se puede si eres teamBoss. Lo hablé con @carlosap, quedamos en hacerlo así porque al llamar deleteTimeEntry, se llama a resendWeelyHourEmail y falla esa parte.

Aquí solo se puede si eres teamBoss. Lo hablé con @carlosap, quedamos en hacerlo así porque al llamar deleteTimeEntry, se llama a resendWeelyHourEmail y falla esa parte.
throw new UserError(`You don't have enough privileges`);
const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({ const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({
where: { where: {

View File

@ -1,28 +1,36 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('workerTimeControl getMailStates()', () => { describe('workerTimeControl getMailStates()', () => {
const workerId = 9; const developerId = 9;
const ctx = {args: { const developerBossId = 120;
month: 12, const employeeId = 1;
year: 2000
}}; let ctx;
let tx;
let opts;
beforeEach(async() => {
ctx = {req: {accessToken: {userId: developerBossId}}, args: {month: 12, year: 2000}};
tx = await models.WorkerTimeControl.beginTransaction({});
opts = {transaction: tx};
});
afterEach(async() => await tx.rollback());
it('should get the states of a month about time control mail', async() => { it('should get the states of a month about time control mail', async() => {
const tx = await models.WorkerTimeControl.beginTransaction({}); const response = await models.WorkerTimeControl.getMailStates(ctx, developerId, opts);
expect(response[0].state).toEqual('REVISE');
expect(response[1].state).toEqual('SENDED');
expect(response[2].state).toEqual('CONFIRMED');
});
it('should throw an error if they are not subordinates', async() => {
ctx.req.accessToken.userId = employeeId;
try { try {
const options = {transaction: tx}; await models.WorkerTimeControl.getMailStates(ctx, developerId, opts);
const response = await models.WorkerTimeControl.getMailStates(ctx, workerId, options);
expect(response[0].state).toEqual('REVISE');
expect(response[1].state).toEqual('SENDED');
expect(response[2].state).toEqual('CONFIRMED');
await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); expect(e.message).toEqual('You don\'t have enough privileges');
throw e;
} }
}); });
}); });

View File

@ -1,10 +1,11 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('updateWorkerTimeControlMail()', () => { describe('updateMailState()', () => {
const developerId = 9;
const employeeId = 1;
it('should update WorkerTimeControlMail if exist record', async() => { it('should update WorkerTimeControlMail if exist record', async() => {
const tx = await models.WorkerTimeControlMail.beginTransaction({}); const tx = await models.WorkerTimeControlMail.beginTransaction({});
const args = { const args = {
workerId: 9,
week: 50, week: 50,
year: 2000, year: 2000,
state: 'CONFIRMED' state: 'CONFIRMED'
@ -15,15 +16,15 @@ describe('updateWorkerTimeControlMail()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const beforeMail = await models.WorkerTimeControlMail.findOne({ const beforeMail = await models.WorkerTimeControlMail.findOne({
where: { where: {
workerFk: args.workerId, workerFk: developerId,
year: args.year, year: args.year,
week: args.week, week: args.week,
} }
}, options); }, options);
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options); await models.WorkerTimeControl.updateMailState(ctx, developerId, options);
const afterMail = await models.WorkerTimeControlMail.findOne({ const afterMail = await models.WorkerTimeControlMail.findOne({
where: { where: {
workerFk: args.workerId, workerFk: developerId,
year: args.year, year: args.year,
week: args.week, week: args.week,
} }
@ -42,7 +43,6 @@ describe('updateWorkerTimeControlMail()', () => {
it('should insert WorkerTimeControlMail if exist record', async() => { it('should insert WorkerTimeControlMail if exist record', async() => {
const tx = await models.WorkerTimeControlMail.beginTransaction({}); const tx = await models.WorkerTimeControlMail.beginTransaction({});
const args = { const args = {
workerId: 1,
week: 51, week: 51,
year: 2000, year: 2000,
state: 'SENDED' state: 'SENDED'
@ -53,15 +53,15 @@ describe('updateWorkerTimeControlMail()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
const beforeMail = await models.WorkerTimeControlMail.find({ const beforeMail = await models.WorkerTimeControlMail.find({
where: { where: {
workerFk: args.workerId, workerFk: employeeId,
year: args.year, year: args.year,
week: args.week, week: args.week,
} }
}, options); }, options);
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options); await models.WorkerTimeControl.updateMailState(ctx, employeeId, options);
const afterMail = await models.WorkerTimeControlMail.find({ const afterMail = await models.WorkerTimeControlMail.find({
where: { where: {
workerFk: args.workerId, workerFk: employeeId,
year: args.year, year: args.year,
week: args.week, week: args.week,
} }
@ -80,7 +80,7 @@ describe('updateWorkerTimeControlMail()', () => {
it('should throw error if not exist any record in this week', async() => { it('should throw error if not exist any record in this week', async() => {
const tx = await models.WorkerTimeControlMail.beginTransaction({}); const tx = await models.WorkerTimeControlMail.beginTransaction({});
const ctx = {args: { const ctx = {args: {
workerId: 1, workerId: employeeId,
week: 1, week: 1,
year: 0, year: 0,
state: 'SENDED' state: 'SENDED'
@ -89,7 +89,7 @@ describe('updateWorkerTimeControlMail()', () => {
let error; let error;
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, options); await models.WorkerTimeControl.updateMailState(ctx, employeeId, options);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -1,12 +1,13 @@
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('updateWorkerTimeControlMail', { Self.remoteMethodCtx('updateMailState', {
description: 'Updates the state of WorkerTimeControlMail', description: 'Updates the state of WorkerTimeControlMail',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [{
arg: 'workerId', arg: 'id',
type: 'number', type: 'number',
required: true description: 'The worker id',
http: {source: 'path'}
}, },
{ {
arg: 'year', arg: 'year',
@ -32,12 +33,12 @@ module.exports = Self => {
root: true root: true
}, },
http: { http: {
path: `/updateWorkerTimeControlMail`, path: `/:id/updateMailState`,
verb: 'POST' verb: 'POST'
} }
}); });
Self.updateWorkerTimeControlMail = async(ctx, options) => { Self.updateMailState = async(ctx, id, options) => {
const models = Self.app.models; const models = Self.app.models;
const args = ctx.args; const args = ctx.args;
const myOptions = {}; const myOptions = {};
@ -59,14 +60,14 @@ module.exports = Self => {
{ {
year: args.year, year: args.year,
week: args.week, week: args.week,
workerFk: args.workerId workerFk: id
}, },
{ {
state: args.state, state: args.state,
reason: args.workerId, reason: args.reason,
year: args.year, year: args.year,
week: args.week, week: args.week,
workerFk: args.workerId workerFk: id
}, },
myOptions); myOptions);

View File

@ -35,7 +35,7 @@ module.exports = Self => {
root: true root: true
}, },
http: { http: {
path: '/weekly-hour-hecord-email', path: '/weekly-hour-record-email',
verb: 'POST' verb: 'POST'
} }
}); });
@ -61,7 +61,7 @@ module.exports = Self => {
const url = `${salix.url}worker/${args.workerId}/time-control?timestamp=${timestamp}`; const url = `${salix.url}worker/${args.workerId}/time-control?timestamp=${timestamp}`;
ctx.args.url = url; ctx.args.url = url;
await models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, myOptions); await models.WorkerTimeControl.updateMailState(ctx, ctx.workerId, myOptions);
return Self.sendTemplate(ctx, 'weekly-hour-record'); return Self.sendTemplate(ctx, 'weekly-hour-record');
}; };

View File

@ -6,7 +6,7 @@ module.exports = Self => {
require('../methods/worker-time-control/deleteTimeEntry')(Self); require('../methods/worker-time-control/deleteTimeEntry')(Self);
require('../methods/worker-time-control/updateTimeEntry')(Self); require('../methods/worker-time-control/updateTimeEntry')(Self);
require('../methods/worker-time-control/sendMail')(Self); require('../methods/worker-time-control/sendMail')(Self);
require('../methods/worker-time-control/updateWorkerTimeControlMail')(Self); require('../methods/worker-time-control/updateMailState')(Self);
require('../methods/worker-time-control/weeklyHourRecordEmail')(Self); require('../methods/worker-time-control/weeklyHourRecordEmail')(Self);
require('../methods/worker-time-control/getMailStates')(Self); require('../methods/worker-time-control/getMailStates')(Self);
require('../methods/worker-time-control/resendWeeklyHourEmail')(Self); require('../methods/worker-time-control/resendWeeklyHourEmail')(Self);

View File

@ -36,15 +36,24 @@
"model": "VnUser", "model": "VnUser",
"foreignKey": "userFk" "foreignKey": "userFk"
}, },
"worker": { "worker": {
"type": "hasOne", "type": "hasOne",
"model": "Worker", "model": "Worker",
"foreignKey": "id" "foreignKey": "id"
}, },
"warehouse": { "warehouse": {
"type": "belongsTo", "type": "belongsTo",
"model": "Warehouse", "model": "Warehouse",
"foreignKey": "warehouseFk" "foreignKey": "warehouseFk"
} }
} },
"acls": [
{
"property": "updateMailState",
"accessType": "WRITE",
"permission": "ALLOW",
"principalType": "ROLE",
"principalId": "$owner"
Review

Pregunta a @alexm si esto funciona

Pregunta a @alexm si esto funciona
Review

Si $owner, hace que solo tenga permiso para el propio usuario. Para que funcione la tabla debe tener relación con la tabla user (vn-user)

Si $owner, hace que solo tenga permiso para el propio usuario. Para que funcione la tabla debe tener relación con la tabla user (vn-user)
}
]
} }

View File

@ -430,7 +430,7 @@ class Controller extends Section {
workerId: this.worker.id, workerId: this.worker.id,
state: 'SENDED' state: 'SENDED'
}; };
this.$http.post(`WorkerTimeControls/weekly-hour-hecord-email`, params) this.$http.post(`WorkerTimeControls/weekly-hour-record-email`, params)
.then(() => { .then(() => {
this.getMailStates(this.date); this.getMailStates(this.date);
this.vnApp.showSuccess(this.$t('Email sended')); this.vnApp.showSuccess(this.$t('Email sended'));

View File

@ -260,7 +260,7 @@ describe('Component vnWorkerTimeControl', () => {
controller.date = today; controller.date = today;
controller.weekNumber = 1; controller.weekNumber = 1;
$httpBackend.expect('POST', 'WorkerTimeControls/weekly-hour-hecord-email').respond(); $httpBackend.expect('POST', 'WorkerTimeControls/weekly-hour-record-email').respond();
controller.resendEmail(); controller.resendEmail();
$httpBackend.flush(); $httpBackend.flush();