Allow to add deploy keys with write-access
This commit is contained in:
parent
d1da2e8180
commit
2b73aaa15a
|
@ -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
|
||||||
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 @@
|
||||||
%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"
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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
|
21
db/schema.rb
21
db/schema.rb
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
|
@ -930,8 +931,8 @@ ActiveRecord::Schema.define(version: 20160810142633) do
|
||||||
t.string "noteable_type"
|
t.string "noteable_type"
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.boolean "submitted_as_ham", default: false, null: false
|
t.boolean "submitted_as_ham", default: false, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1001,13 +1002,13 @@ ActiveRecord::Schema.define(version: 20160810142633) do
|
||||||
add_index "u2f_registrations", ["user_id"], name: "index_u2f_registrations_on_user_id", using: :btree
|
add_index "u2f_registrations", ["user_id"], name: "index_u2f_registrations_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "user_agent_details", force: :cascade do |t|
|
create_table "user_agent_details", force: :cascade do |t|
|
||||||
t.string "user_agent", null: false
|
t.string "user_agent", null: false
|
||||||
t.string "ip_address", null: false
|
t.string "ip_address", null: false
|
||||||
t.integer "subject_id", null: false
|
t.integer "subject_id", null: false
|
||||||
t.string "subject_type", null: false
|
t.string "subject_type", null: false
|
||||||
t.boolean "submitted", default: false, null: false
|
t.boolean "submitted", default: false, null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
|
|
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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) }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue