Skip to content

Conversation

@KevLehman
Copy link
Member

@KevLehman KevLehman commented Nov 13, 2025

Proposed changes (including videos or screenshots)

Issue(s)

https://rocketchat.atlassian.net/browse/ABAC-54
https://rocketchat.atlassian.net/browse/ABAC-28

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • ABAC attribute management now uses dedicated user attribute operations; when a user's attributes change, they may be automatically removed from rooms that no longer match access rules, with consistent system messages and error handling.
  • Tests

    • Added extensive tests covering attribute merging, unsetting, order/deduplication, immutability, loss/gain detection, and room-removal scenarios.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 13, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Nov 13, 2025

⚠️ No Changeset found

Latest commit: f5f152d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main feature: removing users from rooms when subject attributes no longer match.
Linked Issues check ✅ Passed Code changes implement removal of users from non-compliant rooms when attributes change (ABAC-54) and add event handler logic for attribute changes (ABAC-28).
Out of Scope Changes check ✅ Passed All changes align with PR objectives: new DAO methods, room-removal logic, attribute validation tests, and helper functions for computing non-compliance conditions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/on-subject-attr-changed

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 547f9a5 and f5f152d.

📒 Files selected for processing (5)
  • ee/packages/abac/src/index.spec.ts (8 hunks)
  • ee/packages/abac/src/index.ts (2 hunks)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts (1 hunks)
  • packages/model-typings/src/models/IUsersModel.ts (1 hunks)
  • packages/models/src/models/Users.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • packages/model-typings/src/models/IUsersModel.ts
  • packages/models/src/models/Users.ts
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).

Applied to files:

  • ee/packages/abac/src/index.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/index.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/index.ts
🧬 Code graph analysis (2)
ee/packages/abac/src/index.spec.ts (1)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
ee/packages/abac/src/index.ts (3)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
packages/core-services/src/index.ts (1)
  • Room (171-171)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (6)
ee/packages/abac/src/index.spec.ts (4)

21-22: LGTM!

The new mock functions for setAbacAttributesById and unsetAbacAttributesById are properly declared and wired into the Users mock, aligning with the DAO method changes in the implementation.

Also applies to: 48-49


77-79: LGTM!

The helper correctly extracts updated attributes from the new setAbacAttributesById mock, replacing the previous pattern of inspecting updateOne calls.


95-150: LGTM!

Test expectations properly updated to verify the new DAO methods (setAbacAttributesById, unsetAbacAttributesById) instead of direct updateOne calls, maintaining comprehensive coverage of the merge behavior.


1259-1397: LGTM!

Comprehensive test coverage for buildRoomNonCompliantConditionsFromSubject with well-structured scenarios covering empty input, single/multiple attributes, deduplication, duplicate key handling (last wins), ordering resilience, and input immutability.

ee/packages/abac/src/index.ts (2)

751-811: LGTM with dependency on null guard fix

The implementation correctly handles user attribute changes by removing users from non-compliant rooms. The logic properly distinguishes between users losing all attributes (removed from all ABAC rooms) versus losing specific attribute values (removed only from non-matching rooms).

However, this method depends on receiving a non-null user parameter. The null guard fixes suggested for lines 53-72 are essential to prevent null reference errors here.

Note: Once the null guards are added in addSubjectAttributes, this method will function correctly.


813-836: LGTM!

The query builder correctly constructs MongoDB conditions to identify rooms where a user's attributes are non-compliant:

  1. Rooms requiring attribute keys the user doesn't have ($nin on keys)
  2. Rooms requiring values the user lacks for keys they do have ($nin on values per key)

The implementation properly deduplicates keys (last wins) and values per key, and comprehensive test coverage in the spec file validates the logic.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Nov 14, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (feat/abac@9a6b62f). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             feat/abac   #37506   +/-   ##
============================================
  Coverage             ?   54.26%           
============================================
  Files                ?     2659           
  Lines                ?    49968           
  Branches             ?    11125           
============================================
  Hits                 ?    27113           
  Misses               ?    20724           
  Partials             ?     2131           
Flag Coverage Δ
e2e 57.40% <ø> (?)
e2e-api 42.85% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@KevLehman KevLehman marked this pull request as ready for review November 17, 2025 16:00
@KevLehman KevLehman requested a review from a team as a code owner November 17, 2025 16:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/models/src/models/Users.ts (1)

132-138: ABAC setters look correct; consider explicit return typing for clarity

The new setAbacAttributesById / unsetAbacAttributesById wrappers correctly use findOneAndUpdate with returnDocument: 'after' and the expected $set/$unset shapes. To keep this aligned with IUsersModel and other helpers like setLastRoutingTime, it would be slightly clearer to give these methods an explicit return type (Promise<IUser | null> or Promise<WithId<IUser> | null>) instead of relying on inference, but behavior-wise this is fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 820f30f and 984dc29.

📒 Files selected for processing (5)
  • ee/packages/abac/src/index.spec.ts (8 hunks)
  • ee/packages/abac/src/index.ts (2 hunks)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts (1 hunks)
  • packages/model-typings/src/models/IUsersModel.ts (1 hunks)
  • packages/models/src/models/Users.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/index.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/index.ts
🧬 Code graph analysis (5)
packages/models/src/models/Users.ts (1)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
ee/packages/abac/src/subject-attributes-validations.spec.ts (4)
packages/models/src/index.ts (1)
  • registerServiceModels (231-265)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
ee/packages/abac/src/index.ts (1)
  • AbacService (16-774)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
packages/model-typings/src/models/IUsersModel.ts (1)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
ee/packages/abac/src/index.spec.ts (1)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
ee/packages/abac/src/index.ts (3)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
packages/core-services/src/index.ts (1)
  • Room (171-171)
🔇 Additional comments (5)
packages/model-typings/src/models/IUsersModel.ts (1)

160-162: ABAC user DAO typings align with implementation

The new setAbacAttributesById / unsetAbacAttributesById signatures fit the intended usage: they take a userId plus attributes and return the updated IUser | null, matching the UsersRaw helpers and how AbacService consumes them.

ee/packages/abac/src/subject-attributes-validations.spec.ts (1)

246-280: Room-removal integration tests nicely validate subject-driven clean-up

The "removes user from rooms whose attributes become non-compliant after losing a value" scenario accurately mirrors the production logic: you seed rooms with differing ABAC constraints, attach them via __rooms, run addSubjectAttributes, and assert both abacAttributes and __rooms on the stored user. This is a good high-signal test for buildRoomNonCompliantConditionsFromSubject and onSubjectAttributesChanged.

ee/packages/abac/src/index.spec.ts (2)

21-23: Mocks and expectations correctly track new ABAC user DAO usage

The updated mocks for Users.setAbacAttributesById / Users.unsetAbacAttributesById and the refactored getUpdatedAttributesFromCall ensure tests are validating the new API surface instead of the old updateOne path. The merge/dedup tests around addSubjectAttributes remain accurate and now assert calls to the correct DAO methods.

Also applies to: 75-101


1259-1397: Comprehensive tests for buildRoomNonCompliantConditionsFromSubject

The new "buildRoomNonCompliantConditionsFromSubject (private)" suite thoroughly exercises the helper: empty attributes, multiple keys, value deduplication, last-wins semantics for duplicate keys, order resilience, and input immutability are all covered. This gives strong confidence that subject-based non-compliance queries used in onSubjectAttributesChanged behave as intended.

ee/packages/abac/src/index.ts (1)

688-773: Subject-driven room cleanup logic and helper look correct and well-scoped

The new onSubjectAttributesChanged plus buildRoomNonCompliantConditionsFromSubject implement the required behavior:

  • Early exit when there is no user id or no rooms.
  • When _next is empty, remove the user from all rooms in user.__rooms that have non-empty abacAttributes.
  • When _next is non-empty, build $or conditions that:
    • Match rooms with ABAC keys the user no longer has (key: { $nin: userKeys }).
    • Match rooms where, for keys the user does have, the room requires any value outside the user’s value set (values: { $elemMatch: { $nin: [...] } }).
  • Restrict removal to the current user.__rooms set and use p-limit(20) for bounded concurrency.
  • Log and swallow errors so a failure in one removal doesn’t crash the service.

This matches the intended semantics of “remove users from rooms they no longer satisfy after attribute changes” and the accompanying tests verify the key scenarios (value loss, key loss, unrelated losses, complete loss).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
ee/packages/abac/src/subject-attributes-validations.spec.ts (2)

214-218: Consider extracting the mock to beforeEach for clarity.

The mock definition references usersCol which is initialized in beforeEach (line 237). While this works because the mock is only invoked during test execution, moving the mock assignment into beforeEach would make the dependency more explicit and improve readability.

Apply this diff:

-	const originalCoreServices = jest.requireMock('@rocket.chat/core-services');
-	originalCoreServices.Room.removeUserFromRoom = async (rid: string, user: IUser) => {
-		// @ts-expect-error - test
-		await usersCol.updateOne({ _id: user._id }, { $pull: { __rooms: rid } });
-	};
+	const originalCoreServices = jest.requireMock('@rocket.chat/core-services');
 
 	const insertRoom = async (room: { _id: string; abacAttributes?: IAbacAttributeDefinition[] }) =>
 		roomsCol.insertOne({
 			_id: room._id,
 			name: room._id,
 			t: 'p',
 			abacAttributes: room.abacAttributes,
 		});
 
 	const insertUser = async (user: IUser & { __rooms?: string[] }) =>
 		usersCol.insertOne({
 			...user,
 			__rooms: user.__rooms || [],
 		});
 
 	beforeEach(async () => {
 		service = new AbacService();
 		roomsCol = db.collection('rocketchat_room');
 		usersCol = db.collection('users');
+		originalCoreServices.Room.removeUserFromRoom = async (rid: string, user: IUser) => {
+			// @ts-expect-error - test
+			await usersCol.updateOne({ _id: user._id }, { $pull: { __rooms: rid } });
+		};
 		await Promise.all([roomsCol.deleteMany({}), usersCol.deleteMany({})]);
 	});

67-75: Simplify the assertion.

The expression updated?.abacAttributes ?? undefined is redundant. If abacAttributes is undefined or null, the ?? undefined has no effect.

Apply this diff:

-		expect(updated?.abacAttributes ?? undefined).toBeUndefined();
+		expect(updated?.abacAttributes).toBeUndefined();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 984dc29 and a1da8de.

📒 Files selected for processing (1)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
🧬 Code graph analysis (1)
ee/packages/abac/src/subject-attributes-validations.spec.ts (3)
packages/models/src/index.ts (1)
  • registerServiceModels (231-265)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
ee/packages/abac/src/index.ts (1)
  • AbacService (16-774)
🔇 Additional comments (4)
ee/packages/abac/src/subject-attributes-validations.spec.ts (4)

13-23: Past issue resolved: Single teardown confirmed.

The double-closing concern from the previous review has been properly addressed. The top-level afterAll now handles all resource cleanup, and the redundant inner afterAll has been removed.


143-194: Excellent coverage of loss detection scenarios.

The test suite thoroughly covers attribute loss detection logic including value reduction, complete key removal, value growth (no loss), reordering (order-independent comparison), and duplicate merging. The use of Set comparison at line 183 is particularly appropriate for handling order variations.


241-475: Comprehensive coverage of room removal scenarios.

The test suite thoroughly validates the onSubjectAttributesChanged hook behavior across all critical scenarios:

  • Attribute value loss causing non-compliance
  • Complete attribute key loss
  • Attribute growth without triggering removal
  • Room attributes requiring keys the user doesn't have
  • Complete attribute removal
  • Loss of attributes unrelated to room requirements

Each test clearly demonstrates the expected behavior and verifies both database state and room membership changes.


1-476: Well-structured and comprehensive test suite.

This test file provides excellent coverage of the AbacService.addSubjectAttributes functionality:

Strengths:

  • Clear separation between unit tests (attribute manipulation) and integration tests (room removal behavior)
  • Comprehensive edge case coverage including merging, deduplication, loss detection, and room removal scenarios
  • Good use of helper functions for test data creation
  • Proper MongoDB in-memory setup for isolated testing
  • Input immutability verification
  • Clear test naming that describes expected behavior

The test suite aligns well with the service implementation in index.ts and validates the complete workflow from LDAP attribute extraction through user removal from non-compliant rooms.

@KevLehman KevLehman requested review from a team as code owners November 18, 2025 18:16
@KevLehman KevLehman force-pushed the feat/on-subject-attr-changed branch from a1da8de to 547f9a5 Compare November 18, 2025 18:17
@github-actions
Copy link
Contributor

github-actions bot commented Nov 18, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 367MiB 355MiB +12MiB
omnichannel-transcript-service 141MiB 141MiB +3.4KiB
queue-worker-service 141MiB 141MiB +3.6KiB
ddp-streamer-service 127MiB 127MiB +674B
account-service 114MiB 114MiB +2.8KiB
authorization-service 111MiB 111MiB +50KiB
stream-hub-service 111MiB 111MiB +1.3KiB
presence-service 111MiB 111MiB +1.2KiB

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 16:53", "11/19 17:53 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.14]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.14]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.36]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
Loading

Statistics (last 5 days):

  • 📊 Average: 1.4GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37506
  • Baseline: develop
  • Timestamp: 2025-11-19 17:53:59 UTC
  • Historical data points: 5

Updated: Wed, 19 Nov 2025 17:53:59 GMT

@KevLehman KevLehman force-pushed the feat/on-subject-attr-changed branch from 547f9a5 to f5f152d Compare November 19, 2025 17:29
@tassoevan tassoevan merged commit 26cc66a into feat/abac Nov 19, 2025
89 of 91 checks passed
@tassoevan tassoevan deleted the feat/on-subject-attr-changed branch November 19, 2025 19:08
@coderabbitai coderabbitai bot mentioned this pull request Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants