Commit 05d54b51 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Move EE specific `ProtectedRef` into `EE` module

parent 0761e921
module EE
module ProtectedRef
extend ActiveSupport::Concern
class_methods do
def protected_ref_access_levels(*types)
types.each do |type|
# We need to set `inverse_of` to make sure the `belongs_to`-object is set
# when creating children using `accepts_nested_attributes_for`.
#
# If we don't `protected_branch` or `protected_tag` would be empty and
# `project` cannot be delegated to it, which in turn would cause validations
# to fail.
has_many :"#{type}_access_levels", dependent: :destroy, inverse_of: self.model_name.singular
accepts_nested_attributes_for :"#{type}_access_levels", allow_destroy: true
# Overwrite the validation for access levels
#
# EE Needs to allow more access levels in the relation:
# - 1 for each user/group
# - 1 with the `access_level` (Master, Developer)
validates :"#{type}_access_levels", length: { is: 1 }, if: -> { false }
# Returns access levels that grant the specified access type to the given user / group.
access_level_class = const_get("#{type}_access_level".classify)
protected_type = self.model_name.singular
scope :"#{type}_access_by_user", -> (user) { access_level_class.joins(protected_type.to_sym).where("#{protected_type}_id" => self.ids).merge(access_level_class.by_user(user)) }
scope :"#{type}_access_by_group", -> (group) { access_level_class.joins(protected_type.to_sym).where("#{protected_type}_id" => self.ids).merge(access_level_class.by_group(group)) }
end
end
end
end
end
......@@ -20,7 +20,7 @@ module EE
conditions: -> { where(user_id: nil, group_id: nil) } }
validates :group, :user,
absence: true,
unless: proc { |access| access.type != :role && access.project.feature_available?(:ref_permissions_for_users) }
unless: :ref_permissions_for_users_required_and_available
scope :by_user, -> (user) { where(user: user ) }
scope :by_group, -> (group) { where(group: group ) }
......@@ -55,5 +55,13 @@ module EE
super
end
# We don't need to validate the license if this access applies to a role.
#
# If it applies to a user/group we can only skip validation `nil`-validation
# if the feature is available
def ref_permissions_for_users_required_and_available
type != :role && project.feature_available?(:ref_permissions_for_users)
end
end
end
......@@ -25,15 +25,9 @@ module ProtectedRef
# to fail.
has_many :"#{type}_access_levels", dependent: :destroy, inverse_of: self.model_name.singular # rubocop:disable Cop/ActiveRecordDependent
validates :"#{type}_access_levels", length: { minimum: 0 }
validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }
accepts_nested_attributes_for :"#{type}_access_levels", allow_destroy: true
# Returns access levels that grant the specified access type to the given user / group.
access_level_class = const_get("#{type}_access_level".classify)
protected_type = self.model_name.singular
scope :"#{type}_access_by_user", -> (user) { access_level_class.joins(protected_type.to_sym).where("#{protected_type}_id" => self.ids).merge(access_level_class.by_user(user)) }
scope :"#{type}_access_by_group", -> (group) { access_level_class.joins(protected_type.to_sym).where("#{protected_type}_id" => self.ids).merge(access_level_class.by_group(group)) }
end
end
......
class ProtectedBranch < ActiveRecord::Base
include Gitlab::ShellAdapter
include ProtectedRef
prepend EE::ProtectedRef
protected_ref_access_levels :merge, :push
......
class ProtectedTag < ActiveRecord::Base
include Gitlab::ShellAdapter
include ProtectedRef
include EE::ProtectedRef
protected_ref_access_levels :create
......
......@@ -28,7 +28,7 @@ describe EE::ProtectedRefAccess do
expect(access_level.errors).to include(:group)
end
it "allows creating an #{included_in_class} with a group" do
it "allows creating an #{included_in_class} with a user" do
access_level.user = create(:user)
expect(access_level).not_to be_valid
......@@ -47,7 +47,7 @@ describe EE::ProtectedRefAccess do
expect(access_level).to be_valid
end
it "allows creating an #{included_in_class} with a group" do
it "allows creating an #{included_in_class} with a user" do
access_level.user = create(:user)
expect(access_level).to be_valid
......
require 'spec_helper'
describe EE::ProtectedRef do
context 'for protected branches' do
it 'deletes all related access levels' do
protected_branch = create(:protected_branch)
2.times { protected_branch.merge_access_levels.create!(group: create(:group)) }
2.times { protected_branch.push_access_levels.create!(user: create(:user)) }
protected_branch.destroy
expect(ProtectedBranch::MergeAccessLevel.count).to be(0)
expect(ProtectedBranch::PushAccessLevel.count).to be(0)
end
end
end
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