User Contribution Mapping - Placeholder users can be added as regular members via the API
What does this MR do and why?
This MR prevents placeholder users from being added as members via the API. This isn't something that can be done via the UI, so the API should have parity to the UI. Now that we no longer want placeholder users to be added as actual members on the members
table (
see User mapping - Handle memberships (#477845 - closed)), it seemed simplest to add a model validation on Members to prevent that association entirely. This MR also prevents member invites from being sent to emails that match the pattern we use to create emails for placeholder users so placeholder users can't be invited via email either.
Query Plans
There are no placeholder user members on .com, so I ran an EXPLAIN
for the query in this MR's migration locally with the data I had:
Delete on members (cost=5.42..5.49 rows=0 width=0)
-> Nested Loop (cost=5.42..5.49 rows=1 width=18)
-> HashAggregate (cost=5.28..5.29 rows=1 width=20)
Group Key: members_1.id
-> Nested Loop (cost=0.29..5.27 rows=1 width=20)
-> Index Scan using index_users_on_user_type_and_id on users (cost=0.14..2.16 rows=1 width=14)
Index Cond: (user_type = 15)
-> Index Scan using idx_members_on_user_and_source_and_source_type_and_member_role on members members_1 (cost=0.14..3.09 rows=2 width=22)
Index Cond: (user_id = users.id)
-> Index Scan using members_pkey on members (cost=0.14..0.21 rows=1 width=14)
Index Cond: (id = members_1.id)
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
How to set up and validate locally
Start your local GDK instance, and attempt to add a placeholder user as a member via the API with a placeholder uer's ID:
curl 'http://gdk.test:3000/api/v4/groups/24/invitations' -X POST -H "PRIVATE-TOKEN: glpat-..." -d 'user_id=132&access_level=50'
=> {"message":{"nanceeveum_placeholder_user_1":"User must not be a placeholder user"},"status":"error"}
Then again with a placeholder email:
curl 'http://gdk.test:3000/api/v4/groups/24/invitations' -X POST -H "PRIVATE-TOKEN: glpat-..." -d 'email=gitlab_migration_471d1c24_1@gdk.test&access_level=50'
{"message":{"gitlab_migration_471d1c24_1@gdk.test":"The member's email address must not be a placeholder email"},"status":"error"}%
If you don't have placeholder users, enable the improved user mapping feature flags and import a group with contributions from users. Then attempt to add one of the new placeholder users as a member to another group via the API (above). The feature flags needed are:
Feature.enable(:importer_user_mapping)
Feature.enable(:bulk_import_importer_user_mapping)
Related to #482445 (closed)