File: current.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (72 lines) | stat: -rw-r--r-- 2,160 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# frozen_string_literal: true

# rubocop:disable Gitlab/NamespacedClass -- We want this to be top level due to scope of use and no namespace due to ease of calling
class Current < ActiveSupport::CurrentAttributes
  include Gitlab::InternalEventsTracking

  class OrganizationNotAssignedError < RuntimeError
    def message
      'Assign an organization to Current.organization before calling it.'
    end
  end

  class OrganizationAlreadyAssignedError < RuntimeError
    def message
      'Current.organization has already been set in the current thread and should not be set again.'
    end
  end

  # watch background jobs need to reset on each job if using
  attribute :organization, :organization_assigned

  def organization=(value)
    # We want to explicitly allow only one organization assignment per thread
    # This fits the request/response cycle, but of course for rake tasks/background jobs that use the same thread,
    # we will need to reset as the first step in execution with Current.reset..if used at those layers.
    if organization_assigned
      Gitlab::ErrorTracking.track_and_raise_for_dev_exception(OrganizationAlreadyAssignedError.new)

      return # when outside of dev/test
    end

    self.organization_assigned = true

    Gitlab::ApplicationContext.push(organization: value)

    super(value)
  end

  def organization
    unless organization_assigned
      Gitlab::ErrorTracking.track_and_raise_for_dev_exception(OrganizationNotAssignedError.new)
    end

    track_organization_call

    super
  end

  def organization_id
    organization&.id
  end

  private

  # Do not allow to reset this
  def organization_assigned=(value)
    organization_assigned || super(value)
  end

  def track_organization_call
    return unless Feature.enabled?(:track_organization_fallback, Feature.current_request)
    return unless Gitlab::SafeRequestStore[:fallback_organization_used]

    track_internal_event(
      'fallback_current_organization_to_default',
      additional_properties: {
        label: Gitlab::ApplicationContext.current_context_attribute(:caller_id)
      }
    )
  end
end
# rubocop:enable Gitlab/NamespacedClass