Restrict invites by user ID to seat assignment holders

What does this MR do and why?

Under the seat assignment model, inviting a user by ID who holds no seat assignment in the root namespace is now rejected.

This is the backend check. The base branch !249867 (merged) already hides non-seat-holders from the invite modal search, so this covers the paths that bypass the UI.

Email invites are out of scope: those resolving to an existing user are left to a follow-up MR, those resolving to no user are tracked in #606030. Both are TODOs in the code.

References

How to set up and validate locally

  1. Enable the seat_assignment_model feature flag for a group and set seat_assignment_model_enabled: true on its namespace settings.
  2. Apply the following patch to disable the frontend check of the base branch and invite a user with no seat assignment in that namespace. The invite should be rejected:

Patch

diff --git a/ee/app/finders/ee/members/invite_users_finder.rb b/ee/app/finders/ee/members/invite_users_finder.rb
index ba54bbc50f12..9549f0430cb3 100644
--- a/ee/app/finders/ee/members/invite_users_finder.rb
+++ b/ee/app/finders/ee/members/invite_users_finder.rb
@@ -17,7 +17,7 @@ def root_group
 
       override :scope_for_resource
       def scope_for_resource(users)
-        if ::GitlabSubscriptions::SeatAssignmentModel.enabled?(root_group)
+        if false
           users = seat_assignment_scoped_users(users)
         elsif root_group&.enforced_sso?
           users = sso_scoped_users(users)

Result error message

image.png

Edited by Lukas Wanko

Merge request reports

Loading
Loading