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:
authorRémy Coutable <remy@rymai.me>2016-03-16 12:16:49 +0300
committerRémy Coutable <remy@rymai.me>2016-03-16 12:16:49 +0300
commitcacd3373ff7d5f3c8cc5774527e2474f9a28fc92 (patch)
tree58e4426905d64660d8c04020514a86bdb4306264
parent1e8bf60f40426de9cc6671a42019237688a848ac (diff)
parent374037b8a326b82a7787b2e29da820aa9c4390b3 (diff)
Merge remote-tracking branch 'origin/master' into 8-6-stable
-rw-r--r--CHANGELOG5
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock6
-rw-r--r--README.md2
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss5
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb4
-rw-r--r--app/models/abuse_report.rb4
-rw-r--r--app/models/project_wiki.rb8
-rw-r--r--app/models/wiki_page.rb2
-rw-r--r--app/services/delete_user_service.rb24
-rw-r--r--app/services/destroy_group_service.rb4
-rw-r--r--app/views/shared/issuable/_filter.html.haml2
-rw-r--r--app/workers/delete_user_worker.rb10
-rw-r--r--config/initializers/gollum.rb13
-rw-r--r--doc/install/installation.md2
-rw-r--r--features/support/capybara.rb2
-rw-r--r--lib/gitlab/diff/parser.rb2
-rw-r--r--lib/tasks/gitlab/check.rake2
-rw-r--r--spec/lib/gitlab/diff/parser_spec.rb5
-rw-r--r--spec/models/abuse_report_spec.rb16
-rw-r--r--spec/services/delete_user_service_spec.rb58
-rw-r--r--spec/support/capybara.rb2
-rw-r--r--spec/support/wait_for_ajax.rb2
-rw-r--r--spec/workers/delete_user_worker_spec.rb20
25 files changed, 163 insertions, 43 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 7f076f70c7c..fcf659c07f9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@ v 8.6.0 (unreleased)
setup. A password can be provided during setup (see installation docs), or
GitLab will ask the user to create a new one upon first visit.
- Fix issue when pushing to projects ending in .wiki
+ - Add support for wiki with UTF-8 page names (Hiroyuki Sato)
- Don't load all of GitLab in mail_room
- Update `omniauth-saml` to 1.5.0 to allow for custom response attributes to be set
- Memoize @group in Admin::GroupsController (Yatish Mehta)
@@ -39,6 +40,10 @@ v 8.6.0 (unreleased)
- Add ability to show archived projects on dashboard, explore and group pages
- Move group activity to separate page
- Continue parameters are checked to ensure redirection goes to the same instance
+ - User deletion is now done in the background so the request can not time out
+
+v 8.5.7
+ - Bump Git version requirement to 2.7.3
v 8.5.6
- Obtain a lease before querying LDAP
diff --git a/Gemfile b/Gemfile
index a0e8e796627..a849d7493a7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -58,7 +58,9 @@ gem "gitlab_git", '~> 9.0'
gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: "omniauth-ldap"
# Git Wiki
-gem 'gollum-lib', '~> 4.1.0'
+# Required manually in config/initializers/gollum.rb to control load order
+gem 'gollum-lib', '~> 4.1.0', require: false
+gem 'gollum-rugged_adapter', '~> 0.4.2', require: false
# Language detection
gem "github-linguist", "~> 4.7.0", require: "linguist"
diff --git a/Gemfile.lock b/Gemfile.lock
index f4f5649eb75..669bfcf4d6b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -381,6 +381,9 @@ GEM
rouge (~> 1.9)
sanitize (~> 2.1.0)
stringex (~> 2.5.1)
+ gollum-rugged_adapter (0.4.2)
+ mime-types (>= 1.15)
+ rugged (~> 0.24.0, >= 0.21.3)
gon (6.0.1)
actionpack (>= 3.0)
json
@@ -703,7 +706,7 @@ GEM
rubyntlm (0.5.2)
rubypants (0.2.0)
rufus-scheduler (3.1.10)
- rugged (0.24.0b13)
+ rugged (0.24.0)
safe_yaml (1.0.4)
sanitize (2.1.0)
nokogiri (>= 1.4.4)
@@ -941,6 +944,7 @@ DEPENDENCIES
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.1.0)
+ gollum-rugged_adapter (~> 0.4.2)
gon (~> 6.0.1)
grape (~> 0.13.0)
grape-entity (~> 0.4.2)
diff --git a/README.md b/README.md
index 3ec1d4a776c..208427fcf8c 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,7 @@ GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL
- Ruby (MRI) 2.1
-- Git 1.7.10+
+- Git 2.7.3+
- Redis 2.8+
- MySQL or PostgreSQL
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 5b647fc6176..309da34da07 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -161,9 +161,8 @@
.dropdown-menu-user-full-name {
display: block;
- margin-bottom: 2px;
font-weight: 600;
- line-height: 1;
+ line-height: 16px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@@ -171,7 +170,7 @@
.dropdown-menu-user-username {
display: block;
- line-height: 1;
+ line-height: 16px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
index 2463cfa87be..e9b0972bdd8 100644
--- a/app/controllers/admin/abuse_reports_controller.rb
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -6,7 +6,7 @@ class Admin::AbuseReportsController < Admin::ApplicationController
def destroy
abuse_report = AbuseReport.find(params[:id])
- abuse_report.remove_user if params[:remove_user]
+ abuse_report.remove_user(deleted_by: current_user) if params[:remove_user]
abuse_report.destroy
render nothing: true
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 87f4fb455b8..3063d299b1a 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -119,10 +119,10 @@ class Admin::UsersController < Admin::ApplicationController
end
def destroy
- DeleteUserService.new(current_user).execute(user)
+ DeleteUserWorker.perform_async(current_user.id, user.id)
respond_to do |format|
- format.html { redirect_to admin_users_path }
+ format.html { redirect_to admin_users_path, notice: "The user is being deleted." }
format.json { head :ok }
end
end
diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb
index cc59aa4e911..b61f5123127 100644
--- a/app/models/abuse_report.rb
+++ b/app/models/abuse_report.rb
@@ -19,9 +19,9 @@ class AbuseReport < ActiveRecord::Base
validates :message, presence: true
validates :user_id, uniqueness: { message: 'has already been reported' }
- def remove_user
+ def remove_user(deleted_by:)
user.block
- user.destroy
+ DeleteUserWorker.perform_async(deleted_by.id, user.id, delete_solo_owned_groups: true)
end
def notify
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index c96e6f0b8ea..59b1b86d1fb 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -2,7 +2,7 @@ class ProjectWiki
include Gitlab::ShellAdapter
MARKUPS = {
- 'Markdown' => :md,
+ 'Markdown' => :markdown,
'RDoc' => :rdoc,
'AsciiDoc' => :asciidoc
} unless defined?(MARKUPS)
@@ -47,7 +47,7 @@ class ProjectWiki
def wiki
@wiki ||= begin
Gollum::Wiki.new(path_to_repo)
- rescue Gollum::NoSuchPathError
+ rescue Rugged::OSError
create_repo!
end
end
@@ -90,7 +90,7 @@ class ProjectWiki
def create_page(title, content, format = :markdown, message = nil)
commit = commit_details(:created, message, title)
- wiki.write_page(title, format, content, commit)
+ wiki.write_page(title, format.to_sym, content, commit)
update_project_activity
rescue Gollum::DuplicatePageError => e
@@ -101,7 +101,7 @@ class ProjectWiki
def update_page(page, content, format = :markdown, message = nil)
commit = commit_details(:updated, message, page.title)
- wiki.update_page(page, page.name, format, content, commit)
+ wiki.update_page(page, page.name, format.to_sym, content, commit)
update_project_activity
end
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index dbd70dc5a44..526760779a4 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -62,7 +62,7 @@ class WikiPage
# The raw content of this page.
def content
@attributes[:content] ||= if @page
- @page.raw_data
+ @page.text_data
end
end
diff --git a/app/services/delete_user_service.rb b/app/services/delete_user_service.rb
index 173e50c9206..ce79287e35a 100644
--- a/app/services/delete_user_service.rb
+++ b/app/services/delete_user_service.rb
@@ -5,18 +5,22 @@ class DeleteUserService
@current_user = current_user
end
- def execute(user)
- if user.solo_owned_groups.present?
+ def execute(user, options = {})
+ if !options[:delete_solo_owned_groups] && user.solo_owned_groups.present?
user.errors[:base] << 'You must transfer ownership or delete groups before you can remove user'
- user
- else
- user.personal_projects.each do |project|
- # Skip repository removal because we remove directory with namespace
- # that contain all this repositories
- ::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
- end
+ return user
+ end
+
+ user.solo_owned_groups.each do |group|
+ DestroyGroupService.new(group, current_user).execute
+ end
- user.destroy
+ user.personal_projects.each do |project|
+ # Skip repository removal because we remove directory with namespace
+ # that contain all this repositories
+ ::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
end
+
+ user.destroy
end
end
diff --git a/app/services/destroy_group_service.rb b/app/services/destroy_group_service.rb
index 9189de390a2..3c42ac61be4 100644
--- a/app/services/destroy_group_service.rb
+++ b/app/services/destroy_group_service.rb
@@ -6,12 +6,12 @@ class DestroyGroupService
end
def execute
- @group.projects.each do |project|
+ group.projects.each do |project|
# Skip repository removal because we remove directory with namespace
# that contain all this repositories
::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
end
- @group.destroy
+ group.destroy
end
end
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 42a3c2c3f02..3eb0db276b2 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -16,7 +16,7 @@
- if params[:assignee_id]
= hidden_field_tag(:assignee_id, params[:assignee_id])
= dropdown_tag("Assignee", options: { toggle_class: "js-user-search js-filter-submit js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee",
- placeholder: "Search assignee", data: { any_user: "Any Author", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id" } })
+ placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id" } })
.filter-item.inline.milestone-filter
- if params[:milestone_title]
diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb
new file mode 100644
index 00000000000..6ff361e4d80
--- /dev/null
+++ b/app/workers/delete_user_worker.rb
@@ -0,0 +1,10 @@
+class DeleteUserWorker
+ include Sidekiq::Worker
+
+ def perform(current_user_id, delete_user_id, options = {})
+ delete_user = User.find(delete_user_id)
+ current_user = User.find(current_user_id)
+
+ DeleteUserService.new(current_user).execute(delete_user, options.symbolize_keys)
+ end
+end
diff --git a/config/initializers/gollum.rb b/config/initializers/gollum.rb
new file mode 100644
index 00000000000..703f24f93b2
--- /dev/null
+++ b/config/initializers/gollum.rb
@@ -0,0 +1,13 @@
+module Gollum
+ GIT_ADAPTER = "rugged"
+end
+require "gollum-lib"
+
+module Gollum
+ class Committer
+ # Patch for UTF-8 path
+ def method_missing(name, *args)
+ index.send(name, *args)
+ end
+ end
+end
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 4f011397269..362b27350cc 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -76,7 +76,7 @@ Make sure you have the right version of Git installed
# Install Git
sudo apt-get install -y git-core
- # Make sure Git is version 1.7.10 or higher, for example 1.7.12 or 2.0.0
+ # Make sure Git is version 2.7.3 or higher
git --version
Is the system packaged Git too old? Remove it and compile from source.
diff --git a/features/support/capybara.rb b/features/support/capybara.rb
index f33379f76c9..fe9e39cf509 100644
--- a/features/support/capybara.rb
+++ b/features/support/capybara.rb
@@ -9,7 +9,7 @@ Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout, window_size: [1366, 768])
end
-Capybara.default_wait_time = timeout
+Capybara.default_max_wait_time = timeout
Capybara.ignore_hidden_elements = false
unless ENV['CI'] || ENV['CI_SERVER']
diff --git a/lib/gitlab/diff/parser.rb b/lib/gitlab/diff/parser.rb
index d0f6ba23ab4..d0815fc7eea 100644
--- a/lib/gitlab/diff/parser.rb
+++ b/lib/gitlab/diff/parser.rb
@@ -4,6 +4,8 @@ module Gitlab
include Enumerable
def parse(lines)
+ return [] if lines.blank?
+
@lines = lines
line_obj_index = 0
line_old = 1
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 581ab26db79..27ed57efe55 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -913,7 +913,7 @@ namespace :gitlab do
end
def check_git_version
- required_version = Gitlab::VersionInfo.new(1, 7, 10)
+ required_version = Gitlab::VersionInfo.new(2, 7, 3)
current_version = Gitlab::VersionInfo.parse(run(%W(#{Gitlab.config.git.bin_path} --version)))
puts "Your git bin path is \"#{Gitlab.config.git.bin_path}\""
diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb
index f576c39284e..cdff063a9ed 100644
--- a/spec/lib/gitlab/diff/parser_spec.rb
+++ b/spec/lib/gitlab/diff/parser_spec.rb
@@ -90,4 +90,9 @@ eos
end
end
end
+
+ context 'when lines is empty' do
+ it { expect(parser.parse([])).to eq([]) }
+ it { expect(parser.parse(nil)).to eq([]) }
+ end
end
diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb
index 4799bbaa57c..ac12ab6c757 100644
--- a/spec/models/abuse_report_spec.rb
+++ b/spec/models/abuse_report_spec.rb
@@ -13,7 +13,8 @@
require 'rails_helper'
RSpec.describe AbuseReport, type: :model do
- subject { create(:abuse_report) }
+ subject { create(:abuse_report) }
+ let(:user) { create(:user) }
it { expect(subject).to be_valid }
@@ -31,17 +32,14 @@ RSpec.describe AbuseReport, type: :model do
describe '#remove_user' do
it 'blocks the user' do
- report = build(:abuse_report)
-
- allow(report.user).to receive(:destroy)
-
- expect { report.remove_user }.to change { report.user.blocked? }.to(true)
+ expect { subject.remove_user(deleted_by: user) }.to change { subject.user.blocked? }.to(true)
end
- it 'removes the user' do
- report = build(:abuse_report)
+ it 'lets a worker delete the user' do
+ expect(DeleteUserWorker).to receive(:perform_async).with(user.id, subject.user.id,
+ delete_solo_owned_groups: true)
- expect { report.remove_user }.to change { User.count }.by(-1)
+ subject.remove_user(deleted_by: user)
end
end
diff --git a/spec/services/delete_user_service_spec.rb b/spec/services/delete_user_service_spec.rb
new file mode 100644
index 00000000000..a65938fa03b
--- /dev/null
+++ b/spec/services/delete_user_service_spec.rb
@@ -0,0 +1,58 @@
+require 'spec_helper'
+
+describe DeleteUserService, services: true do
+ describe "Deletes a user and all their personal projects" do
+ let!(:user) { create(:user) }
+ let!(:current_user) { create(:user) }
+ let!(:namespace) { create(:namespace, owner: user) }
+ let!(:project) { create(:project, namespace: namespace) }
+
+ context 'no options are given' do
+ it 'deletes the user' do
+ DeleteUserService.new(current_user).execute(user)
+
+ expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'will delete the project in the near future' do
+ expect_any_instance_of(Projects::DestroyService).to receive(:pending_delete!).once
+
+ DeleteUserService.new(current_user).execute(user)
+ end
+ end
+
+ context "solo owned groups present" do
+ let(:solo_owned) { create(:group) }
+ let(:member) { create(:group_member) }
+ let(:user) { member.user }
+
+ before do
+ solo_owned.group_members = [member]
+ DeleteUserService.new(current_user).execute(user)
+ end
+
+ it 'does not delete the user' do
+ expect(User.find(user.id)).to eq user
+ end
+ end
+
+ context "deletions with solo owned groups" do
+ let(:solo_owned) { create(:group) }
+ let(:member) { create(:group_member) }
+ let(:user) { member.user }
+
+ before do
+ solo_owned.group_members = [member]
+ DeleteUserService.new(current_user).execute(user, delete_solo_owned_groups: true)
+ end
+
+ it 'deletes solo owned groups' do
+ expect { Project.find(solo_owned.id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'deletes the user' do
+ expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+end
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index 65d59e6813c..e1f90e17cce 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -10,7 +10,7 @@ Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout, window_size: [1366, 768])
end
-Capybara.default_wait_time = timeout
+Capybara.default_max_wait_time = timeout
Capybara.ignore_hidden_elements = true
unless ENV['CI'] || ENV['CI_SERVER']
diff --git a/spec/support/wait_for_ajax.rb b/spec/support/wait_for_ajax.rb
index 692d219e9f1..b90fc112671 100644
--- a/spec/support/wait_for_ajax.rb
+++ b/spec/support/wait_for_ajax.rb
@@ -1,6 +1,6 @@
module WaitForAjax
def wait_for_ajax
- Timeout.timeout(Capybara.default_wait_time) do
+ Timeout.timeout(Capybara.default_max_wait_time) do
loop until finished_all_ajax_requests?
end
end
diff --git a/spec/workers/delete_user_worker_spec.rb b/spec/workers/delete_user_worker_spec.rb
new file mode 100644
index 00000000000..14c56521280
--- /dev/null
+++ b/spec/workers/delete_user_worker_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe DeleteUserWorker do
+ let!(:user) { create(:user) }
+ let!(:current_user) { create(:user) }
+
+ it "calls the DeleteUserWorker with the params it was given" do
+ expect_any_instance_of(DeleteUserService).to receive(:execute).
+ with(user, {})
+
+ DeleteUserWorker.new.perform(current_user.id, user.id)
+ end
+
+ it "uses symbolized keys" do
+ expect_any_instance_of(DeleteUserService).to receive(:execute).
+ with(user, test: "test")
+
+ DeleteUserWorker.new.perform(current_user.id, user.id, "test" => "test")
+ end
+end