feat(plugins) Base plugins for rooms and permissions

This commit is contained in:
gh0sTedBuddy
2024-04-07 20:08:20 +01:00
parent 2a2a8c800f
commit 675ef2c5a7
3 changed files with 580 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
/**
* Plugin for handling permissions.
*/
class PermissionsPlugin {
/**
* Predefined roles and their corresponding permissions.
*/
static defaultRoles = {
OWNER: 0o777,
ADMIN: 0o755,
MODERATOR: 0o644,
MEMBER: 0o444,
GUEST: 0o400,
};
/**
* Actions and their corresponding required permissions.
*/
static defaultActions = {
SEND_MESSAGE: 0o400,
MUTE_MEMBER: 0o200,
KICK_MEMBER: 0o200,
GRANT_PERMISSION: 0o100,
REVOKE_PERMISSION: 0o100,
ASSIGN_ROLE: 0o100,
};
/**
* Create a new instance of the PermissionsPlugin.
* @param {Object} [config={}] - The configuration object.
* @param {Object} [config.roles] - The custom roles and their corresponding permissions.
* @param {Object} [config.actions] - The custom actions and their corresponding required permissions.
*/
constructor(config = {}) {
this.roles = {
...PermissionsPlugin.defaultRoles,
...config.roles
};
this.actions = {
...PermissionsPlugin.defaultActions,
...config.actions
};
}
/**
* Initialize the plugin.
* @param {Object} server - The server instance.
*/
initialize(server) {
this.server = server;
this.contexts = new Map();
// Listen for the 'permissions:init' event
server.on('permissions:init', (pluginId, context, initContext) => {
const key = pluginId + context;
this.contexts.set(key, new Map());
initContext({
get: (...args) => this.getPermissions(key, ...args),
has: (...args) => this.hasPermission(key, ...args),
can: (...args) => this.hasPermission(key, ...args),
add: (...args) => this.grantPermission(key, ...args),
remove: (...args) => this.revokePermission(key, ...args),
role: (...args) => this.assignRole(key, ...args),
});
});
}
/**
* Get the permissions for the specified key and identifier.
* @param {string} key - The unique key identifying the plugin and context.
* @param {string} identifier - The identifier of the entity (e.g., user, member).
* @returns {Object} The permissions object.
*/
getPermissions(key, identifier) {
const context = this.contexts.get(key);
if (context) {
const permissions = context.get(identifier);
if (permissions) {
const result = {};
for (const [action, requiredPermission] of Object.entries(this.actions)) {
result[action] = this.hasPermission(permissions, requiredPermission);
}
return result;
}
}
return {};
}
/**
* Check if the specified key and identifier has the given permission.
* @param {string} key - The unique key identifying the plugin and context.
* @param {string} identifier - The identifier of the entity (e.g., user, member).
* @param {string} action - The action to check permissions for.
* @returns {boolean} True if the identifier has the permission, false otherwise.
*/
hasPermission(key, identifier, action) {
const context = this.contexts.get(key);
if (context) {
const permissions = context.get(identifier);
if (permissions) {
const requiredPermission = this.actions[action];
return (permissions & requiredPermission) === requiredPermission;
}
}
return false;
}
/**
* Grant permission to the specified key and identifier for the given action.
* @param {string} key - The unique key identifying the plugin and context.
* @param {string} identifier - The identifier of the entity (e.g., user, member).
* @param {string} action - The action to grant permission for.
*/
grantPermission(key, identifier, action) {
const context = this.contexts.get(key);
if (context) {
const permissions = context.get(identifier) || 0;
context.set(identifier, permissions | this.actions[action]);
}
}
/**
* Revoke permission from the specified key and identifier for the given action.
* @param {string} key - The unique key identifying the plugin and context.
* @param {string} identifier - The identifier of the entity (e.g., user, member).
* @param {string} action - The action to revoke permission for.
*/
revokePermission(key, identifier, action) {
const context = this.contexts.get(key);
if (context) {
const permissions = context.get(identifier);
if (permissions) {
context.set(identifier, permissions & ~this.actions[action]);
}
}
}
/**
* Assign a role to the specified key and identifier.
* @param {string} key - The unique key identifying the plugin and context.
* @param {string} identifier - The identifier of the entity (e.g., user, member).
* @param {string} role - The role to assign.
*/
assignRole(key, identifier, role) {
const context = this.contexts.get(key);
if (context) {
context.set(identifier, this.roles[role]);
}
}
}