11import { MeteorError , Room , ServiceClass } from '@rocket.chat/core-services' ;
22import type { AbacActor , IAbacService } from '@rocket.chat/core-services' ;
33import { AbacAccessOperation , AbacObjectType } from '@rocket.chat/core-typings' ;
4- import type { IAbacAttribute , IAbacAttributeDefinition , IRoom , AtLeast , IUser , ILDAPEntry , ISubscription } from '@rocket.chat/core-typings' ;
4+ import type {
5+ IAbacAttribute ,
6+ IAbacAttributeDefinition ,
7+ IRoom ,
8+ AtLeast ,
9+ IUser ,
10+ ILDAPEntry ,
11+ ISubscription ,
12+ AbacAuditReason ,
13+ } from '@rocket.chat/core-typings' ;
514import { Logger } from '@rocket.chat/logger' ;
615import { Rooms , AbacAttributes , Users , Subscriptions , Settings } from '@rocket.chat/models' ;
716import { escapeRegExp } from '@rocket.chat/string-helpers' ;
8- import type { Document , UpdateFilter } from 'mongodb' ;
17+ import type { Document , FindCursor , UpdateFilter } from 'mongodb' ;
918import pLimit from 'p-limit' ;
1019
1120import { Audit } from './audit' ;
@@ -550,12 +559,8 @@ export class AbacService extends ServiceClass implements IAbacService {
550559 }
551560
552561 // When a user is not compliant, remove them from the room automatically
553- await Room . removeUserFromRoom ( room . _id , fullUser , {
554- skipAppPreEvents : true ,
555- customSystemMessage : 'abac-removed-user-from-room' as const ,
556- } ) ;
562+ await this . removeUserFromRoom ( room , fullUser , 'realtime-policy-eval' ) ;
557563
558- void Audit . actionPerformed ( { _id : user . _id , username : fullUser . username } , { _id : room . _id } , 'realtime-policy-eval' ) ;
559564 return false ;
560565 }
561566
@@ -595,22 +600,7 @@ export class AbacService extends ServiceClass implements IAbacService {
595600 const userRemovalPromises = [ ] ;
596601 for await ( const doc of cursor ) {
597602 usersToRemove . push ( doc . _id ) ;
598- userRemovalPromises . push (
599- limit ( ( ) =>
600- Room . removeUserFromRoom ( rid , doc , {
601- skipAppPreEvents : true ,
602- customSystemMessage : 'abac-removed-user-from-room' as const ,
603- } )
604- . then ( ( ) => void Audit . actionPerformed ( { _id : doc . _id , username : doc . username } , { _id : rid } , 'room-attributes-change' ) )
605- . catch ( ( err ) => {
606- this . logger . error ( {
607- msg : 'Failed to remove user from ABAC room after room attributes changed' ,
608- rid,
609- err,
610- } ) ;
611- } ) ,
612- ) ,
613- ) ;
603+ userRemovalPromises . push ( limit ( ( ) => this . removeUserFromRoom ( room , doc , 'room-attributes-change' ) ) ) ;
614604 }
615605
616606 if ( ! usersToRemove . length ) {
@@ -627,12 +617,36 @@ export class AbacService extends ServiceClass implements IAbacService {
627617 }
628618 }
629619
620+ private async removeUserFromRoom ( room : AtLeast < IRoom , '_id' > , user : IUser , reason : AbacAuditReason ) : Promise < void > {
621+ return Room . removeUserFromRoom ( room . _id , user , {
622+ skipAppPreEvents : true ,
623+ customSystemMessage : 'abac-removed-user-from-room' as const ,
624+ } )
625+ . then ( ( ) => void Audit . actionPerformed ( { _id : user . _id , username : user . username } , { _id : room . _id } , reason ) )
626+ . catch ( ( err ) => {
627+ this . logger . error ( {
628+ msg : 'Failed to remove user from ABAC room' ,
629+ rid : room . _id ,
630+ err,
631+ reason,
632+ } ) ;
633+ } ) ;
634+ }
635+
636+ private async removeUserFromRoomList ( roomList : FindCursor < IRoom > , user : IUser , reason : AbacAuditReason ) : Promise < void > {
637+ const removalPromises : Promise < void > [ ] = [ ] ;
638+ for await ( const room of roomList ) {
639+ removalPromises . push ( limit ( ( ) => this . removeUserFromRoom ( room , user , reason ) ) ) ;
640+ }
641+
642+ await Promise . all ( removalPromises ) ;
643+ }
644+
630645 protected async onSubjectAttributesChanged ( user : IUser , _next : IAbacAttributeDefinition [ ] ) : Promise < void > {
631646 if ( ! user ?. _id || ! Array . isArray ( user . __rooms ) || ! user . __rooms . length ) {
632647 return ;
633648 }
634-
635- const roomIds : string [ ] = user . __rooms ;
649+ const roomIds = user . __rooms ;
636650
637651 try {
638652 // No attributes: no rooms :(
@@ -645,28 +659,7 @@ export class AbacService extends ServiceClass implements IAbacService {
645659 { projection : { _id : 1 } } ,
646660 ) ;
647661
648- const removalPromises : Promise < void > [ ] = [ ] ;
649- for await ( const room of cursor ) {
650- removalPromises . push (
651- limit ( ( ) =>
652- Room . removeUserFromRoom ( room . _id , user , {
653- skipAppPreEvents : true ,
654- customSystemMessage : 'abac-removed-user-from-room' as const ,
655- } )
656- . then ( ( ) => void Audit . actionPerformed ( { _id : user . _id , username : user . username } , { _id : room . _id } , 'ldap-sync' ) )
657- . catch ( ( err ) => {
658- this . logger . error ( {
659- msg : 'Failed to remove user from ABAC room after room attributes changed' ,
660- rid : room . _id ,
661- err,
662- } ) ;
663- } ) ,
664- ) ,
665- ) ;
666- }
667-
668- await Promise . all ( removalPromises ) ;
669- return ;
662+ return await this . removeUserFromRoomList ( cursor , user , 'ldap-sync' ) ;
670663 }
671664
672665 const query = {
@@ -676,27 +669,7 @@ export class AbacService extends ServiceClass implements IAbacService {
676669
677670 const cursor = Rooms . find ( query , { projection : { _id : 1 } } ) ;
678671
679- const removalPromises : Promise < unknown > [ ] = [ ] ;
680- for await ( const room of cursor ) {
681- removalPromises . push (
682- limit ( ( ) =>
683- Room . removeUserFromRoom ( room . _id , user , {
684- skipAppPreEvents : true ,
685- customSystemMessage : 'abac-removed-user-from-room' as const ,
686- } )
687- . then ( ( ) => void Audit . actionPerformed ( { _id : user . _id , username : user . username } , { _id : room . _id } , 'ldap-sync' ) )
688- . catch ( ( err ) => {
689- this . logger . error ( {
690- msg : 'Failed to remove user from ABAC room after room attributes changed' ,
691- rid : room . _id ,
692- err,
693- } ) ;
694- } ) ,
695- ) ,
696- ) ;
697- }
698-
699- await Promise . all ( removalPromises ) ;
672+ return await this . removeUserFromRoomList ( cursor , user , 'ldap-sync' ) ;
700673 } catch ( err ) {
701674 this . logger . error ( {
702675 msg : 'Failed to query and remove user from non-compliant ABAC rooms' ,
0 commit comments