Commit 2b73aaa1 authored by Ali Ibrahim's avatar Ali Ibrahim

Allow to add deploy keys with write-access

parent d1da2e81
...@@ -126,6 +126,7 @@ v 8.10.6 ...@@ -126,6 +126,7 @@ v 8.10.6
- Restore "Largest repository" sort option on Admin > Projects page. !5797 - Restore "Largest repository" sort option on Admin > Projects page. !5797
- Fix privilege escalation via project export. - Fix privilege escalation via project export.
- Require administrator privileges to perform a project import. - Require administrator privileges to perform a project import.
- Allow to add deploy keys with write-access !5807 (Ali Ibrahim)
v 8.10.5 v 8.10.5
- Add a data migration to fix some missing timestamps in the members table. !5670 - Add a data migration to fix some missing timestamps in the members table. !5670
......
...@@ -53,6 +53,6 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -53,6 +53,6 @@ class Projects::DeployKeysController < Projects::ApplicationController
end end
def deploy_key_params def deploy_key_params
params.require(:deploy_key).permit(:key, :title) params.require(:deploy_key).permit(:key, :title, :can_push)
end end
end end
...@@ -10,4 +10,13 @@ ...@@ -10,4 +10,13 @@
%p.light.append-bottom-0 %p.light.append-bottom-0
Paste a machine public key here. Read more about how to generate it Paste a machine public key here. Read more about how to generate it
= link_to "here", help_page_path("ssh/README") = link_to "here", help_page_path("ssh/README")
.form-group
.checkbox
= f.label :can_push do
= f.check_box :can_push
%strong Allow write access
.form-group
%p.light.append-bottom-0
Can this key be used to push to this repository? Deploy keys always have pull access
= f.submit "Add key", class: "btn-create btn" = f.submit "Add key", class: "btn-create btn"
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddCanPushToKeys < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = ''
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
disable_ddl_transaction!
def change
add_column_with_default(:keys, :can_push, :boolean, default: false, allow_null: false)
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160810142633) do ActiveRecord::Schema.define(version: 20160811172945) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -484,6 +484,7 @@ ActiveRecord::Schema.define(version: 20160810142633) do ...@@ -484,6 +484,7 @@ ActiveRecord::Schema.define(version: 20160810142633) do
t.string "type" t.string "type"
t.string "fingerprint" t.string "fingerprint"
t.boolean "public", default: false, null: false t.boolean "public", default: false, null: false
t.boolean "can_push", default: false, null: false
end end
add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree
...@@ -589,12 +590,12 @@ ActiveRecord::Schema.define(version: 20160810142633) do ...@@ -589,12 +590,12 @@ ActiveRecord::Schema.define(version: 20160810142633) do
t.datetime "locked_at" t.datetime "locked_at"
t.integer "updated_by_id" t.integer "updated_by_id"
t.string "merge_error" t.string "merge_error"
t.text "merge_params"
t.boolean "merge_when_build_succeeds", default: false, null: false t.boolean "merge_when_build_succeeds", default: false, null: false
t.integer "merge_user_id" t.integer "merge_user_id"
t.string "merge_commit_sha" t.string "merge_commit_sha"
t.datetime "deleted_at" t.datetime "deleted_at"
t.string "in_progress_merge_commit_sha" t.string "in_progress_merge_commit_sha"
t.text "merge_params"
end end
add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
......
...@@ -50,10 +50,13 @@ module Gitlab ...@@ -50,10 +50,13 @@ module Gitlab
end end
def push_access_check(changes) def push_access_check(changes)
unless project.repository.exists?
return build_status_object(false, "A repository for this project does not exist yet.")
end
if user if user
user_push_access_check(changes) user_push_access_check(changes)
elsif deploy_key elsif deploy_key
build_status_object(false, "Deploy keys are not allowed to push code.") deploy_key_push_access_check(changes)
else else
raise 'Wrong actor' raise 'Wrong actor'
end end
...@@ -72,10 +75,6 @@ module Gitlab ...@@ -72,10 +75,6 @@ module Gitlab
return build_status_object(true) return build_status_object(true)
end end
unless project.repository.exists?
return build_status_object(false, "A repository for this project does not exist yet.")
end
changes_list = Gitlab::ChangesList.new(changes) changes_list = Gitlab::ChangesList.new(changes)
# Iterate over all changes to find if user allowed all of them to be applied # Iterate over all changes to find if user allowed all of them to be applied
...@@ -90,6 +89,14 @@ module Gitlab ...@@ -90,6 +89,14 @@ module Gitlab
build_status_object(true) build_status_object(true)
end end
def deploy_key_push_access_check(changes)
if actor.can_push?
build_status_object(true)
else
build_status_object(false, "The deploy key does not have write access to the project.")
end
end
def change_access_check(change) def change_access_check(change)
Checks::ChangeAccess.new(change, user_access: user_access, project: project).exec Checks::ChangeAccess.new(change, user_access: user_access, project: project).exec
end end
......
...@@ -284,19 +284,22 @@ describe Gitlab::GitAccess, lib: true do ...@@ -284,19 +284,22 @@ describe Gitlab::GitAccess, lib: true do
end end
describe 'deploy key permissions' do describe 'deploy key permissions' do
let(:key) { create(:deploy_key) }
let(:actor) { key }
context 'push code' do context 'push code' do
subject { access.check('git-receive-pack', '_any') } subject { access.check('git-receive-pack', '_any') }
context 'when project is authorized' do context 'when project is authorized' do
let(:key) { create(:deploy_key, can_push: true) }
let(:actor) { key }
before { key.projects << project } before { key.projects << project }
it { expect(subject).not_to be_allowed } it { expect(subject).to be_allowed }
end end
context 'when unauthorized' do context 'when unauthorized' do
let(:key) { create(:deploy_key, can_push: false) }
let(:actor) { key }
context 'to public project' do context 'to public project' do
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment