gitlab-org--gitlab-foss/lib/gitlab/cross_project_access.rb

70 lines
1.7 KiB
Ruby

# frozen_string_literal: true
module Gitlab
class CrossProjectAccess
class << self
delegate :add_check, :find_check, :checks,
to: :instance
end
def self.instance
@instance ||= new
end
attr_reader :checks
def initialize
@checks = {}
end
def add_check(
klass,
actions: {},
positive_condition: nil,
negative_condition: nil,
skip: false)
new_check = CheckInfo.new(actions,
positive_condition,
negative_condition,
skip
)
@checks[klass] ||= Gitlab::CrossProjectAccess::CheckCollection.new
@checks[klass].add_check(new_check)
recalculate_checks_for_class(klass)
@checks[klass]
end
def find_check(object)
@cached_checks ||= Hash.new do |cache, new_class|
parent_classes = @checks.keys.select { |existing_class| new_class <= existing_class }
closest_class = closest_parent(parent_classes, new_class)
cache[new_class] = @checks[closest_class]
end
@cached_checks[object.class]
end
private
def recalculate_checks_for_class(klass)
new_collection = @checks[klass]
@checks.each do |existing_class, existing_check_collection|
if existing_class < klass
existing_check_collection.add_collection(new_collection)
elsif klass < existing_class
new_collection.add_collection(existing_check_collection)
end
end
end
def closest_parent(classes, subject)
relevant_ancestors = subject.ancestors & classes
relevant_ancestors.first
end
end
end