@@ -4,7 +4,7 @@ import { expect } from 'chai';
44import { before , after , describe , it } from 'mocha' ;
55import { MongoClient } from 'mongodb' ;
66
7- import { getCredentials , request , credentials , methodCall } from '../../data/api-data' ;
7+ import { api , getCredentials , request , credentials , methodCall } from '../../data/api-data' ;
88import { sleep } from '../../data/livechat/utils' ;
99import {
1010 mockServerHealthy ,
@@ -190,7 +190,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
190190
191191 it ( 'POST /abac/users/sync should return 403' , async ( ) => {
192192 await request
193- . post ( ` ${ v1 } / abac/users/sync` )
193+ . post ( api ( ' abac/users/sync' ) )
194194 . set ( credentials )
195195 . send ( { usernames : [ 'x' ] } )
196196 . expect ( 403 ) ;
@@ -1451,6 +1451,17 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
14511451 } ) ;
14521452 } ) ;
14531453
1454+ it ( 'POST /abac/users/sync should fail with error-abac-not-enabled' , async ( ) => {
1455+ await request
1456+ . post ( api ( 'abac/users/sync' ) )
1457+ . set ( credentials )
1458+ . send ( { ids : [ 'no-such-user-id' ] } )
1459+ . expect ( 400 )
1460+ . expect ( ( res ) => {
1461+ expect ( res . body . error ) . to . include ( 'error-abac-not-enabled' ) ;
1462+ } ) ;
1463+ } ) ;
1464+
14541465 after ( async ( ) => {
14551466 await updateSetting ( 'ABAC_Enabled' , true ) ;
14561467 } ) ;
@@ -1832,6 +1843,27 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
18321843 } ) ;
18331844 } ) ;
18341845
1846+ describe ( 'POST /abac/users/sync (strategy-agnostic)' , ( ) => {
1847+ before ( async ( ) => {
1848+ await updateSetting ( 'ABAC_Enabled' , true ) ;
1849+ } ) ;
1850+
1851+ after ( async ( ) => {
1852+ await updateSetting ( 'ABAC_Enabled' , false ) ;
1853+ } ) ;
1854+
1855+ it ( 'responds 200 with success:true when ABAC_Enabled=true and PDP type=local (no-match id)' , async ( ) => {
1856+ await request
1857+ . post ( api ( 'abac/users/sync' ) )
1858+ . set ( credentials )
1859+ . send ( { ids : [ 'no-such-user-id' ] } )
1860+ . expect ( 200 )
1861+ . expect ( ( res ) => {
1862+ expect ( res . body ) . to . have . property ( 'success' , true ) ;
1863+ } ) ;
1864+ } ) ;
1865+ } ) ;
1866+
18351867 describe ( 'Room access (invite, addition)' , ( ) => {
18361868 let roomWithoutAttr : IRoom ;
18371869 let roomWithAttr : IRoom ;
@@ -2503,7 +2535,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
25032535
25042536 it ( 'should sync ABAC attributes for SOME users via /abac/users/sync' , async ( ) => {
25052537 await request
2506- . post ( ` ${ v1 } / abac/users/sync` )
2538+ . post ( api ( ' abac/users/sync' ) )
25072539 . set ( credentials )
25082540 . send ( {
25092541 usernames : [ 'david.scott' , 'gene.cernan' ] ,
@@ -2533,7 +2565,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
25332565 it ( 'should fail /abac/users/sync when more than 100 usernames are provided' , async ( ) => {
25342566 const usernames = Array . from ( { length : 101 } , ( _ , i ) => `user_${ i } @example.com` ) ;
25352567 await request
2536- . post ( ` ${ v1 } / abac/users/sync` )
2568+ . post ( api ( ' abac/users/sync' ) )
25372569 . set ( credentials )
25382570 . send ( {
25392571 usernames,
@@ -2547,7 +2579,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
25472579 it ( 'should fail /abac/users/sync when more than 100 ids are provided' , async ( ) => {
25482580 const ids = Array . from ( { length : 101 } , ( _ , i ) => `id_${ i } ` ) ;
25492581 await request
2550- . post ( ` ${ v1 } / abac/users/sync` )
2582+ . post ( api ( ' abac/users/sync' ) )
25512583 . set ( credentials )
25522584 . send ( {
25532585 ids,
@@ -2561,7 +2593,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
25612593 it ( 'should fail /abac/users/sync when more than 100 emails are provided' , async ( ) => {
25622594 const emails = Array . from ( { length : 101 } , ( _ , i ) => `user_${ i } @example.com` ) ;
25632595 await request
2564- . post ( ` ${ v1 } / abac/users/sync` )
2596+ . post ( api ( ' abac/users/sync' ) )
25652597 . set ( credentials )
25662598 . send ( {
25672599 emails,
@@ -2575,7 +2607,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
25752607 it ( 'should fail /abac/users/sync when more than 100 ldapIds are provided' , async ( ) => {
25762608 const ldapIds = Array . from ( { length : 101 } , ( _ , i ) => `ldap_${ i } ` ) ;
25772609 await request
2578- . post ( ` ${ v1 } / abac/users/sync` )
2610+ . post ( api ( ' abac/users/sync' ) )
25792611 . set ( credentials )
25802612 . send ( {
25812613 ldapIds,
@@ -2589,7 +2621,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
25892621 it ( 'should succeed /abac/users/sync when exactly 100 usernames are provided (boundary)' , async ( ) => {
25902622 const usernames = Array . from ( { length : 100 } , ( _ , i ) => `boundary_user_${ i } ` ) ;
25912623 await request
2592- . post ( ` ${ v1 } / abac/users/sync` )
2624+ . post ( api ( ' abac/users/sync' ) )
25932625 . set ( credentials )
25942626 . send ( {
25952627 usernames,
@@ -2667,7 +2699,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
26672699 expect ( sergeiInitialAttrs [ 0 ] . values ) . to . include ( initialDept ) ;
26682700
26692701 await request
2670- . post ( ` ${ v1 } / abac/users/sync` )
2702+ . post ( api ( ' abac/users/sync' ) )
26712703 . set ( credentials )
26722704 . send ( {
26732705 usernames : [ 'david.scott' , 'sergei.krikalev' ] ,
@@ -3424,6 +3456,118 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
34243456 } ) ;
34253457 } ) ;
34263458
3459+ describe ( 'Re-evaluation via POST /abac/users/sync' , ( ) => {
3460+ describe ( 'PDP DENY removes the synced user' , ( ) => {
3461+ let room : IRoom ;
3462+ let user : IUser ;
3463+ const username = `abac-sync-deny-${ Date . now ( ) } ` ;
3464+ const email = `${ username } @rocket.chat` ;
3465+
3466+ before ( async function ( ) {
3467+ this . timeout ( 15000 ) ;
3468+
3469+ user = await createUser ( { username, email } ) ;
3470+ room = ( await createRoom ( { type : 'p' , name : `extpdp-sync-deny-${ Date . now ( ) } ` } ) ) . body . group ;
3471+ await request
3472+ . post ( api ( 'groups.invite' ) )
3473+ . set ( credentials )
3474+ . send ( { roomId : room . _id , usernames : [ user . username ] } )
3475+ . expect ( 200 ) ;
3476+
3477+ await mockServerReset ( ) ;
3478+ await seedDefaultMocks ( ) ;
3479+ await seedBulkDecisionByEntity ( [ adminEmail , email ] , 'DECISION_DENY' ) ;
3480+
3481+ await request
3482+ . post ( api ( `abac/rooms/${ room . _id } /attributes/${ attrKey } ` ) )
3483+ . set ( credentials )
3484+ . send ( { values : [ 'alpha' ] } )
3485+ . expect ( 200 ) ;
3486+ } ) ;
3487+
3488+ after ( async ( ) => {
3489+ await Promise . all ( [ deleteRoom ( { type : 'p' , roomId : room . _id } ) , deleteUser ( user ) ] ) ;
3490+ } ) ;
3491+
3492+ it ( 'keeps the user before re-evaluation' , async ( ) => {
3493+ const res = await request . get ( api ( 'groups.members' ) ) . set ( credentials ) . query ( { roomId : room . _id } ) . expect ( 200 ) ;
3494+ const usernames = res . body . members . map ( ( m : IUser ) => m . username ) ;
3495+ expect ( usernames ) . to . include ( user . username ) ;
3496+ } ) ;
3497+
3498+ it ( 'removes the user when the Virtru PDP returns DENY' , async ( ) => {
3499+ await mockServerReset ( ) ;
3500+ await seedDefaultMocks ( ) ;
3501+ await seedBulkDecisionByEntity ( [ adminEmail ] , 'DECISION_DENY' ) ;
3502+
3503+ await request
3504+ . post ( api ( 'abac/users/sync' ) )
3505+ . set ( credentials )
3506+ . send ( { usernames : [ user . username ] } )
3507+ . expect ( 200 ) ;
3508+
3509+ const res = await request . get ( api ( 'groups.members' ) ) . set ( credentials ) . query ( { roomId : room . _id } ) . expect ( 200 ) ;
3510+ const usernames = res . body . members . map ( ( m : IUser ) => m . username ) ;
3511+ expect ( usernames ) . to . not . include ( user . username ) ;
3512+ } ) ;
3513+
3514+ it ( 'keeps the room creator (permitted) after re-evaluation' , async ( ) => {
3515+ const res = await request . get ( api ( 'groups.members' ) ) . set ( credentials ) . query ( { roomId : room . _id } ) . expect ( 200 ) ;
3516+ const memberIds = res . body . members . map ( ( m : IUser ) => m . _id ) ;
3517+ expect ( memberIds ) . to . include ( credentials [ 'X-User-Id' ] ) ;
3518+ } ) ;
3519+ } ) ;
3520+
3521+ describe ( 'PDP PERMIT keeps the synced user' , ( ) => {
3522+ let room : IRoom ;
3523+ let user : IUser ;
3524+ const username = `abac-sync-permit-${ Date . now ( ) } ` ;
3525+ const email = `${ username } @rocket.chat` ;
3526+
3527+ before ( async function ( ) {
3528+ this . timeout ( 15000 ) ;
3529+
3530+ user = await createUser ( { username, email } ) ;
3531+ room = ( await createRoom ( { type : 'p' , name : `extpdp-sync-permit-${ Date . now ( ) } ` } ) ) . body . group ;
3532+ await request
3533+ . post ( api ( 'groups.invite' ) )
3534+ . set ( credentials )
3535+ . send ( { roomId : room . _id , usernames : [ user . username ] } )
3536+ . expect ( 200 ) ;
3537+
3538+ await mockServerReset ( ) ;
3539+ await seedDefaultMocks ( ) ;
3540+ await seedBulkDecisionByEntity ( [ adminEmail , email ] , 'DECISION_DENY' ) ;
3541+
3542+ await request
3543+ . post ( api ( `abac/rooms/${ room . _id } /attributes/${ attrKey } ` ) )
3544+ . set ( credentials )
3545+ . send ( { values : [ 'alpha' ] } )
3546+ . expect ( 200 ) ;
3547+ } ) ;
3548+
3549+ after ( async ( ) => {
3550+ await Promise . all ( [ deleteRoom ( { type : 'p' , roomId : room . _id } ) , deleteUser ( user ) ] ) ;
3551+ } ) ;
3552+
3553+ it ( 'keeps the user when the Virtru PDP returns PERMIT' , async ( ) => {
3554+ await mockServerReset ( ) ;
3555+ await seedDefaultMocks ( ) ;
3556+ await seedBulkDecisionByEntity ( [ adminEmail , email ] , 'DECISION_DENY' ) ;
3557+
3558+ await request
3559+ . post ( api ( 'abac/users/sync' ) )
3560+ . set ( credentials )
3561+ . send ( { usernames : [ user . username ] } )
3562+ . expect ( 200 ) ;
3563+
3564+ const res = await request . get ( api ( 'groups.members' ) ) . set ( credentials ) . query ( { roomId : room . _id } ) . expect ( 200 ) ;
3565+ const usernames = res . body . members . map ( ( m : IUser ) => m . username ) ;
3566+ expect ( usernames ) . to . include ( user . username ) ;
3567+ } ) ;
3568+ } ) ;
3569+ } ) ;
3570+
34273571 describe ( '[GET] /abac/pdp/health' , ( ) => {
34283572 beforeEach ( async ( ) => {
34293573 await mockServerReset ( ) ;
@@ -3945,7 +4089,7 @@ const addAbacAttributesToUserDirectly = async (userId: string, abacAttributes: I
39454089
39464090 it ( 'POST /abac/users/sync is NOT blocked by external attribute store (no error-abac-attribute-store-external)' , async ( ) => {
39474091 const res = await request
3948- . post ( ` ${ v1 } / abac/users/sync` )
4092+ . post ( api ( ' abac/users/sync' ) )
39494093 . set ( credentials )
39504094 . send ( { usernames : [ 'no-such-user-vstore' ] } ) ;
39514095 expect ( res . body ?. error ) . to . not . equal ( 'error-abac-attribute-store-external' ) ;
0 commit comments