From b469a1d73ab14d698b548ac291effe46d38febe4 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Tue, 7 Oct 2025 14:51:46 -0500 Subject: [PATCH 1/2] Scope user sign in to organization Allow routing user sign in requests through the organization scoped routes. --- app/helpers/projects_helper.rb | 2 +- app/helpers/routing/organizations_helper.rb | 4 ++ app/views/devise/sessions/_new_base.html.haml | 2 +- config/routes/organizations.rb | 8 ++++ .../security/policies_controller_spec.rb | 3 +- .../trials/access_denied_spec.rb | 3 +- .../duo_enterprise/access_denied_spec.rb | 3 +- .../trials/duo_pro/access_denied_spec.rb | 3 +- .../features/groups/saml_providers_spec.rb | 2 +- .../security/group/internal_access_spec.rb | 2 +- .../security/group/private_access_spec.rb | 2 +- .../security/project/internal_access_spec.rb | 2 +- .../security/project/private_access_spec.rb | 2 +- .../analytics/dashboards_controller_spec.rb | 3 +- ...egistries_and_upstreams_controller_spec.rb | 3 +- .../maven/registries_controller_spec.rb | 3 +- .../maven/upstreams_controller_spec.rb | 3 +- .../virtual_registries_controller_spec.rb | 2 +- .../duo_agents_platform_controller_spec.rb | 3 +- .../security/policies_controller_spec.rb | 3 +- lib/gitlab/devise_failure.rb | 43 +++++++++++++++++++ .../concerns/routable_actions_spec.rb | 2 +- .../import/bulk_imports_controller_spec.rb | 2 +- .../settings/ci_cd_controller_spec.rb | 2 +- spec/features/atom/issues_spec.rb | 2 +- spec/features/atom/merge_requests_spec.rb | 2 +- .../projects/jobs/user_browses_jobs_spec.rb | 4 +- .../projects/pipelines/pipelines_spec.rb | 4 +- spec/features/projects/show/redirects_spec.rb | 2 +- .../show/user_interacts_with_stars_spec.rb | 2 +- .../show/user_sees_git_instructions_spec.rb | 2 +- .../projects/tags/user_views_tags_spec.rb | 4 +- .../security/group/internal_access_spec.rb | 2 +- .../security/group/private_access_spec.rb | 2 +- .../security/project/internal_access_spec.rb | 2 +- .../security/project/private_access_spec.rb | 2 +- .../security/project/public_access_spec.rb | 2 +- .../project/snippet/internal_access_spec.rb | 2 +- .../project/snippet/private_access_spec.rb | 2 +- spec/features/user_settings/password_spec.rb | 2 +- .../features/users/anonymous_sessions_spec.rb | 3 +- .../users/email_verification_on_login_spec.rb | 3 +- spec/features/users/logout_spec.rb | 2 +- spec/helpers/projects_helper_spec.rb | 6 +-- .../routing/organizations_helper_spec.rb | 7 +++ .../groups/achievements_controller_spec.rb | 2 +- .../groups/crm/contacts_controller_spec.rb | 2 +- .../crm/organizations_controller_spec.rb | 2 +- .../groups/group_members_controller_spec.rb | 2 +- ...infrastructure_registry_controller_spec.rb | 2 +- .../projects/graphs_controller_spec.rb | 2 +- .../harbor/artifacts_controller_spec.rb | 2 +- .../harbor/repositories_controller_spec.rb | 2 +- .../projects/harbor/tags_controller_spec.rb | 2 +- .../projects/incidents_controller_spec.rb | 2 +- .../projects/network_controller_spec.rb | 3 +- .../project_members_controller_spec.rb | 2 +- spec/requests/sessions_spec.rb | 2 +- spec/requests/verifies_with_email_spec.rb | 2 +- spec/routing/routing_spec.rb | 8 ++++ spec/support/matchers/access_matchers.rb | 8 +++- 61 files changed, 149 insertions(+), 62 deletions(-) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index d4172314eb3f71..8e60482fe827c8 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -522,7 +522,7 @@ def star_count_data_attributes(project) { project_id: project.id, - sign_in_path: new_session_path(:user, redirect_to_referer: 'yes'), + sign_in_path: new_user_session_path(redirect_to_referer: 'yes'), star_count: project.star_count, starred: starred.to_s, starrers_path: project_starrers_path(project) diff --git a/app/helpers/routing/organizations_helper.rb b/app/helpers/routing/organizations_helper.rb index 0c3bc14a510f30..a27de4060f5fd7 100644 --- a/app/helpers/routing/organizations_helper.rb +++ b/app/helpers/routing/organizations_helper.rb @@ -27,6 +27,10 @@ def self.install url_helpers.alias_method :unscoped_root_url, :root_url if url_helpers.respond_to?(:root_url) url_helpers.alias_method :unscoped_root_path, :root_path if url_helpers.respond_to?(:root_path) + if url_helpers.respond_to?(:new_user_session_path) + url_helpers.alias_method :unscoped_new_user_session_path, :new_user_session_path + end + # Override URL helpers to be Organization context aware. route_pairs = find_route_pairs override_module = build_override_module(route_pairs) diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index b0044138213b5d..9d31b758bd379a 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,4 +1,4 @@ -- url = admin_mode ? admin_session_path : session_path(:user) +- url = admin_mode ? admin_session_path : new_user_session_path - form_class = admin_mode ? '' : 'js-arkose-labs-form' - button_class = admin_mode ? '' : 'js-sign-in-button' - submit_message = admin_mode ? _('Enter admin mode') : _('Sign in') diff --git a/config/routes/organizations.rb b/config/routes/organizations.rb index 883372d9c75e60..d57f63f3471b8e 100644 --- a/config/routes/organizations.rb +++ b/config/routes/organizations.rb @@ -29,6 +29,14 @@ root to: "dashboard/projects#index" end + + devise_scope :user do + resource :session, only: [], controller: 'sessions', path: "", as: :user_session do + get :new, path: '/users/sign_in', as: "new" + post :create, path: '/users/sign_in' + post :destroy, path: '/users/sign_out', as: "destroy" + end + end end scope path: '-' do diff --git a/ee/spec/controllers/groups/security/policies_controller_spec.rb b/ee/spec/controllers/groups/security/policies_controller_spec.rb index df4d5267f96e5e..a23bcc642bad3b 100644 --- a/ee/spec/controllers/groups/security/policies_controller_spec.rb +++ b/ee/spec/controllers/groups/security/policies_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Groups::Security::PoliciesController, type: :request, feature_category: :security_policy_management do +RSpec.describe Groups::Security::PoliciesController, :with_current_organization, + type: :request, feature_category: :security_policy_management do let_it_be(:owner) { create(:user) } let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } diff --git a/ee/spec/features/gitlab_subscriptions/trials/access_denied_spec.rb b/ee/spec/features/gitlab_subscriptions/trials/access_denied_spec.rb index 3dfeb489e82aed..4eddb2a74ef47f 100644 --- a/ee/spec/features/gitlab_subscriptions/trials/access_denied_spec.rb +++ b/ee/spec/features/gitlab_subscriptions/trials/access_denied_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe 'Ultimate trial access denied flow', :saas_trial, :js, feature_category: :acquisition do +RSpec.describe 'Ultimate trial access denied flow', :with_current_organization, :saas_trial, :js, + feature_category: :acquisition do # rubocop:disable Gitlab/RSpec/AvoidSetup -- reuse of common flow it_behaves_like 'duo access denied flow' do let(:duo_path) { new_trial_path(namespace_id: non_existing_record_id) } diff --git a/ee/spec/features/gitlab_subscriptions/trials/duo_enterprise/access_denied_spec.rb b/ee/spec/features/gitlab_subscriptions/trials/duo_enterprise/access_denied_spec.rb index 55fa89cdf6939d..2e96027c5458d5 100644 --- a/ee/spec/features/gitlab_subscriptions/trials/duo_enterprise/access_denied_spec.rb +++ b/ee/spec/features/gitlab_subscriptions/trials/duo_enterprise/access_denied_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe 'Duo Enterprise trial access denied flow', :saas_trial, :js, feature_category: :acquisition do +RSpec.describe 'Duo Enterprise trial access denied flow', :with_current_organization, :saas_trial, :js, + feature_category: :acquisition do # rubocop:disable Gitlab/RSpec/AvoidSetup -- reuse of common flow it_behaves_like 'duo access denied flow' do let(:duo_path) { new_trials_duo_enterprise_path } diff --git a/ee/spec/features/gitlab_subscriptions/trials/duo_pro/access_denied_spec.rb b/ee/spec/features/gitlab_subscriptions/trials/duo_pro/access_denied_spec.rb index a4d9e1261ce92d..d07eb9af553af7 100644 --- a/ee/spec/features/gitlab_subscriptions/trials/duo_pro/access_denied_spec.rb +++ b/ee/spec/features/gitlab_subscriptions/trials/duo_pro/access_denied_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe 'Duo Pro trial access denied flow', :saas_trial, :js, feature_category: :acquisition do +RSpec.describe 'Duo Pro trial access denied flow', :with_current_organization, :saas_trial, :js, + feature_category: :acquisition do # rubocop:disable Gitlab/RSpec/AvoidSetup -- reuse of common flow it_behaves_like 'duo access denied flow' do let(:duo_path) { new_trials_duo_pro_path } diff --git a/ee/spec/features/groups/saml_providers_spec.rb b/ee/spec/features/groups/saml_providers_spec.rb index 525cebc3a1c2e4..82936a7700186e 100644 --- a/ee/spec/features/groups/saml_providers_spec.rb +++ b/ee/spec/features/groups/saml_providers_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'SAML provider settings', feature_category: :system_access do +RSpec.describe 'SAML provider settings', :with_current_organization, feature_category: :system_access do let_it_be_with_refind(:user) { create(:user) } let_it_be_with_refind(:group) { create(:group, owners: user) } diff --git a/ee/spec/features/security/group/internal_access_spec.rb b/ee/spec/features/security/group/internal_access_spec.rb index 92e8812d27920a..485cd261982373 100644 --- a/ee/spec/features/security/group/internal_access_spec.rb +++ b/ee/spec/features/security/group/internal_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe '[EE] Internal Group access', feature_category: :groups_and_projects do +RSpec.describe '[EE] Internal Group access', :with_current_organization, feature_category: :groups_and_projects do include AccessMatchers let_it_be(:group) { create(:group, :internal) } diff --git a/ee/spec/features/security/group/private_access_spec.rb b/ee/spec/features/security/group/private_access_spec.rb index 5f4da3db659eb8..f67377e949d187 100644 --- a/ee/spec/features/security/group/private_access_spec.rb +++ b/ee/spec/features/security/group/private_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe '[EE] Private Group access', feature_category: :groups_and_projects do +RSpec.describe '[EE] Private Group access', :with_current_organization, feature_category: :groups_and_projects do include AccessMatchers let_it_be(:group) { create(:group, :private) } diff --git a/ee/spec/features/security/project/internal_access_spec.rb b/ee/spec/features/security/project/internal_access_spec.rb index ec6928392e9b77..731a0766ecd605 100644 --- a/ee/spec/features/security/project/internal_access_spec.rb +++ b/ee/spec/features/security/project/internal_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe '[EE] Internal Project Access', feature_category: :groups_and_projects do +RSpec.describe '[EE] Internal Project Access', :with_current_organization, feature_category: :groups_and_projects do include AccessMatchers let_it_be(:project) { create(:project, :internal, :repository) } diff --git a/ee/spec/features/security/project/private_access_spec.rb b/ee/spec/features/security/project/private_access_spec.rb index 87af60d916be31..1ba99889ef4343 100644 --- a/ee/spec/features/security/project/private_access_spec.rb +++ b/ee/spec/features/security/project/private_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe '[EE] Private Project Access', feature_category: :groups_and_projects do +RSpec.describe '[EE] Private Project Access', :with_current_organization, feature_category: :groups_and_projects do include AccessMatchers let_it_be(:project) { create(:project, :private, :repository) } diff --git a/ee/spec/requests/groups/analytics/dashboards_controller_spec.rb b/ee/spec/requests/groups/analytics/dashboards_controller_spec.rb index 9e4391275ed318..34923b83a8464d 100644 --- a/ee/spec/requests/groups/analytics/dashboards_controller_spec.rb +++ b/ee/spec/requests/groups/analytics/dashboards_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Groups::Analytics::DashboardsController, feature_category: :groups_and_projects do +RSpec.describe Groups::Analytics::DashboardsController, :with_current_organization, + feature_category: :groups_and_projects do let_it_be(:group) { create(:group) } let_it_be(:another_group) { create(:group) } let_it_be(:user) do diff --git a/ee/spec/requests/groups/virtual_registries/maven/registries_and_upstreams_controller_spec.rb b/ee/spec/requests/groups/virtual_registries/maven/registries_and_upstreams_controller_spec.rb index 3be121b629d837..2a4ede50e67cc1 100644 --- a/ee/spec/requests/groups/virtual_registries/maven/registries_and_upstreams_controller_spec.rb +++ b/ee/spec/requests/groups/virtual_registries/maven/registries_and_upstreams_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Groups::VirtualRegistries::Maven::RegistriesAndUpstreamsController, feature_category: :virtual_registry do +RSpec.describe Groups::VirtualRegistries::Maven::RegistriesAndUpstreamsController, :with_current_organization, + feature_category: :virtual_registry do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :private) } diff --git a/ee/spec/requests/groups/virtual_registries/maven/registries_controller_spec.rb b/ee/spec/requests/groups/virtual_registries/maven/registries_controller_spec.rb index bb428c40b8e589..b8bee3981c22fe 100644 --- a/ee/spec/requests/groups/virtual_registries/maven/registries_controller_spec.rb +++ b/ee/spec/requests/groups/virtual_registries/maven/registries_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Groups::VirtualRegistries::Maven::RegistriesController, feature_category: :virtual_registry do +RSpec.describe Groups::VirtualRegistries::Maven::RegistriesController, :with_current_organization, + feature_category: :virtual_registry do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :private) } diff --git a/ee/spec/requests/groups/virtual_registries/maven/upstreams_controller_spec.rb b/ee/spec/requests/groups/virtual_registries/maven/upstreams_controller_spec.rb index d603143d809ed8..eb10bf281ba387 100644 --- a/ee/spec/requests/groups/virtual_registries/maven/upstreams_controller_spec.rb +++ b/ee/spec/requests/groups/virtual_registries/maven/upstreams_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Groups::VirtualRegistries::Maven::UpstreamsController, feature_category: :virtual_registry do +RSpec.describe Groups::VirtualRegistries::Maven::UpstreamsController, :with_current_organization, + feature_category: :virtual_registry do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :private) } let_it_be(:maven_upstream) { create(:virtual_registries_packages_maven_upstream, group:) } diff --git a/ee/spec/requests/groups/virtual_registries_controller_spec.rb b/ee/spec/requests/groups/virtual_registries_controller_spec.rb index 5eb932e81f8557..1aa31af1582ffc 100644 --- a/ee/spec/requests/groups/virtual_registries_controller_spec.rb +++ b/ee/spec/requests/groups/virtual_registries_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Groups::VirtualRegistriesController, feature_category: :virtual_registry do +RSpec.describe Groups::VirtualRegistriesController, :with_current_organization, feature_category: :virtual_registry do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :private) } diff --git a/ee/spec/requests/projects/duo_agents_platform_controller_spec.rb b/ee/spec/requests/projects/duo_agents_platform_controller_spec.rb index f3083960b31132..6b16f90eec3383 100644 --- a/ee/spec/requests/projects/duo_agents_platform_controller_spec.rb +++ b/ee/spec/requests/projects/duo_agents_platform_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe 'Projects::DuoAgentsPlatform', type: :request, feature_category: :duo_agent_platform do +RSpec.describe 'Projects::DuoAgentsPlatform', :with_current_organization, type: :request, + feature_category: :duo_agent_platform do let(:project) { create(:project) } let(:user) { create(:user) } diff --git a/ee/spec/requests/projects/security/policies_controller_spec.rb b/ee/spec/requests/projects/security/policies_controller_spec.rb index 6847c746bddd4b..f8ca249c4225cd 100644 --- a/ee/spec/requests/projects/security/policies_controller_spec.rb +++ b/ee/spec/requests/projects/security/policies_controller_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Projects::Security::PoliciesController, type: :request, feature_category: :security_policy_management do +RSpec.describe Projects::Security::PoliciesController, :with_current_organization, + type: :request, feature_category: :security_policy_management do let_it_be(:owner) { create(:user) } let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :repository, namespace: owner.namespace) } diff --git a/lib/gitlab/devise_failure.rb b/lib/gitlab/devise_failure.rb index 2c48ad3b46bc76..381900aa9cab2f 100644 --- a/lib/gitlab/devise_failure.rb +++ b/lib/gitlab/devise_failure.rb @@ -15,6 +15,49 @@ def respond super end end + + # Override to ensure organization context is preserved in redirects + def scope_url + opts = {} + + # Initialize script_name with nil to prevent infinite loops in + # authenticated mounted engines + opts[:script_name] = nil + + # Use the same organization resolution as the rest of the application + current_organization = ::Routing::OrganizationsHelper::MappedHelpers.current_organization + route = if current_organization && current_organization.scoped_paths? + # Use organization-scoped route + opts[:organization_path] = current_organization.path + route_for_organization(scope) + else + # Use global route + route(scope) + end + + opts[:format] = request_format unless skip_format? + + router_name = Devise.mappings[scope].router_name || Devise.available_router_name + context = send(router_name) # rubocop:disable GitlabSecurity/PublicSend -- Safe usage copied from Devise + + opts[:script_name] = relative_url_root if relative_url_root? + + if context.respond_to?(route) + context.send(route, opts) # rubocop:disable GitlabSecurity/PublicSend -- Safe usage copied from Devise + elsif respond_to?(:root_url) + root_url(opts) + else + "/" + end + end + + private + + def route_for_organization(scope) + # Organization-scoped routes are prefixed with "organization_" + # e.g., new_user_session -> new_organization_user_session + :"new_organization_#{scope}_session_url" + end end end diff --git a/spec/controllers/concerns/routable_actions_spec.rb b/spec/controllers/concerns/routable_actions_spec.rb index 7bd55100f64372..a32b4a50510056 100644 --- a/spec/controllers/concerns/routable_actions_spec.rb +++ b/spec/controllers/concerns/routable_actions_spec.rb @@ -145,7 +145,7 @@ def get_routable(routable, id: routable.full_path) get_routable(routable) expect(response).to have_gitlab_http_status(:found) - expect(response.location).to end_with('/users/sign_in') + expect(response.location).to end_with(new_user_session_path) end end end diff --git a/spec/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb index 77114b9e2da198..220b2e746a19ee 100644 --- a/spec/controllers/import/bulk_imports_controller_spec.rb +++ b/spec/controllers/import/bulk_imports_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::BulkImportsController, :with_organization_url_helpers, feature_category: :importers do +RSpec.describe Import::BulkImportsController, :with_current_organization, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:current_organization) { user.organization } diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb index be15427d52d94c..3ec56b8bdbe830 100644 --- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb @@ -585,7 +585,7 @@ def show request expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to('/users/sign_in') + expect(response).to redirect_to(new_user_session_path) end end end diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index bd5903efe1069b..b77fc475f74d9a 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Issues Feed', feature_category: :devops_reports do +RSpec.describe 'Issues Feed', :with_current_organization, feature_category: :devops_reports do describe 'GET /issues' do let_it_be_with_reload(:user) do user = create(:user, email: 'private1@example.com') diff --git a/spec/features/atom/merge_requests_spec.rb b/spec/features/atom/merge_requests_spec.rb index 0238380da90afc..0a14a18badd859 100644 --- a/spec/features/atom/merge_requests_spec.rb +++ b/spec/features/atom/merge_requests_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Merge Requests Feed', feature_category: :devops_reports do +RSpec.describe 'Merge Requests Feed', :with_current_organization, feature_category: :devops_reports do describe 'GET /merge_requests' do let_it_be_with_reload(:user) { create(:user, email: 'private1@example.com') } let_it_be(:assignee) { create(:user, email: 'private2@example.com') } diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb index cd7af6b8e71f36..92fbe5f4563fd5 100644 --- a/spec/features/projects/jobs/user_browses_jobs_spec.rb +++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb @@ -8,7 +8,7 @@ def visit_jobs_page wait_for_requests end -RSpec.describe 'User browses jobs', feature_category: :continuous_integration do +RSpec.describe 'User browses jobs', :with_current_organization, feature_category: :continuous_integration do describe 'Jobs', :js do let(:project) { create(:project, :repository) } let(:user) { create(:user) } @@ -251,7 +251,7 @@ def visit_jobs_page wait_for_requests expect(page).to have_content 'Sign in or sign up before continuing' - expect(page).to have_current_path("/users/sign_in") + expect(page).to have_current_path(new_user_session_path) end end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 6c971f04fd1faf..9f232de52cbd2a 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do +RSpec.describe 'Pipelines', :js, :with_current_organization, feature_category: :continuous_integration do include ListboxHelpers include ProjectForksHelper include Spec::Support::Helpers::ModalHelpers @@ -981,7 +981,7 @@ def expect_not_to_show_prompt(project) it 'redirects the user to sign_in and displays the flash alert' do expect(page).to have_content 'Sign in or sign up before continuing' - expect(page).to have_current_path("/users/sign_in") + expect(page).to have_current_path(new_user_session_path) end end end diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb index 660798077868b9..f4f7f9a01b4e08 100644 --- a/spec/features/projects/show/redirects_spec.rb +++ b/spec/features/projects/show/redirects_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Show > Redirects', feature_category: :groups_and_projects do +RSpec.describe 'Projects > Show > Redirects', :with_current_organization, feature_category: :groups_and_projects do let(:user) { create :user } let(:public_project) { create :project, :public } let(:private_project) { create :project, :private } diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb index 58c389fc8d7409..d43bdeb1edb21f 100644 --- a/spec/features/projects/show/user_interacts_with_stars_spec.rb +++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb @@ -6,7 +6,7 @@ let(:project) { create(:project, :public, :repository) } context 'when user is signed in', :js do - let(:user) { create(:user, organization: current_organization) } + let(:user) { create(:user) } before do sign_in(user) diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb index 52aa32f58f8c8c..ce966393168d8e 100644 --- a/spec/features/projects/show/user_sees_git_instructions_spec.rb +++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Show > User sees Git instructions', feature_category: :groups_and_projects do +RSpec.describe 'Projects > Show > User sees Git instructions', :with_current_organization, feature_category: :groups_and_projects do let_it_be(:user) { create(:user) } before do diff --git a/spec/features/projects/tags/user_views_tags_spec.rb b/spec/features/projects/tags/user_views_tags_spec.rb index 28a9ced69e69ec..c118d86277712b 100644 --- a/spec/features/projects/tags/user_views_tags_spec.rb +++ b/spec/features/projects/tags/user_views_tags_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -RSpec.describe 'User views tags', :feature, feature_category: :source_code_management do +RSpec.describe 'User views tags', :feature, :with_current_organization, feature_category: :source_code_management do include_examples 'user views tag' do let(:tag_page) { project_tags_path(project) } end @@ -19,7 +19,7 @@ it do visit project_tags_path(project, format: :atom) - expect(page).to have_current_path("/users/sign_in") + expect(page).to have_current_path(new_user_session_path) end end diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb index 49f81600ac225b..b77aa6eaa94ce5 100644 --- a/spec/features/security/group/internal_access_spec.rb +++ b/spec/features/security/group/internal_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Internal Group access', feature_category: :system_access do +RSpec.describe 'Internal Group access', :with_current_organization, feature_category: :system_access do include AccessMatchers let(:group) { create(:group, :internal) } diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb index 5206667427e040..29d37aefc6793d 100644 --- a/spec/features/security/group/private_access_spec.rb +++ b/spec/features/security/group/private_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Private Group access', feature_category: :system_access do +RSpec.describe 'Private Group access', :with_current_organization, feature_category: :system_access do include AccessMatchers let(:group) { create(:group, :private) } diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 460080fa1a6e11..06b62d0628aeca 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe "Internal Project Access", feature_category: :system_access do +RSpec.describe "Internal Project Access", :with_current_organization, feature_category: :system_access do include AccessMatchers let_it_be(:project, reload: true) { create(:project, :internal, :repository, :with_namespace_settings) } diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb index 50f03008ab16fa..33e872fdd2dbaf 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe "Private Project Access", feature_category: :system_access do +RSpec.describe "Private Project Access", :with_current_organization, feature_category: :system_access do include AccessMatchers let_it_be(:project, reload: true) do diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb index 4b4c23c0bbb170..3e137a9c402a2a 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe "Public Project Access", feature_category: :system_access do +RSpec.describe "Public Project Access", :with_current_organization, feature_category: :system_access do include AccessMatchers let_it_be(:project, reload: true) do diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb index 6ed0ec2021076e..2d9dd1d005a55d 100644 --- a/spec/features/security/project/snippet/internal_access_spec.rb +++ b/spec/features/security/project/snippet/internal_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe "Internal Project Snippets Access", feature_category: :system_access do +RSpec.describe "Internal Project Snippets Access", :with_current_organization, feature_category: :system_access do include AccessMatchers let_it_be(:project) { create(:project, :internal) } diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb index ef61f79a1b559d..61fb9b849b39e6 100644 --- a/spec/features/security/project/snippet/private_access_spec.rb +++ b/spec/features/security/project/snippet/private_access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe "Private Project Snippets Access", feature_category: :system_access do +RSpec.describe "Private Project Snippets Access", :with_current_organization, feature_category: :system_access do include AccessMatchers let_it_be(:project) { create(:project, :private) } diff --git a/spec/features/user_settings/password_spec.rb b/spec/features/user_settings/password_spec.rb index d8f9f431457807..e127d1efacd843 100644 --- a/spec/features/user_settings/password_spec.rb +++ b/spec/features/user_settings/password_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User Settings > Password', feature_category: :user_profile do +RSpec.describe 'User Settings > Password', :with_current_organization, feature_category: :user_profile do let(:user) { create(:user) } def fill_passwords(password, confirmation) diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb index 81b18b7ca020fa..0c409703c37149 100644 --- a/spec/features/users/anonymous_sessions_spec.rb +++ b/spec/features/users/anonymous_sessions_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state, feature_category: :system_access do +RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state, :with_current_organization, + feature_category: :system_access do include SessionHelpers before do diff --git a/spec/features/users/email_verification_on_login_spec.rb b/spec/features/users/email_verification_on_login_spec.rb index a17ac46a7d83ed..1f575a983dc317 100644 --- a/spec/features/users/email_verification_on_login_spec.rb +++ b/spec/features/users/email_verification_on_login_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, :js, :with_organization_url_helpers, feature_category: :instance_resiliency do +RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, :js, :with_current_organization, + feature_category: :instance_resiliency do include EmailHelpers let(:user) { create(:user) } diff --git a/spec/features/users/logout_spec.rb b/spec/features/users/logout_spec.rb index c9839247e7dce6..9b0e0569a45ba0 100644 --- a/spec/features/users/logout_spec.rb +++ b/spec/features/users/logout_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Logout/Sign out', :js, feature_category: :system_access do +RSpec.describe 'Logout/Sign out', :js, :with_current_organization, feature_category: :system_access do let(:user) { create(:user) } before do diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index bc7edc58a05fa0..b4ba964874344a 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ProjectsHelper, feature_category: :source_code_management do +RSpec.describe ProjectsHelper, :with_current_organization, feature_category: :source_code_management do include ProjectForksHelper include AfterNextHelpers @@ -1139,7 +1139,7 @@ def license_name describe '#star_count_data_attributes' do before do allow(user).to receive(:starred?).with(project).and_return(starred) - allow(helper).to receive(:new_session_path).and_return(sign_in_path) + allow(helper).to receive(:new_user_session_path).and_return(sign_in_path) allow(project).to receive(:star_count).and_return(5) end @@ -1950,7 +1950,7 @@ def license_name { 'initial_sort' => 'created_desc', 'programming_languages' => ProgrammingLanguage.most_popular, - 'base_path' => '/' + 'base_path' => current_organization.full_path } ) end diff --git a/spec/helpers/routing/organizations_helper_spec.rb b/spec/helpers/routing/organizations_helper_spec.rb index 27e57531bfbd73..234d6d0bf42728 100644 --- a/spec/helpers/routing/organizations_helper_spec.rb +++ b/spec/helpers/routing/organizations_helper_spec.rb @@ -210,4 +210,11 @@ it_behaves_like 'organization aware route helper' end + + describe '#new_user_session_path' do + let(:helper) { :new_user_session } + let(:organization_helper) { :new_organization_user_session } + + it_behaves_like 'organization aware route helper' + end end diff --git a/spec/requests/groups/achievements_controller_spec.rb b/spec/requests/groups/achievements_controller_spec.rb index b3f2bcdf07ad4e..e33f369c0b9723 100644 --- a/spec/requests/groups/achievements_controller_spec.rb +++ b/spec/requests/groups/achievements_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Groups::AchievementsController, feature_category: :user_profile do +RSpec.describe Groups::AchievementsController, :with_current_organization, feature_category: :user_profile do let_it_be(:user) { create(:user) } shared_examples 'response with 404 status' do diff --git a/spec/requests/groups/crm/contacts_controller_spec.rb b/spec/requests/groups/crm/contacts_controller_spec.rb index 48e9bfe6ef0fd9..a947f895fe7ca6 100644 --- a/spec/requests/groups/crm/contacts_controller_spec.rb +++ b/spec/requests/groups/crm/contacts_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Groups::Crm::ContactsController, feature_category: :team_planning do +RSpec.describe Groups::Crm::ContactsController, :with_current_organization, feature_category: :team_planning do let_it_be(:user) { create(:user) } shared_examples 'response with 404 status' do diff --git a/spec/requests/groups/crm/organizations_controller_spec.rb b/spec/requests/groups/crm/organizations_controller_spec.rb index c180365ae55f61..e1b3208bd3e8d7 100644 --- a/spec/requests/groups/crm/organizations_controller_spec.rb +++ b/spec/requests/groups/crm/organizations_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Groups::Crm::OrganizationsController, feature_category: :team_planning do +RSpec.describe Groups::Crm::OrganizationsController, :with_current_organization, feature_category: :team_planning do let_it_be(:user) { create(:user) } shared_examples 'response with 404 status' do diff --git a/spec/requests/groups/group_members_controller_spec.rb b/spec/requests/groups/group_members_controller_spec.rb index 5b7d81680ae65e..fe1383991769fe 100644 --- a/spec/requests/groups/group_members_controller_spec.rb +++ b/spec/requests/groups/group_members_controller_spec.rb @@ -4,7 +4,7 @@ require_relative '../concerns/membership_actions_shared_examples' -RSpec.describe Groups::GroupMembersController, feature_category: :groups_and_projects do +RSpec.describe Groups::GroupMembersController, :with_current_organization, feature_category: :groups_and_projects do let_it_be(:user) { create(:user) } let_it_be(:membershipable) { create(:group, :public, parent: create(:group, :public)) } diff --git a/spec/requests/groups/infrastructure_registry_controller_spec.rb b/spec/requests/groups/infrastructure_registry_controller_spec.rb index c4005fe6763201..369a06d9971ba8 100644 --- a/spec/requests/groups/infrastructure_registry_controller_spec.rb +++ b/spec/requests/groups/infrastructure_registry_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Groups::InfrastructureRegistryController, feature_category: :package_registry do +RSpec.describe Groups::InfrastructureRegistryController, :with_current_organization, feature_category: :package_registry do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :private) } diff --git a/spec/requests/projects/graphs_controller_spec.rb b/spec/requests/projects/graphs_controller_spec.rb index 66793e3e1ae7c7..91a1d8a6e2726b 100644 --- a/spec/requests/projects/graphs_controller_spec.rb +++ b/spec/requests/projects/graphs_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::GraphsController, feature_category: :source_code_management do +RSpec.describe Projects::GraphsController, :with_current_organization, feature_category: :source_code_management do let_it_be(:project) { create(:project, :repository, :private) } let(:ref) { 'master' } diff --git a/spec/requests/projects/harbor/artifacts_controller_spec.rb b/spec/requests/projects/harbor/artifacts_controller_spec.rb index 0f68ac0439c96c..3ba13231a4647b 100644 --- a/spec/requests/projects/harbor/artifacts_controller_spec.rb +++ b/spec/requests/projects/harbor/artifacts_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::Harbor::ArtifactsController, feature_category: :container_registry do +RSpec.describe Projects::Harbor::ArtifactsController, :with_current_organization, feature_category: :container_registry do it_behaves_like 'a harbor artifacts controller', anonymous_status_code: '302' do let_it_be(:container) { create(:project) } let_it_be(:harbor_integration) { create(:harbor_integration, project: container) } diff --git a/spec/requests/projects/harbor/repositories_controller_spec.rb b/spec/requests/projects/harbor/repositories_controller_spec.rb index 7430ac5a64f27a..264b7e27300ebd 100644 --- a/spec/requests/projects/harbor/repositories_controller_spec.rb +++ b/spec/requests/projects/harbor/repositories_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::Harbor::RepositoriesController, feature_category: :source_code_management do +RSpec.describe Projects::Harbor::RepositoriesController, :with_current_organization, feature_category: :source_code_management do it_behaves_like 'a harbor repositories controller', anonymous_status_code: '302' do let_it_be(:container, reload: true) { create(:project) } let_it_be(:harbor_integration) { create(:harbor_integration, project: container) } diff --git a/spec/requests/projects/harbor/tags_controller_spec.rb b/spec/requests/projects/harbor/tags_controller_spec.rb index f1ac2f01c57df4..27b4203af4b36b 100644 --- a/spec/requests/projects/harbor/tags_controller_spec.rb +++ b/spec/requests/projects/harbor/tags_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::Harbor::TagsController, feature_category: :source_code_management do +RSpec.describe Projects::Harbor::TagsController, :with_current_organization, feature_category: :source_code_management do it_behaves_like 'a harbor tags controller', anonymous_status_code: '302' do let_it_be(:container) { create(:project) } let_it_be(:harbor_integration) { create(:harbor_integration, project: container) } diff --git a/spec/requests/projects/incidents_controller_spec.rb b/spec/requests/projects/incidents_controller_spec.rb index 76cedc2c330a4e..cd33cdaf769f2a 100644 --- a/spec/requests/projects/incidents_controller_spec.rb +++ b/spec/requests/projects/incidents_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::IncidentsController, feature_category: :incident_management do +RSpec.describe Projects::IncidentsController, :with_current_organization, feature_category: :incident_management do let_it_be_with_refind(:project) { create(:project) } let_it_be(:developer) { create(:user, developer_of: project) } let_it_be(:guest) { create(:user, guest_of: project) } diff --git a/spec/requests/projects/network_controller_spec.rb b/spec/requests/projects/network_controller_spec.rb index 01fb1b94985ede..253677d6e6c9b2 100644 --- a/spec/requests/projects/network_controller_spec.rb +++ b/spec/requests/projects/network_controller_spec.rb @@ -2,8 +2,9 @@ require 'spec_helper' -RSpec.describe Projects::NetworkController, feature_category: :source_code_management do +RSpec.describe Projects::NetworkController, :with_current_organization, feature_category: :source_code_management do let_it_be(:project) { create(:project, :repository, :private) } + let(:ref) { 'master' } describe 'GET #show' do diff --git a/spec/requests/projects/project_members_controller_spec.rb b/spec/requests/projects/project_members_controller_spec.rb index 57bd1ceb0e6769..4e3c022f99e72b 100644 --- a/spec/requests/projects/project_members_controller_spec.rb +++ b/spec/requests/projects/project_members_controller_spec.rb @@ -4,7 +4,7 @@ require_relative '../concerns/membership_actions_shared_examples' -RSpec.describe Projects::ProjectMembersController, feature_category: :groups_and_projects do +RSpec.describe Projects::ProjectMembersController, :with_current_organization, feature_category: :groups_and_projects do let_it_be(:user) { create(:user) } let_it_be(:membershipable) { create(:project, :public, namespace: create(:group, :public), creator: user) } diff --git a/spec/requests/sessions_spec.rb b/spec/requests/sessions_spec.rb index 2bb44ec457dc76..b22373cda26c3e 100644 --- a/spec/requests/sessions_spec.rb +++ b/spec/requests/sessions_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Sessions', feature_category: :system_access do +RSpec.describe 'Sessions', :with_current_organization, feature_category: :system_access do include SessionHelpers let_it_be(:user) { create(:user) } diff --git a/spec/requests/verifies_with_email_spec.rb b/spec/requests/verifies_with_email_spec.rb index f44b1123154bad..708831bb7fb69e 100644 --- a/spec/requests/verifies_with_email_spec.rb +++ b/spec/requests/verifies_with_email_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe VerifiesWithEmail, :clean_gitlab_redis_sessions, :clean_gitlab_redis_rate_limiting, - feature_category: :instance_resiliency do + :with_current_organization, feature_category: :instance_resiliency do include SessionHelpers include EmailHelpers diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index 3f6d5925d67a0f..3da9843265dd7c 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -259,16 +259,24 @@ end RSpec.describe "Authentication", "routing" do + let_it_be(:current_organization) { create(:common_organization) } + it "GET /users/sign_in" do expect(get("/users/sign_in")).to route_to('sessions#new') + expect(get("/o/#{current_organization.path}/users/sign_in")) + .to route_to('sessions#new', organization_path: current_organization.path) end it "POST /users/sign_in" do expect(post("/users/sign_in")).to route_to('sessions#create') + expect(post("/o/#{current_organization.path}/users/sign_in")) + .to route_to('sessions#create', organization_path: current_organization.path) end it "POST /users/sign_out" do expect(post("/users/sign_out")).to route_to('sessions#destroy') + expect(post("/o/#{current_organization.path}/users/sign_out")) + .to route_to('sessions#destroy', organization_path: current_organization.path) end it "POST /users/password" do diff --git a/spec/support/matchers/access_matchers.rb b/spec/support/matchers/access_matchers.rb index 1b460fbdbf7ff5..37662c3f35f302 100644 --- a/spec/support/matchers/access_matchers.rb +++ b/spec/support/matchers/access_matchers.rb @@ -52,7 +52,9 @@ def description_for(user, type) emulate_user(user, @membership) visit(url) - [200, 204].include?(status_code) && !current_path.in?([new_user_session_path, new_admin_session_path]) + [200, 204].include?(status_code) && !current_path.in?( + [new_user_session_path, new_admin_session_path, unscoped_new_user_session_path] + ) end chain :of do |membership| @@ -67,7 +69,9 @@ def description_for(user, type) emulate_user(user, @membership) visit(url) - [401, 404, 403].include?(status_code) || current_path.in?([new_user_session_path, new_admin_session_path]) + [401, 404, 403].include?(status_code) || current_path.in?( + [new_user_session_path, new_admin_session_path, unscoped_new_user_session_path] + ) end chain :of do |membership| -- GitLab From e1566280b1807e106ed7f0c9977088f0456c7477 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Wed, 22 Oct 2025 13:08:53 -0500 Subject: [PATCH 2/2] Fix unscoped unlock spec --- spec/features/users/email_verification_on_login_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/features/users/email_verification_on_login_spec.rb b/spec/features/users/email_verification_on_login_spec.rb index 1f575a983dc317..15b07b0a9a46c7 100644 --- a/spec/features/users/email_verification_on_login_spec.rb +++ b/spec/features/users/email_verification_on_login_spec.rb @@ -7,7 +7,6 @@ include EmailHelpers let(:user) { create(:user) } - let(:current_organization) { user.organization } let(:another_user) { create(:user) } let(:new_email) { build_stubbed(:user).email } let(:email_verification_required) { true } @@ -371,7 +370,7 @@ # unlocking works as expected visit unlock_url expect_user_to_be_unlocked - expect(page).to have_current_path(new_user_session_path) + expect(page).to have_current_path(unscoped_new_user_session_path) expect(page).to have_content('Your account has been unlocked successfully') gitlab_sign_in(user) -- GitLab