Skip to content

Check only top-level groups on sign-up form username endpoint

What does this MR do and why?

Check only top-level groups on sign-up form endpoint

WHen a user signs up for GitLab, the sign-up form checks to see if the username they want is already taken. Currently it checks all group names to see if there is a conflict, however, there is only a conflict for top-level groups, not sub-groups.

This changes the endpoint to check only top-level groups, not subgroups. I have verified that new users can sign up with the username of an existing subgroup.

Database Review

This modifies a query to check for the existence of a namespace.

Query before this MR
SELECT "namespaces"."id",
       "namespaces"."name",
       "namespaces"."path",
       "namespaces"."owner_id",
       "namespaces"."created_at",
       "namespaces"."updated_at",
       "namespaces"."type",
       "namespaces"."description",
       "namespaces"."avatar",
       "namespaces"."membership_lock",
       "namespaces"."share_with_group_lock",
       "namespaces"."visibility_level",
       "namespaces"."request_access_enabled",
       "namespaces"."ldap_sync_status",
       "namespaces"."ldap_sync_error",
       "namespaces"."ldap_sync_last_update_at",
       "namespaces"."ldap_sync_last_successful_update_at",
       "namespaces"."ldap_sync_last_sync_at",
       "namespaces"."description_html",
       "namespaces"."lfs_enabled",
       "namespaces"."parent_id",
       "namespaces"."shared_runners_minutes_limit",
       "namespaces"."repository_size_limit",
       "namespaces"."require_two_factor_authentication",
       "namespaces"."two_factor_grace_period",
       "namespaces"."cached_markdown_version",
       "namespaces"."project_creation_level",
       "namespaces"."runners_token",
       "namespaces"."file_template_project_id",
       "namespaces"."saml_discovery_token",
       "namespaces"."runners_token_encrypted",
       "namespaces"."custom_project_templates_group_id",
       "namespaces"."auto_devops_enabled",
       "namespaces"."extra_shared_runners_minutes_limit",
       "namespaces"."last_ci_minutes_notification_at",
       "namespaces"."last_ci_minutes_usage_notification_level",
       "namespaces"."subgroup_creation_level",
       "namespaces"."max_pages_size",
       "namespaces"."max_artifacts_size",
       "namespaces"."mentions_disabled",
       "namespaces"."default_branch_protection",
       "namespaces"."max_personal_access_token_lifetime",
       "namespaces"."push_rule_id",
       "namespaces"."shared_runners_enabled",
       "namespaces"."allow_descendants_override_disabled_shared_runners",
       "namespaces"."traversal_ids",
       "namespaces"."organization_id"
FROM "namespaces"
WHERE "namespaces"."type" != 'Project'
  AND (lower(path) = 'atevans-group-test'
       OR lower(name) = 'atevans-group-test') LIMIT 1
Query after this change
SELECT "namespaces"."id",
       "namespaces"."name",
       "namespaces"."path",
       "namespaces"."owner_id",
       "namespaces"."created_at",
       "namespaces"."updated_at",
       "namespaces"."type",
       "namespaces"."description",
       "namespaces"."avatar",
       "namespaces"."membership_lock",
       "namespaces"."share_with_group_lock",
       "namespaces"."visibility_level",
       "namespaces"."request_access_enabled",
       "namespaces"."ldap_sync_status",
       "namespaces"."ldap_sync_error",
       "namespaces"."ldap_sync_last_update_at",
       "namespaces"."ldap_sync_last_successful_update_at",
       "namespaces"."ldap_sync_last_sync_at",
       "namespaces"."description_html",
       "namespaces"."lfs_enabled",
       "namespaces"."parent_id",
       "namespaces"."shared_runners_minutes_limit",
       "namespaces"."repository_size_limit",
       "namespaces"."require_two_factor_authentication",
       "namespaces"."two_factor_grace_period",
       "namespaces"."cached_markdown_version",
       "namespaces"."project_creation_level",
       "namespaces"."runners_token",
       "namespaces"."file_template_project_id",
       "namespaces"."saml_discovery_token",
       "namespaces"."runners_token_encrypted",
       "namespaces"."custom_project_templates_group_id",
       "namespaces"."auto_devops_enabled",
       "namespaces"."extra_shared_runners_minutes_limit",
       "namespaces"."last_ci_minutes_notification_at",
       "namespaces"."last_ci_minutes_usage_notification_level",
       "namespaces"."subgroup_creation_level",
       "namespaces"."max_pages_size",
       "namespaces"."max_artifacts_size",
       "namespaces"."mentions_disabled",
       "namespaces"."default_branch_protection",
       "namespaces"."max_personal_access_token_lifetime",
       "namespaces"."push_rule_id",
       "namespaces"."shared_runners_enabled",
       "namespaces"."allow_descendants_override_disabled_shared_runners",
       "namespaces"."traversal_ids",
       "namespaces"."organization_id"
FROM "namespaces"
WHERE "namespaces"."type" != 'Project'
  AND "namespaces"."parent_id" IS NULL
  AND (lower(path) = 'atevans-group-test'
       OR lower(name) = 'atevans-group-test') LIMIT 1

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.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After
Screenshot_2024-08-20_at_11.30.23_AM Screenshot_2024-08-20_at_11.29.49_AM

How to set up and validate locally

  1. create a new group username-test-group
  2. create a new subgroup username-test-subgroup
  3. ensure signup is enabled in your gitlab.yml
  4. sign out, or open an incognito tab
  5. go to the sign up form: https://gdk.test:3443/users/sign_up
  6. enter username-test-subgroup in the "Username" box
  7. verify that the form shows "Username is available" as help text

Related to #438828 (closed)

Edited by Andrew Evans

Merge request reports

Loading