From d1df8009a620138e1a53de2c19ab952d725590d8 Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 29 Aug 2023 10:52:05 +0200 Subject: [PATCH 1/5] refs #6023 Fix change rol bug --- back/methods/vn-user/privileges.js | 66 ++++++++++++-------- modules/account/back/methods/account/sync.js | 5 ++ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 08cfaaae8..05ad4481c 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -40,44 +40,56 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const myOptions = {}; + let tx; if (typeof options == 'object') Object.assign(myOptions, options); - const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + }; - const userToUpdate = await Self.findById(id, { - fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], - include: { - relation: 'role', - scope: { - fields: ['name'] + try { + const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); + + const userToUpdate = await Self.findById(id, { + fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], + include: { + relation: 'role', + scope: { + fields: ['name'] + } } - } - }, myOptions); + }, myOptions); - if (!user.hasGrant) - throw new UserError(`You don't have grant privilege`); + if (!user.hasGrant) + throw new UserError(`You don't have grant privilege`); - const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); + const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); - if (!hasRoleFromUser) - throw new UserError(`You don't own the role and you can't assign it to another user`); - - if (hasGrant != null) - userToUpdate.hasGrant = hasGrant; - - if (roleFk) { - const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); - const hasRole = await Self.hasRole(userId, role.name, myOptions); - - if (!hasRole) + if (!hasRoleFromUser) throw new UserError(`You don't own the role and you can't assign it to another user`); - userToUpdate.roleFk = roleFk; - } + if (hasGrant != null) + userToUpdate.hasGrant = hasGrant; - await userToUpdate.save(userToUpdate); - await models.Account.sync(userToUpdate.name); + if (roleFk) { + const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); + const hasRole = await Self.hasRole(userId, role.name, myOptions); + + if (!hasRole) + throw new UserError(`You don't own the role and you can't assign it to another user`); + + userToUpdate.roleFk = roleFk; + } + + await userToUpdate.save(myOptions); + await models.Account.sync(userToUpdate.name, null, null, myOptions); + await tx.commit(); + } catch (err) { + await tx.rollback(); + throw err; + }; }; }; diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index a5befc22c..3ab19eed5 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -30,6 +30,11 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + }; + const models = Self.app.models; const user = await models.VnUser.findOne({ fields: ['id'], -- 2.40.1 From 9f6d034f9cf044f9ab688bb860bf4277d1df7bec Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 29 Aug 2023 13:45:20 +0200 Subject: [PATCH 2/5] refs #6023 Minor changes --- back/methods/vn-user/privileges.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 05ad4481c..0520fd5c2 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -86,9 +86,9 @@ module.exports = Self => { await userToUpdate.save(myOptions); await models.Account.sync(userToUpdate.name, null, null, myOptions); - await tx.commit(); + if (tx) await tx.commit(); } catch (err) { - await tx.rollback(); + if (tx) await tx.rollback(); throw err; }; }; -- 2.40.1 From 0dbb77fc646f625df5432ba655c7a9da0357034e Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 31 Aug 2023 09:20:33 +0200 Subject: [PATCH 3/5] refs #6023 Transactioned sync --- modules/account/back/methods/account/sync.js | 31 +++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index 3ab19eed5..c4f9cb181 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -25,8 +25,10 @@ module.exports = Self => { }); Self.sync = async function(userName, password, force, options) { + const models = Self.app.models; const myOptions = {}; - + let tx; + if (typeof options == 'object') Object.assign(myOptions, options); @@ -35,16 +37,23 @@ module.exports = Self => { myOptions.transaction = tx; }; - const models = Self.app.models; - const user = await models.VnUser.findOne({ - fields: ['id'], - where: {name: userName} - }, myOptions); - const isSync = !await models.UserSync.exists(userName, myOptions); + try { + const user = await models.VnUser.findOne({ + fields: ['id'], + where: {name: userName} + }, myOptions); + const isSync = !await models.UserSync.exists(userName, myOptions); - if (!force && isSync && user) return; - await models.AccountConfig.syncUser(userName, password); - await models.UserSync.destroyById(userName, myOptions); + if (!force && isSync && user) { + if (tx) await tx.rollback(); + return; + } + await models.AccountConfig.syncUser(userName, password); + await models.UserSync.destroyById(userName, myOptions); + if (tx) await tx.commit(); + } catch (err) { + if (tx) await tx.rollback(); + throw err; + } }; }; - -- 2.40.1 From 9f92bc4b4c5e72bc63385605a115f6d464416dac Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 10 Nov 2023 11:43:42 +0100 Subject: [PATCH 4/5] fix: refs #6023 Rollback privileges.js --- back/methods/vn-user/privileges.js | 66 ++++++++++++------------------ 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js index 0520fd5c2..08cfaaae8 100644 --- a/back/methods/vn-user/privileges.js +++ b/back/methods/vn-user/privileges.js @@ -40,56 +40,44 @@ module.exports = Self => { 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; - }; + const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); - try { - const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions); - - const userToUpdate = await Self.findById(id, { - fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], - include: { - relation: 'role', - scope: { - fields: ['name'] - } + const userToUpdate = await Self.findById(id, { + fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'], + include: { + relation: 'role', + scope: { + fields: ['name'] } - }, myOptions); + } + }, myOptions); - if (!user.hasGrant) - throw new UserError(`You don't have grant privilege`); + if (!user.hasGrant) + throw new UserError(`You don't have grant privilege`); - const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); + const hasRoleFromUser = await Self.hasRole(userId, userToUpdate.role().name, myOptions); - if (!hasRoleFromUser) + if (!hasRoleFromUser) + throw new UserError(`You don't own the role and you can't assign it to another user`); + + if (hasGrant != null) + userToUpdate.hasGrant = hasGrant; + + if (roleFk) { + const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); + const hasRole = await Self.hasRole(userId, role.name, myOptions); + + if (!hasRole) throw new UserError(`You don't own the role and you can't assign it to another user`); - if (hasGrant != null) - userToUpdate.hasGrant = hasGrant; + userToUpdate.roleFk = roleFk; + } - if (roleFk) { - const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions); - const hasRole = await Self.hasRole(userId, role.name, myOptions); - - if (!hasRole) - throw new UserError(`You don't own the role and you can't assign it to another user`); - - userToUpdate.roleFk = roleFk; - } - - await userToUpdate.save(myOptions); - await models.Account.sync(userToUpdate.name, null, null, myOptions); - if (tx) await tx.commit(); - } catch (err) { - if (tx) await tx.rollback(); - throw err; - }; + await userToUpdate.save(userToUpdate); + await models.Account.sync(userToUpdate.name); }; }; -- 2.40.1 From b7da144967c5c34cdcd937ae39169fcae8001df1 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 10 Nov 2023 11:55:37 +0100 Subject: [PATCH 5/5] feat: refs #6023 Added SELECT FOR UPDATE --- modules/account/back/methods/account/sync.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/account/back/methods/account/sync.js b/modules/account/back/methods/account/sync.js index c4f9cb181..8548e71f3 100644 --- a/modules/account/back/methods/account/sync.js +++ b/modules/account/back/methods/account/sync.js @@ -48,6 +48,13 @@ module.exports = Self => { if (tx) await tx.rollback(); return; } + + await Self.rawSql(` + SELECT id + FROM account.user + WHERE id = ? + FOR UPDATE`, [user.id], myOptions); + await models.AccountConfig.syncUser(userName, password); await models.UserSync.destroyById(userName, myOptions); if (tx) await tx.commit(); -- 2.40.1