151 lines
5.3 KiB
JavaScript
151 lines
5.3 KiB
JavaScript
|
|
/**
|
||
|
|
* 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]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|