Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Speicher <robert@gitlab.com>2015-10-22 16:03:04 +0300
committerRobert Speicher <rspeicher@gmail.com>2015-10-22 16:05:54 +0300
commit8fe4352eba29a2642e7bb39f95f284700593e24e (patch)
tree8d5f849e68f61d1b1a76ec68eca9ffef91a33ec0
parent613f368ce576daf10d79d3c39ddf600cc0d9f6c7 (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.rb1
-rw-r--r--app/models/project.rb9
-rw-r--r--lib/gitlab/database.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb35
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