diff options
author | Robert Speicher <robert@gitlab.com> | 2015-10-22 16:03:04 +0300 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2015-10-22 16:05:54 +0300 |
commit | 8fe4352eba29a2642e7bb39f95f284700593e24e (patch) | |
tree | 8d5f849e68f61d1b1a76ec68eca9ffef91a33ec0 | |
parent | 613f368ce576daf10d79d3c39ddf600cc0d9f6c7 (diff) |
Merge branch 'project-path-case-sensitivity' into 'master'
Prefer project with exact path to differently cased one when both exist.
Fixes #3113.
See merge request !1649
-rw-r--r-- | app/controllers/application_controller.rb | 1 | ||||
-rw-r--r-- | app/models/project.rb | 9 | ||||
-rw-r--r-- | lib/gitlab/database.rb | 2 | ||||
-rw-r--r-- | spec/controllers/projects_controller_spec.rb | 35 |
4 files changed, 35 insertions, 12 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 865deb7d46a..1b0609e279e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -124,7 +124,6 @@ class ApplicationController < ActionController::Base project_path = "#{namespace}/#{id}" @project = Project.find_with_namespace(project_path) - if @project and can?(current_user, :read_project, @project) if @project.path_with_namespace != project_path redirect_to request.original_url.gsub(project_path, @project.path_with_namespace) and return diff --git a/app/models/project.rb b/app/models/project.rb index 88cd88dcb5a..f9bed7cf89f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -243,11 +243,12 @@ class Project < ActiveRecord::Base # Use of unscoped ensures we're not secretly adding any ORDER BYs, which # have a negative impact on performance (and aren't needed for this # query). - unscoped. + projects = unscoped. joins(:namespace). - iwhere('namespaces.path' => namespace_path). - iwhere('projects.path' => project_path). - take + iwhere('namespaces.path' => namespace_path) + + projects.where('projects.path' => project_path).take || + projects.iwhere('projects.path' => project_path).take end def visibility_levels diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 741a52714ac..71f37f1fef8 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -1,7 +1,7 @@ module Gitlab module Database def self.mysql? - ActiveRecord::Base.connection.adapter_name.downcase == 'mysql' + ActiveRecord::Base.connection.adapter_name.downcase == 'mysql2' end def self.postgresql? diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 21beaf37fce..2e41a567587 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -23,16 +23,39 @@ describe ProjectsController do end context "when requested with case sensitive namespace and project path" do - it "redirects to the normalized path for case mismatch" do - get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase + context "when there is a match with the same casing" do + it "loads the project" do + get :show, namespace_id: public_project.namespace.path, id: public_project.path - expect(response).to redirect_to("/#{public_project.path_with_namespace}") + expect(assigns(:project)).to eq(public_project) + expect(response.status).to eq(200) + end end - it "loads the page if normalized path matches request path" do - get :show, namespace_id: public_project.namespace.path, id: public_project.path + context "when there is a match with different casing" do + it "redirects to the normalized path" do + get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase - expect(response.status).to eq(200) + expect(assigns(:project)).to eq(public_project) + expect(response).to redirect_to("/#{public_project.path_with_namespace}") + end + + + # MySQL queries are case insensitive by default, so this spec would fail. + if Gitlab::Database.postgresql? + context "when there is also a match with the same casing" do + + let!(:other_project) { create(:project, :public, namespace: public_project.namespace, path: public_project.path.upcase) } + + it "loads the exactly matched project" do + + get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase + + expect(assigns(:project)).to eq(other_project) + expect(response.status).to eq(200) + end + end + end end end end |