From 277745a5ca1a7f4aa48bdd5702bf4a4de8bd0958 Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Wed, 18 Jan 2023 22:27:50 +1100 Subject: [PATCH] Fix the completely fucked up "my permission", the board equivalent, and staff permissions page since a recent permission update. Upside is it now considers the "parent" thing, which is nice. --- lib/permission/permission.js | 9 +++++---- lib/permission/permissions.js | 4 ++-- models/forms/editaccount.js | 3 +-- models/forms/editstaff.js | 15 +++------------ models/pages/manage/editstaff.js | 4 +++- models/pages/manage/mypermissions.js | 3 +++ models/pages/mypermissions.js | 3 +++ views/includes/globalpermissionsform.pug | 3 ++- views/mixins/mypermissions.pug | 19 +++++++++++-------- views/pages/editstaff.pug | 19 +++++++++++-------- views/pages/managemypermissions.pug | 2 +- views/pages/mypermissions.pug | 2 +- 12 files changed, 46 insertions(+), 40 deletions(-) diff --git a/lib/permission/permission.js b/lib/permission/permission.js index 5de21e9d..3aa85f9c 100644 --- a/lib/permission/permission.js +++ b/lib/permission/permission.js @@ -11,7 +11,7 @@ class Permission extends BigBitfield { // List of permission bits static allPermissions = Object.values(Permissions) - .filter(e => typeof e[1] === 'number'); + .filter(v => typeof v === 'number'); // Convert to a map of bit to metadata and state, for use in templates toJSON() { @@ -26,8 +26,9 @@ class Permission extends BigBitfield { } // Update permission based on body and another users permission - handleBody(body, editorPermission) { - for (let bit in Metadata) { + handleBody(body, editorPermission, boardOnly=false) { + const handlingBits = boardOnly ? Permissions._MANAGE_BOARD_BITS : Object.keys(Metadata); + for (let bit of handlingBits) { // If perm has no "parent" bit, or current user has the parent permission, set each bit based on the form input const allowedParent = !Metadata[bit].parent || editorPermission.get(Metadata[bit].parent); @@ -39,7 +40,7 @@ class Permission extends BigBitfield { applyInheritance() { if (this.get(Permissions.ROOT)){ //root gets all perms - this.setAll(this.constructor.allPermissions); + this.setAll(Permission.allPermissions); } else if (this.get(Permissions.MANAGE_BOARD_OWNER)) { //BOs and "global staff" this.setAll(Permissions._MANAGE_BOARD_BITS); } diff --git a/lib/permission/permissions.js b/lib/permission/permissions.js index 27ed5766..6f3c6ed8 100644 --- a/lib/permission/permissions.js +++ b/lib/permission/permissions.js @@ -75,13 +75,13 @@ const Metadata = Object.seal(Object.freeze(Object.preventExtensions({ [Permissions.MANAGE_GLOBAL_ACCOUNTS]: { label: 'Accounts', desc: 'Access the accounts list. Ability to search/sort. Ability to edit permissions of any user.', parent: Permissions.ROOT }, [Permissions.MANAGE_GLOBAL_ROLES]: { label: 'Roles', desc: 'Access roles list. Ability to edit roles', parent: Permissions.ROOT }, - [Permissions.MANAGE_BOARD_OWNER]: { title: 'Board Management', subtitle: 'Note: Setting board management permissions on an account/role level will grant them globally i.e for all boards.\nTo make somebody a normal board owner/staff, transfer them the board or give them the appropriate permissions in the board staff permission editing interface.', label: 'Board Owner', desc: 'Full control of the board, equivalent to the BO. Can delete and/or transfer the board. Can only be given by somebody else with "Board Owner" permission. Use with caution!' }, + [Permissions.MANAGE_BOARD_OWNER]: { title: 'Board Management', subtitle: 'Note: Setting board management permissions on an account/role level will grant them globally i.e for all boards.\nTo make somebody a normal board owner/staff, transfer them the board or give them the appropriate permissions in the board staff permission editing interface.', label: 'Board Owner', desc: 'Full control of the board, equivalent to the BO. Can delete and/or transfer the board. Can only be given by somebody else with "Board Owner" permission. Use with caution!', parent: Permissions.MANAGE_BOARD_OWNER }, [Permissions.MANAGE_BOARD_GENERAL]: { label: 'Board Staff', desc: 'General board staff permission. Access mod index, catalog, recent posts and reports. Ability to submit mod actions. Bypass board-specific bans and post filters.' }, [Permissions.MANAGE_BOARD_BANS]: { label: 'Bans', desc: 'Access board bans. Ability to unban, edit, or deny appeals.' }, [Permissions.MANAGE_BOARD_LOGS]: { label: 'Logs', desc: 'Access board logs. Ability to search/filter.' }, [Permissions.MANAGE_BOARD_SETTINGS]: { label: 'Settings', desc: 'Access board settings. Ability to change any settings. Settings page will show transfer/delete forms for those with "Board Owner" permission.' }, [Permissions.MANAGE_BOARD_CUSTOMISATION]: { label: 'Customisation', desc: 'Access to board assets and custompages. Ability to upload, create, edit, delete.' }, - [Permissions.MANAGE_BOARD_STAFF]: { label: 'Staff', desc: 'Access to staff management, and ability to add or remove permissions from others. Can only be given by somebody else with "Board Owner" permission. Use with caution!' }, + [Permissions.MANAGE_BOARD_STAFF]: { label: 'Staff', desc: 'Access to staff management, and ability to add or remove permissions from others. Can only be given by somebody else with "Board Owner" permission. Use with caution!', parent: Permissions.MANAGE_BOARD_OWNER }, [Permissions.USE_MARKDOWN_PINKTEXT]: { title: 'Post styling', label: 'Pinktext', desc: 'Use pinktext' }, [Permissions.USE_MARKDOWN_GREENTEXT]: { label: 'Greentext', desc: 'Use greentext' }, diff --git a/models/forms/editaccount.js b/models/forms/editaccount.js index 9aec55ac..45fdd023 100644 --- a/models/forms/editaccount.js +++ b/models/forms/editaccount.js @@ -13,9 +13,8 @@ module.exports = async (req, res) => { } else { updatingPermissions = new Permission(res.locals.editingAccount.permissions); updatingPermissions.handleBody(req.body, res.locals.permissions); - updatingPermissions.applyInheritance(); } - updatingPermissions.applyInheritance(); + // updatingPermissions.applyInheritance(); const updated = await Accounts.setAccountPermissions(req.body.username, updatingPermissions).then(r => r.matchedCount); diff --git a/models/forms/editstaff.js b/models/forms/editstaff.js index 1ed43045..8a5f39fa 100644 --- a/models/forms/editstaff.js +++ b/models/forms/editstaff.js @@ -2,24 +2,15 @@ const { Boards } = require(__dirname+'/../../db/') , dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') - , { Permissions } = require(__dirname+'/../../lib/permission/permissions.js') , Permission = require(__dirname+'/../../lib/permission/permission.js'); module.exports = async (req, res) => { let updatingPermissions = new Permission(res.locals.board.staff[req.body.username].permissions); - //maybe these can be changed - //updatingPermissions.set(Permissions.MANAGE_BOARD_GENERSL, (req.body.MANAGE_BOARD_GENERAL != null)) - updatingPermissions.set(Permissions.MANAGE_BOARD_BANS, (req.body.MANAGE_BOARD_BANS != null)); - updatingPermissions.set(Permissions.MANAGE_BOARD_LOGS, (req.body.MANAGE_BOARD_LOGS != null)); - updatingPermissions.set(Permissions.MANAGE_BOARD_SETTINGS, (req.body.MANAGE_BOARD_SETTINGS != null)); - updatingPermissions.set(Permissions.MANAGE_BOARD_CUSTOMISATION, (req.body.MANAGE_BOARD_CUSTOMISATION != null)); - if (res.locals.permissions.get(Permissions.MANAGE_BOARD_OWNER)) { - //be careful giving others manage_board_owner! - updatingPermissions.set(Permissions.MANAGE_BOARD_OWNER, (req.body.MANAGE_BOARD_OWNER != null)); - updatingPermissions.set(Permissions.MANAGE_BOARD_STAFF, (req.body.MANAGE_BOARD_STAFF != null)); - } + updatingPermissions = new Permission(res.locals.board.staff[req.body.username].permissions); + updatingPermissions.handleBody(req.body, res.locals.permissions, true); + // updatingPermissions.applyInheritance(); const updated = await Boards.setStaffPermissions(req.params.board, req.body.username, updatingPermissions).then(r => r.matchedCount); diff --git a/models/pages/manage/editstaff.js b/models/pages/manage/editstaff.js index e460bb14..4988fe29 100644 --- a/models/pages/manage/editstaff.js +++ b/models/pages/manage/editstaff.js @@ -1,6 +1,7 @@ 'use strict'; -const Permission = require(__dirname+'/../../../lib/permission/permission.js'); +const Permission = require(__dirname+'/../../../lib/permission/permission.js') + , { Permissions } = require(__dirname+'/../../../lib/permission/permissions.js'); module.exports = async (req, res, next) => { @@ -19,6 +20,7 @@ module.exports = async (req, res, next) => { permissions: res.locals.permissions, staffUsername: req.params.staffusername, staffPermissions: new Permission(staffData.permissions), + manageBoardBits: Permissions._MANAGE_BOARD_BITS, }); }; diff --git a/models/pages/manage/mypermissions.js b/models/pages/manage/mypermissions.js index 3fb0e459..14c50173 100644 --- a/models/pages/manage/mypermissions.js +++ b/models/pages/manage/mypermissions.js @@ -1,5 +1,7 @@ 'use strict'; +const { Permissions } = require(__dirname+'/../../../lib/permission/permissions.js'); + module.exports = async (req, res) => { res @@ -8,6 +10,7 @@ module.exports = async (req, res) => { user: res.locals.user, board: res.locals.board, permissions: res.locals.permissions, + manageBoardBits: Permissions._MANAGE_BOARD_BITS, }); }; diff --git a/models/pages/mypermissions.js b/models/pages/mypermissions.js index 7ef5347a..f47b3cfe 100644 --- a/models/pages/mypermissions.js +++ b/models/pages/mypermissions.js @@ -1,5 +1,7 @@ 'use strict'; +const { Permissions } = require(__dirname+'/../../lib/permission/permissions.js'); + module.exports = async (req, res) => { res @@ -7,6 +9,7 @@ module.exports = async (req, res) => { .render('mypermissions', { user: res.locals.user, permissions: res.locals.permissions, + manageBoardBits: Permissions._MANAGE_BOARD_BITS, }); }; diff --git a/views/includes/globalpermissionsform.pug b/views/includes/globalpermissionsform.pug index 31beda95..f26b22c0 100644 --- a/views/includes/globalpermissionsform.pug +++ b/views/includes/globalpermissionsform.pug @@ -6,7 +6,8 @@ for bit, index in Object.keys(jsonPermissions) p #{jsonPermissions[bit].subtitle} .row - const hasParent = jsonPermissions[bit].parent == null || permissions.get(jsonPermissions[bit].parent); - label.postform-style.ph-5(class=(!hasParent ? 'notallowed' : null) title=(!hasParent ? `Requires permission "${jsonPermissions[bit].label}"` : null)) + - const parentLabel = !hasParent ? jsonPermissions[jsonPermissions[bit].parent].label : ''; + label.postform-style.ph-5(class=(!hasParent ? 'notallowed' : null) title=(!hasParent ? `Requires permission "${parentLabel}"` : null)) input(type='checkbox' name=`permission_bit_${bit}` value=bit checked=jsonPermissions[bit].state disabled=!hasParent) .rlabel #{jsonPermissions[bit].label} p #{jsonPermissions[bit].desc} diff --git a/views/mixins/mypermissions.pug b/views/mixins/mypermissions.pug index 0b4d8094..a814c1e8 100644 --- a/views/mixins/mypermissions.pug +++ b/views/mixins/mypermissions.pug @@ -1,10 +1,13 @@ -mixin mypermissions(jsonPermissions, keys) - for perm, index in keys - if jsonPermissions[perm].title && index > 0 +mixin mypermissions(jsonPermissions, boardOnly=false) + - const permissionKeys = boardOnly ? Object.keys(jsonPermissions).filter(p => manageBoardBits.includes(parseInt(p))) : Object.keys(jsonPermissions) + for bit, index in permissionKeys + if jsonPermissions[bit].title && index > 0 hr(size=1) - h4.mv-5 #{jsonPermissions[perm].title} + h4.mv-5 #{jsonPermissions[bit].title} + if jsonPermissions[bit].subtitle + p #{jsonPermissions[bit].subtitle} .row - label.postform-style.ph-5 - input(type='checkbox' checked=jsonPermissions[perm].state disabled) - .rlabel #{jsonPermissions[perm].label} - p #{jsonPermissions[perm].desc} + label.postform-style.ph-5.notallowed + input(type='checkbox' name=`permission_bit_${bit}` value=bit checked=jsonPermissions[bit].state disabled=true) + .rlabel #{jsonPermissions[bit].label} + p #{jsonPermissions[bit].desc} diff --git a/views/pages/editstaff.pug b/views/pages/editstaff.pug index 151807e5..b1449301 100644 --- a/views/pages/editstaff.pug +++ b/views/pages/editstaff.pug @@ -21,14 +21,17 @@ block content input(type='hidden' name='_csrf' value=csrf) input(type='hidden' name='username' value=staffUsername) //-for perm in Object.keys(jsonPermissions) - for perm, index in Object.keys(jsonPermissions).filter(p => p.startsWith('MANAGE_BOARD_')) - if jsonPermissions[perm].title && index > 0 + for bit, index in Object.keys(jsonPermissions).filter(p => manageBoardBits.includes(parseInt(p))) + if jsonPermissions[bit].title && index > 0 hr(size=1) - h4.mv-5 #{jsonPermissions[perm].title} + h4.mv-5 #{jsonPermissions[bit].title} + if jsonPermissions[bit].subtitle + p #{jsonPermissions[bit].subtitle} .row - label.postform-style.ph-5 - - const checkDisabled = !perm.startsWith('MANAGE_BOARD_') || perm === 'MANAGE_BOARD_GENERAL' || (!permissions.get(Permissions.MANAGE_BOARD_OWNER) && (perm==='MANAGE_BOARD_OWNER' || perm==='MANAGE_BOARD_STAFF')); - input(type='checkbox' name=perm value=1 checked=jsonPermissions[perm].state disabled=checkDisabled) - .rlabel #{jsonPermissions[perm].label} - p #{jsonPermissions[perm].desc} + - const hasParent = jsonPermissions[bit].parent == null || permissions.get(jsonPermissions[bit].parent); + - const parentLabel = !hasParent ? jsonPermissions[jsonPermissions[bit].parent].label : ''; + label.postform-style.ph-5(class=(!hasParent ? 'notallowed' : null) title=(!hasParent ? `Requires permission "${parentLabel}"` : null)) + input(type='checkbox' name=`permission_bit_${bit}` value=bit checked=jsonPermissions[bit].state disabled=!hasParent) + .rlabel #{jsonPermissions[bit].label} + p #{jsonPermissions[bit].desc} input(type='submit', value='Save') diff --git a/views/pages/managemypermissions.pug b/views/pages/managemypermissions.pug index a8830f79..09a33777 100644 --- a/views/pages/managemypermissions.pug +++ b/views/pages/managemypermissions.pug @@ -17,4 +17,4 @@ block content | a(href=`/${board._id}/manage/editstaff/${user.username}.html`) [Edit] - const jsonPermissions = permissions.toJSON(); - +mypermissions(jsonPermissions, Object.keys(jsonPermissions).filter(p => p.startsWith('MANAGE_BOARD_'))) + +mypermissions(jsonPermissions, true) diff --git a/views/pages/mypermissions.pug b/views/pages/mypermissions.pug index 3e289dc9..9aea2475 100644 --- a/views/pages/mypermissions.pug +++ b/views/pages/mypermissions.pug @@ -27,4 +27,4 @@ block content | a(href=`/globalmanage/editaccount/${user.username}.html`) [Edit] - const jsonPermissions = permissions.toJSON(); - +mypermissions(jsonPermissions, Object.keys(jsonPermissions)) + +mypermissions(jsonPermissions)