diff --git a/app/controllers/groups/redirect_controller.rb b/app/controllers/groups/redirect_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..d17ee9844c9cce990f13da997c69d937e2d9a779 --- /dev/null +++ b/app/controllers/groups/redirect_controller.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Groups + class RedirectController < ::ApplicationController + skip_before_action :authenticate_user! + + feature_category :groups_and_projects + + def redirect_from_id + group = Group.find(group_params[:id]) + + if can?(current_user, :read_group, group) + redirect_to group + else + render_404 + end + end + + private + + def group_params + params.permit(:id) + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 3fede72eebb3b5a0e53ef5648b89e810f4b51c96..27577cc7e378dff846d30a1efa05a49c4edbf1c7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -270,11 +270,14 @@ resources :groups, only: [:index, :new, :create] + get '/-/g/:id' => 'groups/redirect#redirect_from_id' + draw :group resources :projects, only: [:index, :new, :create] get '/projects/:id' => 'projects/redirect#redirect_from_id' + get '/-/p/:id' => 'projects/redirect#redirect_from_id' draw :git_http draw :api diff --git a/spec/requests/groups/redirect_controller_spec.rb b/spec/requests/groups/redirect_controller_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..bd8ea696602a64849ea9e5f62d791407b1ffe59d --- /dev/null +++ b/spec/requests/groups/redirect_controller_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe "Groups::RedirectController requests", feature_category: :groups_and_projects do + using RSpec::Parameterized::TableSyntax + + let_it_be(:private_group) { create(:group, :private) } + let_it_be(:private_group2) { create(:group, :private) } + let_it_be(:public_group) { create(:group, :public) } + let_it_be(:user) { create(:user, developer_of: private_group) } + + describe 'GET redirect_from_id' do + where(:authenticated, :group, :is_found) do + true | ref(:private_group) | true + false | ref(:private_group) | false + true | ref(:private_group2) | false + true | ref(:public_group) | true + false | ref(:public_group) | true + true | build(:group, id: 0) | false + end + + with_them do + before do + sign_in(user) if authenticated + + get "/-/g/#{group.id}" + end + + if params[:is_found] + it 'redirects to the group page' do + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(group_path(group)) + end + else + it 'gives 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end +end diff --git a/spec/requests/projects/redirect_controller_spec.rb b/spec/requests/projects/redirect_controller_spec.rb index 46b233b353c9f5970753b54ea3e00aa85a0ce095..bc11f36cec5599e571df0f6fa4741eb192dd990c 100644 --- a/spec/requests/projects/redirect_controller_spec.rb +++ b/spec/requests/projects/redirect_controller_spec.rb @@ -6,13 +6,15 @@ using RSpec::Parameterized::TableSyntax let_it_be(:private_project) { create(:project, :private) } + let_it_be(:private_project2) { create(:project, :private) } let_it_be(:public_project) { create(:project, :public) } let_it_be(:user) { create(:user, developer_of: private_project) } - describe 'GET redirect_from_id' do + shared_examples 'project redirect' do |endpoint_format| where(:authenticated, :project, :is_found) do true | ref(:private_project) | true false | ref(:private_project) | false + true | ref(:private_project2) | false true | ref(:public_project) | true false | ref(:public_project) | true true | build(:project, id: 0) | false @@ -22,7 +24,7 @@ before do sign_in(user) if authenticated - get "/projects/#{project.id}" + get format(endpoint_format, id: project.id) end if params[:is_found] @@ -38,6 +40,11 @@ end end + describe 'GET redirect_from_id' do + it_behaves_like 'project redirect', '/projects/%{id}' + it_behaves_like 'project redirect', '/-/p/%{id}' + end + # This is a regression test for https://gitlab.com/gitlab-org/gitlab/-/issues/351058 context 'with sourcegraph enabled' do let_it_be(:sourcegraph_url) { 'https://sourcegraph.test' } diff --git a/spec/routing/group_routing_spec.rb b/spec/routing/group_routing_spec.rb index 5282c30787e7ee278cfd626234ed06e7d03dc79a..0ca6e2fe0912e6b308cbc7a426f894491535754e 100644 --- a/spec/routing/group_routing_spec.rb +++ b/spec/routing/group_routing_spec.rb @@ -153,4 +153,10 @@ end end end + + describe Groups::RedirectController, 'routing' do + it 'to #redirect_from_id' do + expect(get('/-/g/1')).to route_to('groups/redirect#redirect_from_id', id: '1') + end + end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index e00366af15b428fe0f9e77df264aaed799ee6c52..073edc367aa331358b39e5568deaff146e4bd4aa 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -75,6 +75,7 @@ describe Projects::RedirectController, 'routing' do it 'to #redirect_from_id' do expect(get('/projects/1')).to route_to('projects/redirect#redirect_from_id', id: '1') + expect(get('/-/p/1')).to route_to('projects/redirect#redirect_from_id', id: '1') end end