anything-llm/server/utils/helpers/admin/index.js
Timothy Carambat 9a237db3d1
Implement total permission overhaul (#629)
* Implement total permission overhaul
Add explicit permissions on each flex and strict route
Patch issues with role escalation and CRUD of users
Patch permissions on all routes for coverage
Improve middleware to accept role array for clarity

* update comments

* remove permissions to API-keys for manager. Manager could generate API-key and using high-privelege api-key give themselves admin

* update sidebar permissions for multi-user and single user

* update options for mobile sidebar
2024-01-22 14:14:01 -08:00

53 lines
2.2 KiB
JavaScript

const { User } = require("../../../models/user");
const { ROLES } = require("../../middleware/multiUserProtected");
// When a user is updating or creating a user in multi-user, we need to check if they
// are allowed to do this and that the new or existing user will be at or below their permission level.
// the user executing this function should be an admin or manager.
function validRoleSelection(currentUser = {}, newUserParams = {}) {
if (!newUserParams.hasOwnProperty("role"))
return { valid: true, error: null }; // not updating role, so skip.
if (currentUser.role === ROLES.admin) return { valid: true, error: null };
if (currentUser.role === ROLES.manager) {
const validRoles = [ROLES.manager, ROLES.default];
if (!validRoles.includes(newUserParams.role))
return { valid: false, error: "Invalid role selection for user." };
return { valid: true, error: null };
}
return { valid: false, error: "Invalid condition for caller." };
}
// Check to make sure with this update that includes a role change to an existing admin to a non-admin
// that we still have at least one admin left or else they will lock themselves out.
async function canModifyAdmin(userToModify, updates) {
// if updates don't include role property or the user being modified isn't an admin currently - skip.
if (!updates.hasOwnProperty("role")) return { valid: true, error: null };
if (userToModify.role !== ROLES.admin) return { valid: true, error: null };
const adminCount = await User.count({ role: ROLES.admin });
if (adminCount - 1 <= 0)
return {
valid: false,
error: "No system admins will remain if you do this. Update failed.",
};
return { valid: true, error: null };
}
function validCanModify(currentUser, existingUser) {
if (currentUser.role === ROLES.admin) return { valid: true, error: null };
if (currentUser.role === ROLES.manager) {
const validRoles = [ROLES.manager, ROLES.default];
if (!validRoles.includes(existingUser.role))
return { valid: false, error: "Cannot perform that action on user." };
return { valid: true, error: null };
}
return { valid: false, error: "Invalid condition for caller." };
}
module.exports = {
validCanModify,
validRoleSelection,
canModifyAdmin,
};