diff options
author | Douwe Maan <douwe@gitlab.com> | 2016-02-04 16:12:47 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2016-02-04 16:12:47 +0000 |
commit | ac923b4fb40da88d6c7907d08d4584d5d4a560e2 (patch) | |
tree | 79050d2d630b681d1ed97448e497be87c4905328 | |
parent | dfe12649f64bcac76b270a96be04285bbe0c2aa2 (diff) | |
parent | 5dc77d7577bf19586f6cd756678d0c2660e7f868 (diff) | |
download | gitlab-ce-ac923b4fb40da88d6c7907d08d4584d5d4a560e2.tar.gz |
Merge branch 'fix/atom-url-issue' into 'master'
Fix atom url issue on projects
This MR adds prevents a project to have a path ending in .atom that conflicts with the feed
and
Adds a migration to migrate old .atom projects to a different path
Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/3699
See merge request !2651
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb | 80 | ||||
-rw-r--r-- | db/schema.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/backend/shell.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/regex.rb | 4 | ||||
-rw-r--r-- | spec/controllers/projects_controller_spec.rb | 8 |
6 files changed, 93 insertions, 4 deletions
diff --git a/CHANGELOG b/CHANGELOG index 330872e504d..b7e8822fdd6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,6 +26,7 @@ v 8.5.0 (unreleased) - Fix API to keep request parameters in Link header (Michael Potthoff) - Deprecate API "merge_request/:merge_request_id/comments". Use "merge_requests/:merge_request_id/notes" instead - Deprecate API "merge_request/:merge_request_id/...". Use "merge_requests/:merge_request_id/..." instead + - Prevent parse error when name of project ends with .atom and prevent path issues - Mark inline difference between old and new paths when a file is renamed - Support Akismet spam checking for creation of issues via API (Stan Hu) - Improve UI consistency between projects and groups lists diff --git a/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb b/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb new file mode 100644 index 00000000000..091de54978b --- /dev/null +++ b/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb @@ -0,0 +1,80 @@ +class RemoveDotAtomPathEndingOfProjects < ActiveRecord::Migration + include Gitlab::ShellAdapter + + class ProjectPath + attr_reader :old_path, :id, :namespace_path + + def initialize(old_path, id, namespace_path, namespace_id) + @old_path = old_path + @id = id + @namespace_path = namespace_path + @namespace_id = namespace_id + end + + def clean_path + @_clean_path ||= PathCleaner.clean(@old_path, @namespace_id) + end + end + + class PathCleaner + def initialize(path, namespace_id) + @namespace_id = namespace_id + @path = path + end + + def self.clean(*args) + new(*args).clean + end + + def clean + path = cleaned_path + count = 0 + while path_exists?(path) + path = "#{cleaned_path}#{count}" + count += 1 + end + path + end + + private + + def cleaned_path + @_cleaned_path ||= @path.gsub(/\.atom\z/, '-atom') + end + + def path_exists?(path) + Project.find_by_path_and_namespace_id(path, @namespace_id) + end + end + + def projects_with_dot_atom + select_all("SELECT p.id, p.path, n.path as namespace_path, n.id as namespace_id FROM projects p inner join namespaces n on n.id = p.namespace_id WHERE lower(p.path) LIKE '%.atom'") + end + + def up + projects_with_dot_atom.each do |project| + project_path = ProjectPath.new(project['path'], project['id'], project['namespace_path'], project['namespace_id']) + clean_path(project_path) if rename_project_repo(project_path) + end + end + + private + + def clean_path(project_path) + execute "UPDATE projects SET path = #{sanitize(project_path.clean_path)} WHERE id = #{project_path.id}" + end + + def rename_project_repo(project_path) + old_path_with_namespace = File.join(project_path.namespace_path, project_path.old_path) + new_path_with_namespace = File.join(project_path.namespace_path, project_path.clean_path) + + gitlab_shell.mv_repository("#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki") + gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace) + rescue + false + end + + def sanitize(value) + ActiveRecord::Base.connection.quote(value) + end +end diff --git a/db/schema.rb b/db/schema.rb index d546e06cd8a..d4710346b82 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160128233227) do +ActiveRecord::Schema.define(version: 20160129135155) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb index 4c15d58d680..f751458ac66 100644 --- a/lib/gitlab/backend/shell.rb +++ b/lib/gitlab/backend/shell.rb @@ -47,7 +47,7 @@ module Gitlab # new_path - new project path with namespace # # Ex. - # mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git") + # mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new") # def mv_repository(path, new_path) Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'mv-project', diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index 5c35c5b1450..ace906a6f59 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -34,12 +34,12 @@ module Gitlab def project_path_regex - @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git)\z/.freeze + @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git|\.atom)\z/.freeze end def project_path_regex_message "can contain only letters, digits, '_', '-' and '.'. " \ - "Cannot start with '-' or end in '.git'" \ + "Cannot start with '-', end in '.git' or end in '.atom'" \ end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 665526fde93..6eee4dfe229 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -86,6 +86,14 @@ describe ProjectsController do end end end + + context "when the url contains .atom" do + let(:public_project_with_dot_atom) { build(:project, :public, name: 'my.atom', path: 'my.atom') } + + it 'expect an error creating the project' do + expect(public_project_with_dot_atom).not_to be_valid + end + end end describe "#destroy" do |