visibility_level_helper.rb 7.0 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5 6
module VisibilityLevelHelper
  def visibility_level_color(level)
    case level
    when Gitlab::VisibilityLevel::PRIVATE
7
      'vs-private'
8
    when Gitlab::VisibilityLevel::INTERNAL
9
      'vs-internal'
10
    when Gitlab::VisibilityLevel::PUBLIC
11
      'vs-public'
12 13 14
    end
  end

V
Vinnie Okada 已提交
15 16
  # Return the description for the +level+ argument.
  #
17 18 19
  # +level+       One of the Gitlab::VisibilityLevel constants
  # +form_model+  Either a model object (Project, Snippet, etc.) or the name of
  #               a Project or Snippet class.
V
Vinnie Okada 已提交
20
  def visibility_level_description(level, form_model)
21 22
    case form_model
    when Project
V
Vinnie Okada 已提交
23
      project_visibility_level_description(level)
F
Felipe Artur 已提交
24 25
    when Group
      group_visibility_level_description(level)
26 27
    when Snippet
      snippet_visibility_level_description(level, form_model)
V
Vinnie Okada 已提交
28 29 30 31
    end
  end

  def project_visibility_level_description(level)
32 33
    case level
    when Gitlab::VisibilityLevel::PRIVATE
34
      _("Project access must be granted explicitly to each user.")
35
    when Gitlab::VisibilityLevel::INTERNAL
36
      _("The project can be accessed by any logged in user.")
37
    when Gitlab::VisibilityLevel::PUBLIC
38
      _("The project can be accessed without any authentication.")
V
Valery Sizov 已提交
39 40 41
    end
  end

F
Felipe Artur 已提交
42 43 44
  def group_visibility_level_description(level)
    case level
    when Gitlab::VisibilityLevel::PRIVATE
45
      _("The group and its projects can only be viewed by members.")
F
Felipe Artur 已提交
46
    when Gitlab::VisibilityLevel::INTERNAL
47
      _("The group and any internal projects can be viewed by any logged in user.")
F
Felipe Artur 已提交
48
    when Gitlab::VisibilityLevel::PUBLIC
49
      _("The group and any public projects can be viewed without any authentication.")
F
Felipe Artur 已提交
50 51 52
    end
  end

53
  def snippet_visibility_level_description(level, snippet = nil)
54 55
    case level
    when Gitlab::VisibilityLevel::PRIVATE
56
      if snippet.is_a? ProjectSnippet
57
        _("The snippet is visible only to project members.")
58
      else
59
        _("The snippet is visible only to me.")
60
      end
61
    when Gitlab::VisibilityLevel::INTERNAL
62
      _("The snippet is visible to any logged in user.")
63
    when Gitlab::VisibilityLevel::PUBLIC
64
      _("The snippet can be accessed without any authentication.")
65 66 67
    end
  end

68 69
  # Note: these messages closely mirror the form validation strings found in the project
  # model and any changes or additons to these may also need to be made there.
70 71 72
  def disallowed_project_visibility_level_description(level, project)
    level_name = Gitlab::VisibilityLevel.level_name(level).downcase
    reasons = []
73
    instructions = []
74 75

    unless project.visibility_level_allowed_as_fork?(level)
76
      reasons << "the fork source project has lower visibility"
77 78 79
    end

    unless project.visibility_level_allowed_by_group?(level)
R
Rubén Dávila 已提交
80
      errors = visibility_level_errors_for_group(project.group, level_name)
81

R
Rubén Dávila 已提交
82 83
      reasons << errors[:reason]
      instructions << errors[:instruction]
84 85 86
    end

    reasons = reasons.any? ? ' because ' + reasons.to_sentence : ''
87
    "This project cannot be #{level_name}#{reasons}.#{instructions.join}".html_safe
88 89
  end

90 91
  # Note: these messages closely mirror the form validation strings found in the group
  # model and any changes or additons to these may also need to be made there.
92 93 94
  def disallowed_group_visibility_level_description(level, group)
    level_name = Gitlab::VisibilityLevel.level_name(level).downcase
    reasons = []
95
    instructions = []
96 97

    unless group.visibility_level_allowed_by_projects?(level)
98
      reasons << "it contains projects with higher visibility"
99 100 101
    end

    unless group.visibility_level_allowed_by_sub_groups?(level)
102
      reasons << "it contains sub-groups with higher visibility"
103 104 105
    end

    unless group.visibility_level_allowed_by_parent?(level)
R
Rubén Dávila 已提交
106
      errors = visibility_level_errors_for_group(group.parent, level_name)
107

R
Rubén Dávila 已提交
108 109
      reasons << errors[:reason]
      instructions << errors[:instruction]
110 111 112
    end

    reasons = reasons.any? ? ' because ' + reasons.to_sentence : ''
113
    "This group cannot be #{level_name}#{reasons}.#{instructions.join}".html_safe
114 115
  end

D
Douwe Maan 已提交
116
  def visibility_icon_description(form_model)
117
    if form_model.respond_to?(:visibility_level_allowed_as_fork?)
D
Douwe Maan 已提交
118
      project_visibility_icon_description(form_model.visibility_level)
119
    elsif form_model.respond_to?(:visibility_level_allowed_by_sub_groups?)
D
Douwe Maan 已提交
120 121 122 123 124 125
      group_visibility_icon_description(form_model.visibility_level)
    end
  end

  def group_visibility_icon_description(level)
    "#{visibility_level_label(level)} - #{group_visibility_level_description(level)}"
D
Douwe Maan 已提交
126 127
  end

D
Douwe Maan 已提交
128
  def project_visibility_icon_description(level)
129
    "#{visibility_level_label(level)} - #{project_visibility_level_description(level)}"
D
Douwe Maan 已提交
130 131
  end

132
  def visibility_level_label(level)
133 134 135
    # The visibility level can be:
    # 'VisibilityLevel|Private', 'VisibilityLevel|Internal', 'VisibilityLevel|Public'
    s_(Project.visibility_levels.key(level))
136
  end
137

138
  def restricted_visibility_levels(show_all = false)
B
blackst0ne 已提交
139
    return [] if current_user.admin? && !show_all
140

141
    Gitlab::CurrentSettings.restricted_visibility_levels || []
142
  end
V
Vinnie Okada 已提交
143

D
Douwe Maan 已提交
144 145
  delegate  :default_project_visibility,
            :default_group_visibility,
146
            to: :'Gitlab::CurrentSettings.current_application_settings'
147

148
  def disallowed_visibility_level?(form_model, level)
149
    return false unless form_model.respond_to?(:visibility_level_allowed?)
150

151
    !form_model.visibility_level_allowed?(level)
V
Valery Sizov 已提交
152
  end
R
Rubén Dávila 已提交
153

154 155 156 157
  # Visibility level can be restricted in two ways:
  #
  # 1. The group permissions (e.g. a subgroup is private, which requires
  # all projects to be private)
158
  # 2. The global allowed visibility settings, set by the admin
159 160 161 162 163 164 165 166 167 168 169
  def selected_visibility_level(form_model, requested_level)
    requested_level =
      if requested_level.present?
        requested_level.to_i
      else
        default_project_visibility
      end

    [requested_level, max_allowed_visibility_level(form_model)].min
  end

170 171 172 173 174 175 176 177
  def multiple_visibility_levels_restricted?
    restricted_visibility_levels.many? # rubocop: disable CodeReuse/ActiveRecord
  end

  def all_visibility_levels_restricted?
    Gitlab::VisibilityLevel.values == restricted_visibility_levels
  end

R
Rubén Dávila 已提交
178 179
  private

180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
  def max_allowed_visibility_level(form_model)
    # First obtain the maximum visibility for the project or group
    current_level = max_allowed_visibility_level_by_model(form_model)

    # Now limit this by the global setting
    Gitlab::VisibilityLevel.closest_allowed_level(current_level)
  end

  def max_allowed_visibility_level_by_model(form_model)
    current_level = Gitlab::VisibilityLevel::PRIVATE

    Gitlab::VisibilityLevel.values.sort.each do |value|
      if disallowed_visibility_level?(form_model, value)
        break
      else
        current_level = value
      end
    end

    current_level
  end

R
Rubén Dávila 已提交
202
  def visibility_level_errors_for_group(group, level_name)
M
Mike Greiling 已提交
203
    group_name = link_to group.name, group_path(group)
R
Rubén Dávila 已提交
204 205
    change_visiblity = link_to 'change the visibility', edit_group_path(group)

M
Mike Greiling 已提交
206
    { reason: "the visibility of #{group_name} is #{group.visibility}",
R
Rubén Dávila 已提交
207 208
      instruction: " To make this group #{level_name}, you must first #{change_visiblity} of the parent group." }
  end
209
end