Welcome to mirror list, hosted at ThFree Co, Russian Federation.

visibility_level.rb « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 76cf769d0419741d5dae9edbe4dcd2f3f353f681 (plain)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# frozen_string_literal: true

# Gitlab::VisibilityLevel module
#
# Define allowed public modes that can be used for
# GitLab projects to determine project public mode
#
module Gitlab
  module VisibilityLevel
    extend ActiveSupport::Concern

    included do
      scope :public_only,               -> { where(visibility_level: PUBLIC) }
      scope :public_and_internal_only,  -> { where(visibility_level: [PUBLIC, INTERNAL] ) }
      scope :non_public_only,           -> { where.not(visibility_level: PUBLIC) }

      scope :public_to_user, -> (user = nil) do
        where(visibility_level: VisibilityLevel.levels_for_user(user))
      end
    end

    PRIVATE  = 0 unless const_defined?(:PRIVATE)
    INTERNAL = 10 unless const_defined?(:INTERNAL)
    PUBLIC   = 20 unless const_defined?(:PUBLIC)

    class << self
      delegate :values, to: :options

      def levels_for_user(user = nil)
        return [PUBLIC] unless user

        if user.can_read_all_resources?
          [PRIVATE, INTERNAL, PUBLIC]
        elsif user.external?
          [PUBLIC]
        else
          [INTERNAL, PUBLIC]
        end
      end

      def string_values
        string_options.keys
      end

      def options
        {
          N_('VisibilityLevel|Private')  => PRIVATE,
          N_('VisibilityLevel|Internal') => INTERNAL,
          N_('VisibilityLevel|Public')   => PUBLIC
        }
      end

      def string_options
        {
          'private'  => PRIVATE,
          'internal' => INTERNAL,
          'public'   => PUBLIC
        }
      end

      def allowed_levels
        restricted_levels = Gitlab::CurrentSettings.restricted_visibility_levels

        self.values - Array(restricted_levels)
      end

      def closest_allowed_level(target_level)
        highest_allowed_level = allowed_levels.select { |level| level <= target_level }.max

        # If all levels are restricted, fall back to PRIVATE
        highest_allowed_level || PRIVATE
      end

      def allowed_for?(user, level)
        user.admin? || allowed_level?(level.to_i)
      end

      # Level should be a numeric value, e.g. `20`
      # Return true if the specified level is allowed for the current user.
      def allowed_level?(level)
        valid_level?(level) && non_restricted_level?(level)
      end

      def non_restricted_level?(level)
        !restricted_level?(level)
      end

      def restricted_level?(level)
        restricted_levels = Gitlab::CurrentSettings.restricted_visibility_levels

        if restricted_levels.nil?
          false
        else
          restricted_levels.include?(level)
        end
      end

      def public_visibility_restricted?
        restricted_level?(PUBLIC)
      end

      def valid_level?(level)
        options.value?(level)
      end

      def level_name(level)
        level_name = N_('VisibilityLevel|Unknown')
        options.each do |name, lvl|
          level_name = name if lvl == level.to_i
        end

        s_(level_name)
      end

      def level_value(level)
        return level.to_i if level.to_i.to_s == level.to_s && string_options.key(level.to_i)

        string_options[level] || PRIVATE
      end

      def string_level(level)
        string_options.key(level)
      end
    end

    def visibility_level_previous_changes
      previous_changes[:visibility_level]
    end

    def private?
      visibility_level_value == PRIVATE
    end

    def internal?
      visibility_level_value == INTERNAL
    end

    def public?
      visibility_level_value == PUBLIC
    end

    def visibility_level_value
      self[visibility_level_field]
    end

    def visibility
      Gitlab::VisibilityLevel.string_level(visibility_level_value)
    end

    def visibility=(level)
      self[visibility_level_field] = Gitlab::VisibilityLevel.level_value(level)
    end

    def visibility_attribute_present?(attributes)
      visibility_level_attributes.each do |attr|
        return true if attributes[attr].present?
      end

      false
    end

    def visibility_level_attributes
      [visibility_level_field, visibility_level_field.to_s,
       :visibility, 'visibility']
    end
  end
end