Commit 7714c114 authored by Timothy Andrew's avatar Timothy Andrew Committed by Alfredo Sumaran

Backend implementation to allow a group to be granted access to a protected branch.

1. A protected branch access level `belongs_to` a group in addition to a
   user. When access for a user is checked, see if the user is present
   in the access level's group, if any.

2. If a group is added to a project with `:reporter` access or lower,
   adding a group to a proteted branch does _not_ grant access, since
   the `push_code` ability is still checked. This is tested with a few
   hundred new tests in `git_access_spec`.
parent e9b33c14
...@@ -3,6 +3,7 @@ class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base ...@@ -3,6 +3,7 @@ class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base
belongs_to :protected_branch belongs_to :protected_branch
belongs_to :user belongs_to :user
belongs_to :group
delegate :project, to: :protected_branch delegate :project, to: :protected_branch
...@@ -21,6 +22,7 @@ class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base ...@@ -21,6 +22,7 @@ class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base
def check_access(user) def check_access(user)
return true if user.is_admin? return true if user.is_admin?
return user.id == self.user_id if self.user.present? return user.id == self.user_id if self.user.present?
return group.users.exists?(user.id) if self.group.present?
project.team.max_member_access(user.id) >= access_level project.team.max_member_access(user.id) >= access_level
end end
......
...@@ -3,6 +3,7 @@ class ProtectedBranch::PushAccessLevel < ActiveRecord::Base ...@@ -3,6 +3,7 @@ class ProtectedBranch::PushAccessLevel < ActiveRecord::Base
belongs_to :protected_branch belongs_to :protected_branch
belongs_to :user belongs_to :user
belongs_to :group
delegate :project, to: :protected_branch delegate :project, to: :protected_branch
...@@ -24,6 +25,7 @@ class ProtectedBranch::PushAccessLevel < ActiveRecord::Base ...@@ -24,6 +25,7 @@ class ProtectedBranch::PushAccessLevel < ActiveRecord::Base
return false if access_level == Gitlab::Access::NO_ACCESS return false if access_level == Gitlab::Access::NO_ACCESS
return true if user.is_admin? return true if user.is_admin?
return user.id == self.user_id if self.user.present? return user.id == self.user_id if self.user.present?
return group.users.exists?(user.id) if self.group.present?
project.team.max_member_access(user.id) >= access_level project.team.max_member_access(user.id) >= access_level
end end
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddGroupIdColumnsToProtectedBranchAccessLevels < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = true
DOWNTIME_REASON = "This migrations adds two foreign keys, and so requires downtime."
# 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.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change
add_column :protected_branch_merge_access_levels, :group_id, :integer
add_foreign_key :protected_branch_merge_access_levels, :namespaces, column: :group_id
add_column :protected_branch_push_access_levels, :group_id, :integer
add_foreign_key :protected_branch_push_access_levels, :namespaces, column: :group_id
end
end
...@@ -1048,6 +1048,7 @@ ActiveRecord::Schema.define(version: 20161007133303) do ...@@ -1048,6 +1048,7 @@ ActiveRecord::Schema.define(version: 20161007133303) do
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.integer "user_id" t.integer "user_id"
t.integer "group_id"
end end
add_index "protected_branch_merge_access_levels", ["protected_branch_id"], name: "index_protected_branch_merge_access", using: :btree add_index "protected_branch_merge_access_levels", ["protected_branch_id"], name: "index_protected_branch_merge_access", using: :btree
...@@ -1059,6 +1060,7 @@ ActiveRecord::Schema.define(version: 20161007133303) do ...@@ -1059,6 +1060,7 @@ ActiveRecord::Schema.define(version: 20161007133303) do
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.integer "user_id" t.integer "user_id"
t.integer "group_id"
end end
add_index "protected_branch_push_access_levels", ["protected_branch_id"], name: "index_protected_branch_push_access", using: :btree add_index "protected_branch_push_access_levels", ["protected_branch_id"], name: "index_protected_branch_push_access", using: :btree
...@@ -1404,8 +1406,10 @@ ActiveRecord::Schema.define(version: 20161007133303) do ...@@ -1404,8 +1406,10 @@ ActiveRecord::Schema.define(version: 20161007133303) do
add_foreign_key "path_locks", "projects" add_foreign_key "path_locks", "projects"
add_foreign_key "path_locks", "users" add_foreign_key "path_locks", "users"
add_foreign_key "personal_access_tokens", "users" add_foreign_key "personal_access_tokens", "users"
add_foreign_key "protected_branch_merge_access_levels", "namespaces", column: "group_id"
add_foreign_key "protected_branch_merge_access_levels", "protected_branches" add_foreign_key "protected_branch_merge_access_levels", "protected_branches"
add_foreign_key "protected_branch_merge_access_levels", "users" add_foreign_key "protected_branch_merge_access_levels", "users"
add_foreign_key "protected_branch_push_access_levels", "namespaces", column: "group_id"
add_foreign_key "protected_branch_push_access_levels", "protected_branches" add_foreign_key "protected_branch_push_access_levels", "protected_branches"
add_foreign_key "protected_branch_push_access_levels", "users" add_foreign_key "protected_branch_push_access_levels", "users"
add_foreign_key "remote_mirrors", "projects" add_foreign_key "remote_mirrors", "projects"
......
...@@ -11,6 +11,9 @@ FactoryGirl.define do ...@@ -11,6 +11,9 @@ FactoryGirl.define do
transient do transient do
authorize_user_to_push nil authorize_user_to_push nil
authorize_user_to_merge nil authorize_user_to_merge nil
authorize_group_to_push nil
authorize_group_to_merge nil
end end
trait :remove_default_access_levels do trait :remove_default_access_levels do
...@@ -47,6 +50,9 @@ FactoryGirl.define do ...@@ -47,6 +50,9 @@ FactoryGirl.define do
after(:create) do |protected_branch, evaluator| after(:create) do |protected_branch, evaluator|
protected_branch.push_access_levels.create!(user: evaluator.authorize_user_to_push) if evaluator.authorize_user_to_push protected_branch.push_access_levels.create!(user: evaluator.authorize_user_to_push) if evaluator.authorize_user_to_push
protected_branch.merge_access_levels.create!(user: evaluator.authorize_user_to_merge) if evaluator.authorize_user_to_merge protected_branch.merge_access_levels.create!(user: evaluator.authorize_user_to_merge) if evaluator.authorize_user_to_merge
protected_branch.push_access_levels.create!(group: evaluator.authorize_group_to_push) if evaluator.authorize_group_to_push
protected_branch.merge_access_levels.create!(group: evaluator.authorize_group_to_merge) if evaluator.authorize_group_to_merge
end end
end end
end end
This diff is collapsed.
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