Module: FinderWithCrossProjectAccess

Extended by:
ActiveSupport::Concern, Gitlab::Utils::Override
Included in:
EventsFinder, IssuableFinder, LabelsFinder, TodosFinder, UserRecentEventsFinder
Defined in:
app/finders/concerns/finder_with_cross_project_access.rb

Overview

Module to prepend into finders to specify whether or not the finder requires cross project access

This module depends on the finder implementing the following methods:

  • ‘#execute` should return an `ActiveRecord::Relation` or the `model` needs to

    be defined in the call to `requires_cross_project_access`.
    
  • ‘#current_user` the user that requires access (or nil)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Gitlab::Utils::Override

extended, extensions, included, method_added, override, prepended, queue_verification, verify!

Instance Attribute Details

#should_skip_cross_project_checkObject

Returns the value of attribute should_skip_cross_project_check.



67
68
69
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 67

def should_skip_cross_project_check
  @should_skip_cross_project_check
end

Instance Method Details

#can_read_cross_project?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 79

def can_read_cross_project?
  Ability.allowed?(current_user, :read_cross_project)
end

#can_read_project?(project) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 83

def can_read_project?(project)
  Ability.allowed?(current_user, :read_project, project)
end

#execute(*args, **kwargs) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 35

def execute(*args, **kwargs)
  check = Gitlab::CrossProjectAccess.find_check(self)
  original = -> { super }

  return original.call unless check
  return original.call if should_skip_cross_project_check || can_read_cross_project?

  if check.should_run?(self)
    finder_model&.none || original.call.model.none
  else
    original.call
  end
end

#find(*args) ⇒ Object



63
64
65
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 63

def find(*args)
  skip_cross_project_check { super }
end

#find_by(*args) ⇒ Object



58
59
60
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 58

def find_by(*args)
  skip_cross_project_check { super }
end

#find_by!(*args) ⇒ Object



53
54
55
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 53

def find_by!(*args)
  skip_cross_project_check { super }
end

#skip_cross_project_checkObject



69
70
71
72
73
74
75
76
77
# File 'app/finders/concerns/finder_with_cross_project_access.rb', line 69

def skip_cross_project_check
  self.should_skip_cross_project_check = true

  yield
ensure
  # The find could raise an `ActiveRecord::RecordNotFound`, after which we
  # still want to re-enable the check.
  self.should_skip_cross_project_check = false
end