Skip to content
Snippets Groups Projects
Unverified Commit 190d1ded authored by Ricardo Garim's avatar Ricardo Garim Committed by GitHub
Browse files

refactor: Permissions out of DB Watcher (#32360)

parent 18cae038
No related branches found
No related tags found
No related merge requests found
......@@ -4,6 +4,7 @@ import { isBodyParamsValidPermissionUpdate } from '@rocket.chat/rest-typings';
import { Meteor } from 'meteor/meteor';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { notifyOnPermissionChangedById } from '../../../lib/server/lib/notifyListener';
import { API } from '../api';
API.v1.addRoute(
......@@ -70,6 +71,7 @@ API.v1.addRoute(
for await (const permission of bodyParams.permissions) {
await Permissions.setRoles(permission._id, permission.roles);
void notifyOnPermissionChangedById(permission._id);
}
const result = (await Meteor.callAsync('permissions/get')) as IPermission[];
......
......@@ -9,7 +9,7 @@ import { getUsersInRolePaginated } from '../../../authorization/server/functions
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { hasRoleAsync, hasAnyRoleAsync } from '../../../authorization/server/functions/hasRole';
import { apiDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { notifyListenerOnRoleChanges } from '../../../lib/server/lib/notifyListenerOnRoleChanges';
import { notifyOnRoleChanged } from '../../../lib/server/lib/notifyListener';
import { settings } from '../../../settings/server/index';
import { API } from '../api';
import { getPaginationItems } from '../helpers/getPaginationItems';
......@@ -180,7 +180,7 @@ API.v1.addRoute(
await Roles.removeById(role._id);
void notifyListenerOnRoleChanges(role._id, 'removed', role);
void notifyOnRoleChanged(role, 'removed');
return API.v1.success();
},
......
......@@ -2,6 +2,7 @@ import { Permissions } from '@rocket.chat/models';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { Meteor } from 'meteor/meteor';
import { notifyOnPermissionChangedById } from '../../../lib/server/lib/notifyListener';
import { CONSTANTS, AuthorizationUtils } from '../../lib';
import { hasPermissionAsync } from '../functions/hasPermission';
......@@ -41,11 +42,15 @@ Meteor.methods<ServerMethods>({
action: 'Adding_permission',
});
}
// for setting-based-permissions, authorize the group access as well
if (permission.groupPermissionId) {
await Permissions.addRole(permission.groupPermissionId, role);
void notifyOnPermissionChangedById(permission.groupPermissionId);
}
await Permissions.addRole(permission._id, role);
void notifyOnPermissionChangedById(permission._id);
},
});
......@@ -2,6 +2,7 @@ import { Permissions } from '@rocket.chat/models';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { Meteor } from 'meteor/meteor';
import { notifyOnPermissionChangedById } from '../../../lib/server/lib/notifyListener';
import { CONSTANTS } from '../../lib';
import { hasPermissionAsync } from '../functions/hasPermission';
......@@ -36,10 +37,12 @@ Meteor.methods<ServerMethods>({
// for setting based permissions, revoke the group permission once all setting permissions
// related to this group have been removed
if (permission.groupPermissionId) {
await Permissions.removeRole(permission.groupPermissionId, role);
void notifyOnPermissionChangedById(permission.groupPermissionId);
}
await Permissions.removeRole(permission._id, role);
void notifyOnPermissionChangedById(permission._id);
},
});
import { api, dbWatchersDisabled } from '@rocket.chat/core-services';
import type { IPbxEvent, IRocketChatRecord, IRoom } from '@rocket.chat/core-typings';
import { PbxEvents, Rooms } from '@rocket.chat/models';
import type { IPermission, IRocketChatRecord, IRoom, ISetting, IPbxEvent, IRole } from '@rocket.chat/core-typings';
import { Rooms, Permissions, Settings, PbxEvents, Roles } from '@rocket.chat/models';
type ClientAction = 'inserted' | 'updated' | 'removed';
......@@ -66,6 +66,43 @@ export async function notifyOnRoomChangedByUserDM<T extends IRoom>(
}
}
export async function notifyOnSettingChanged(setting: ISetting, clientAction: ClientAction = 'updated'): Promise<void> {
if (!dbWatchersDisabled) {
return;
}
void api.broadcast('watch.settings', { clientAction, setting });
}
export async function notifyOnPermissionChanged(permission: IPermission, clientAction: ClientAction = 'updated'): Promise<void> {
if (!dbWatchersDisabled) {
return;
}
void api.broadcast('permission.changed', { clientAction, data: permission });
if (permission.level === 'settings' && permission.settingId) {
const setting = await Settings.findOneNotHiddenById(permission.settingId);
if (!setting) {
return;
}
void notifyOnSettingChanged(setting, 'updated');
}
}
export async function notifyOnPermissionChangedById(pid: IPermission['_id'], clientAction: ClientAction = 'updated'): Promise<void> {
if (!dbWatchersDisabled) {
return;
}
const permission = await Permissions.findOneById(pid);
if (!permission) {
return;
}
return notifyOnPermissionChanged(permission, clientAction);
}
export async function notifyOnPbxEventChangedById<T extends IPbxEvent>(
id: T['_id'],
clientAction: ClientAction = 'updated',
......@@ -80,3 +117,27 @@ export async function notifyOnPbxEventChangedById<T extends IPbxEvent>(
void api.broadcast('watch.pbxevents', { clientAction, id, data: item });
}
}
export async function notifyOnRoleChanged<T extends IRole>(role: T, clientAction: 'removed' | 'changed' = 'changed'): Promise<void> {
if (!dbWatchersDisabled) {
return;
}
void api.broadcast('watch.roles', { clientAction, role });
}
export async function notifyOnRoleChangedById<T extends IRole>(
id: T['_id'],
clientAction: 'removed' | 'changed' = 'changed',
): Promise<void> {
if (!dbWatchersDisabled) {
return;
}
const role = await Roles.findOneById(id);
if (!role) {
return;
}
void notifyOnRoleChanged(role, clientAction);
}
import { api, dbWatchersDisabled } from '@rocket.chat/core-services';
import type { IRole } from '@rocket.chat/core-typings';
import { Roles } from '@rocket.chat/models';
type ClientAction = 'inserted' | 'updated' | 'removed';
export async function notifyListenerOnRoleChanges(
rid: IRole['_id'],
clientAction: ClientAction = 'updated',
existingRoleData?: IRole,
): Promise<void> {
if (!dbWatchersDisabled) {
return;
}
const role = existingRoleData || (await Roles.findOneById(rid));
if (!role) {
return;
}
void api.broadcast('watch.roles', {
clientAction,
role,
});
}
......@@ -2,7 +2,7 @@ import { api, MeteorError } from '@rocket.chat/core-services';
import type { IRole } from '@rocket.chat/core-typings';
import { Roles } from '@rocket.chat/models';
import { notifyListenerOnRoleChanges } from '../../../../app/lib/server/lib/notifyListenerOnRoleChanges';
import { notifyOnRoleChanged } from '../../../../app/lib/server/lib/notifyListener';
import { isValidRoleScope } from '../../../../lib/roles/isValidRoleScope';
type InsertRoleOptions = {
......@@ -22,7 +22,7 @@ export const insertRoleAsync = async (roleData: Omit<IRole, '_id'>, options: Ins
const role = await Roles.createWithRandomId(name, scope, description, false, mandatory2fa);
void notifyListenerOnRoleChanges(role._id, 'inserted', role);
void notifyOnRoleChanged(role);
if (options.broadcastUpdate) {
void api.broadcast('user.roleUpdate', {
......
......@@ -2,7 +2,7 @@ import { api, MeteorError } from '@rocket.chat/core-services';
import type { IRole } from '@rocket.chat/core-typings';
import { Roles } from '@rocket.chat/models';
import { notifyListenerOnRoleChanges } from '../../../../app/lib/server/lib/notifyListenerOnRoleChanges';
import { notifyOnRoleChangedById } from '../../../../app/lib/server/lib/notifyListener';
import { isValidRoleScope } from '../../../../lib/roles/isValidRoleScope';
type UpdateRoleOptions = {
......@@ -39,7 +39,7 @@ export const updateRole = async (roleId: IRole['_id'], roleData: Omit<IRole, '_i
await Roles.updateById(roleId, roleData.name, roleData.scope, roleData.description, roleData.mandatory2fa);
void notifyListenerOnRoleChanges(roleId);
void notifyOnRoleChangedById(roleId);
if (options.broadcastUpdate) {
void api.broadcast('user.roleUpdate', {
......
......@@ -33,7 +33,6 @@ export function getWatchCollections(): string[] {
Users.getCollectionName(),
LivechatInquiry.getCollectionName(),
LivechatDepartmentAgents.getCollectionName(),
Permissions.getCollectionName(),
LoginServiceConfiguration.getCollectionName(),
InstanceStatus.getCollectionName(),
IntegrationHistory.getCollectionName(),
......@@ -50,6 +49,7 @@ export function getWatchCollections(): string[] {
collections.push(Roles.getCollectionName());
collections.push(Rooms.getCollectionName());
collections.push(PbxEvents.getCollectionName());
collections.push(Permissions.getCollectionName());
}
if (onlyCollections.length > 0) {
......
import type { IRole, AtLeast } from '@rocket.chat/core-typings';
import { Roles } from '@rocket.chat/models';
import { notifyListenerOnRoleChanges } from '../../../app/lib/server/lib/notifyListenerOnRoleChanges';
import { notifyOnRoleChanged, notifyOnRoleChangedById } from '../../../app/lib/server/lib/notifyListener';
export const createOrUpdateProtectedRoleAsync = async (
roleId: string,
......@@ -20,12 +20,12 @@ export const createOrUpdateProtectedRoleAsync = async (
roleData.mandatory2fa || role.mandatory2fa,
);
void notifyListenerOnRoleChanges(roleId, 'updated', updatedRole);
void notifyOnRoleChanged(updatedRole);
return;
}
const insertedRole = await Roles.insertOne({
await Roles.insertOne({
_id: roleId,
scope: 'Users',
description: '',
......@@ -34,5 +34,5 @@ export const createOrUpdateProtectedRoleAsync = async (
protected: true,
});
void notifyListenerOnRoleChanges(insertedRole.insertedId, 'inserted');
void notifyOnRoleChangedById(roleId);
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment