debian-mirror-gitlab/debian/patches/sec-release-8-13-12.patch
2018-03-15 11:46:59 +05:30

431 lines
14 KiB
Diff

--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -111,6 +111,8 @@
Gitlab::UploadsTransfer.new.rename_namespace(path_was, path)
+ remove_exports!
+
# If repositories moved successfully we need to
# send update instructions to users.
# However we cannot allow rollback since we moved namespace dir
@@ -174,5 +176,15 @@
GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path)
end
end
+
+ remove_exports!
+ end
+
+ def remove_exports!
+ Gitlab::Popen.popen(%W(find #{export_path} -not -path #{export_path} -delete))
+ end
+
+ def export_path
+ File.join(Gitlab::ImportExport.storage_path, path_was)
end
end
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -100,15 +100,19 @@
present key.deploy_key, with: Entities::SSHKey
end
- desc 'Delete existing deploy key of currently authenticated user' do
+ desc 'Delete deploy key for a project' do
success Key
end
params do
requires :key_id, type: Integer, desc: 'The ID of the deploy key'
end
delete ":id/#{path}/:key_id" do
- key = user_project.deploy_keys.find(params[:key_id])
- key.destroy
+ key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id])
+ if key
+ key.destroy
+ else
+ not_found!('Deploy Key')
+ end
end
end
end
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -97,6 +97,12 @@
IssuesFinder.new(current_user, project_id: user_project.id).find(id)
end
+ def find_merge_request_with_access(id, access_level = :read_merge_request)
+ merge_request = user_project.merge_requests.find(id)
+ authorize! access_level, merge_request
+ merge_request
+ end
+
def paginate(relation)
relation.page(params[:page]).per(params[:per_page].to_i).tap do |data|
add_pagination_headers(data)
--- a/lib/api/merge_request_diffs.rb
+++ b/lib/api/merge_request_diffs.rb
@@ -15,10 +15,8 @@
end
get ":id/merge_requests/:merge_request_id/versions" do
- merge_request = user_project.merge_requests.
- find(params[:merge_request_id])
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
- authorize! :read_merge_request, merge_request
present merge_request.merge_request_diffs, with: Entities::MergeRequestDiff
end
@@ -34,10 +32,8 @@
end
get ":id/merge_requests/:merge_request_id/versions/:version_id" do
- merge_request = user_project.merge_requests.
- find(params[:merge_request_id])
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
- authorize! :read_merge_request, merge_request
present merge_request.merge_request_diffs.find(params[:version_id]), with: Entities::MergeRequestDiffFull
end
end
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -121,9 +121,7 @@
# GET /projects/:id/merge_requests/:merge_request_id
#
get path do
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
-
- authorize! :read_merge_request, merge_request
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
present merge_request, with: Entities::MergeRequest, current_user: current_user
end
@@ -138,9 +136,8 @@
# GET /projects/:id/merge_requests/:merge_request_id/commits
#
get "#{path}/commits" do
- merge_request = user_project.merge_requests.
- find(params[:merge_request_id])
- authorize! :read_merge_request, merge_request
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
+
present merge_request.commits, with: Entities::RepoCommit
end
@@ -154,9 +151,8 @@
# GET /projects/:id/merge_requests/:merge_request_id/changes
#
get "#{path}/changes" do
- merge_request = user_project.merge_requests.
- find(params[:merge_request_id])
- authorize! :read_merge_request, merge_request
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
+
present merge_request, with: Entities::MergeRequestChanges, current_user: current_user
end
@@ -174,8 +170,7 @@
optional :milestone_id, type: Integer, desc: 'The ID of the new milestone'
end
put path do
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
- authorize! :update_merge_request, merge_request
+ merge_request = find_merge_request_with_access(params.delete(:merge_request_id), :update_merge_request)
# Ensure source_branch is not specified
if params[:source_branch].present?
@@ -262,10 +257,7 @@
# GET /projects/:id/merge_requests/:merge_request_id/comments
#
get "#{path}/comments" do
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
-
- authorize! :read_merge_request, merge_request
-
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
present paginate(merge_request.notes.fresh), with: Entities::MRNote
end
@@ -284,9 +276,7 @@
post "#{path}/comments" do
required_attributes! [:note]
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
-
- authorize! :create_note, merge_request
+ merge_request = find_merge_request_with_access(params[:merge_request_id], :create_note)
opts = {
note: params[:note],
@@ -311,7 +301,7 @@
# Examples:
# GET /projects/:id/merge_requests/:merge_request_id/closes_issues
get "#{path}/closes_issues" do
- merge_request = user_project.merge_requests.find(params[:merge_request_id])
+ merge_request = find_merge_request_with_access(params[:merge_request_id])
issues = ::Kaminari.paginate_array(merge_request.closes_issues(current_user))
present paginate(issues), with: issue_entity(user_project), current_user: current_user
end
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -74,21 +74,27 @@
required_attributes! [:body]
opts = {
- note: params[:body],
- noteable_type: noteables_str.classify,
- noteable_id: params[noteable_id_str]
+ note: params[:body],
+ noteable_type: noteables_str.classify,
+ noteable_id: params[noteable_id_str]
}
- if params[:created_at] && (current_user.is_admin? || user_project.owner == current_user)
- opts[:created_at] = params[:created_at]
- end
+ noteable = user_project.send(noteables_str.to_sym).find(opts[:noteable_id])
+
+ if can?(current_user, noteable_read_ability_name(noteable), noteable)
+ if params[:created_at] && (current_user.is_admin? || user_project.owner == current_user)
+ opts[:created_at] = params[:created_at]
+ end
- note = ::Notes::CreateService.new(user_project, current_user, opts).execute
+ note = ::Notes::CreateService.new(user_project, current_user, opts).execute
- if note.valid?
- present note, with: Entities::const_get(note.class.name)
+ if note.valid?
+ present note, with: Entities::const_get(note.class.name)
+ else
+ not_found!("Note #{note.errors.messages}")
+ end
else
- not_found!("Note #{note.errors.messages}")
+ not_found!("Note")
end
end
--- a/lib/api/subscriptions.rb
+++ b/lib/api/subscriptions.rb
@@ -3,8 +3,8 @@
before { authenticate! }
subscribable_types = {
- 'merge_request' => proc { |id| user_project.merge_requests.find(id) },
- 'merge_requests' => proc { |id| user_project.merge_requests.find(id) },
+ 'merge_request' => proc { |id| find_merge_request_with_access(id, :update_merge_request) },
+ 'merge_requests' => proc { |id| find_merge_request_with_access(id, :update_merge_request) },
'issues' => proc { |id| find_project_issue(id) },
'labels' => proc { |id| find_project_label(id) },
}
--- a/lib/api/todos.rb
+++ b/lib/api/todos.rb
@@ -4,7 +4,7 @@
before { authenticate! }
ISSUABLE_TYPES = {
- 'merge_requests' => ->(id) { user_project.merge_requests.find(id) },
+ 'merge_requests' => ->(id) { find_merge_request_with_access(id) },
'issues' => ->(id) { find_project_issue(id) }
}
--- /dev/null
+++ b/spec/features/projects/import_export/namespace_export_file_spec.rb
@@ -0,0 +1,62 @@
+require 'spec_helper'
+
+feature 'Import/Export - Namespace export file cleanup', feature: true, js: true do
+ let(:export_path) { "#{Dir::tmpdir}/import_file_spec" }
+ let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys }
+
+ let(:project) { create(:empty_project) }
+
+ background do
+ allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
+ end
+
+ after do
+ FileUtils.rm_rf(export_path, secure: true)
+ end
+
+ context 'admin user' do
+ before do
+ login_as(:admin)
+ end
+
+ context 'moving the namespace' do
+ scenario 'removes the export file' do
+ setup_export_project
+
+ old_export_path = project.export_path.dup
+
+ expect(File).to exist(old_export_path)
+
+ project.namespace.update(path: 'new_path')
+
+ expect(File).not_to exist(old_export_path)
+ end
+ end
+
+ context 'deleting the namespace' do
+ scenario 'removes the export file' do
+ setup_export_project
+
+ old_export_path = project.export_path.dup
+
+ expect(File).to exist(old_export_path)
+
+ project.namespace.destroy
+
+ expect(File).not_to exist(old_export_path)
+ end
+ end
+
+ def setup_export_project
+ visit edit_namespace_project_path(project.namespace, project)
+
+ expect(page).to have_content('Export project')
+
+ click_link 'Export project'
+
+ visit edit_namespace_project_path(project.namespace, project)
+
+ expect(page).to have_content('Download export')
+ end
+ end
+end
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -69,6 +69,7 @@
new_path = @namespace.path + "_new"
allow(@namespace).to receive(:path_was).and_return(@namespace.path)
allow(@namespace).to receive(:path).and_return(new_path)
+ expect(@namespace).to receive(:remove_exports!)
expect(@namespace.move_dir).to be_truthy
end
@@ -91,11 +92,17 @@
let!(:project) { create(:project, namespace: namespace) }
let!(:path) { File.join(Gitlab.config.repositories.storages.default, namespace.path) }
- before { namespace.destroy }
-
it "removes its dirs when deleted" do
+ namespace.destroy
+
expect(File.exist?(path)).to be(false)
end
+
+ it 'removes the exports folder' do
+ expect(namespace).to receive(:remove_exports!)
+
+ namespace.destroy
+ end
end
describe '.find_by_path_or_name' do
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -597,6 +597,15 @@
expect(json_response.first['title']).to eq(issue.title)
expect(json_response.first['id']).to eq(issue.id)
end
+
+ it 'returns 403 if the user has no access to the merge request' do
+ guest = create(:user)
+ project.team << [guest, :guest]
+
+ get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", guest)
+
+ expect(response).to have_http_status(403)
+ end
end
describe 'POST :id/merge_requests/:merge_request_id/subscription' do
@@ -618,6 +627,15 @@
expect(response).to have_http_status(404)
end
+
+ it 'returns 403 if user has no access to read code' do
+ guest = create(:user)
+ project.team << [guest, :guest]
+
+ post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest)
+
+ expect(response).to have_http_status(403)
+ end
end
describe 'DELETE :id/merge_requests/:merge_request_id/subscription' do
@@ -639,6 +657,15 @@
expect(response).to have_http_status(404)
end
+
+ it 'returns 403 if user has no access to read code' do
+ guest = create(:user)
+ project.team << [guest, :guest]
+
+ delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest)
+
+ expect(response).to have_http_status(403)
+ end
end
def mr_with_later_created_and_updated_at_time
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -253,6 +253,18 @@
end
end
+ context 'when user does not have access to read the noteable' do
+ it 'responds with 404' do
+ project = create(:empty_project, :private) { |p| p.team << [user, :guest] }
+ issue = create(:issue, :confidential, project: project)
+
+ post api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
+ body: 'Foo'
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
context 'when user does not have access to create noteable' do
let(:private_issue) { create(:issue, project: create(:project, :private)) }
--- a/spec/requests/api/todos_spec.rb
+++ b/spec/requests/api/todos_spec.rb
@@ -183,12 +183,25 @@
expect(response.status).to eq(404)
end
+
+ it 'returns an error if the issuable is not accessible' do
+ guest = create(:user)
+ project_1.team << [guest, :guest]
+
+ post api("/projects/#{project_1.id}/#{issuable_type}/#{issuable.id}/todo", guest)
+
+ if issuable_type == 'merge_requests'
+ expect(response).to have_http_status(403)
+ else
+ expect(response).to have_http_status(404)
+ end
+ end
end
describe 'POST :id/issuable_type/:issueable_id/todo' do
context 'for an issue' do
it_behaves_like 'an issuable', 'issues' do
- let(:issuable) { create(:issue, author: author_1, project: project_1) }
+ let(:issuable) { create(:issue, :confidential, author: author_1, project: project_1) }
end
end