group_child_entity.rb 2.76 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5
class GroupChildEntity < Grape::Entity
  include ActionView::Helpers::NumberHelper
  include RequestAwareEntity
6
  include MarkupHelper
7

8 9
  expose :id, :name, :description, :visibility, :full_name,
         :created_at, :updated_at, :avatar_url
10

11
  expose :type do |instance|
12
    type
13 14
  end

15
  expose :can_edit do |instance|
16
    can_edit?
17 18
  end

19
  expose :edit_path do |instance|
20 21 22 23 24
    # We know `type` will be one either `project` or `group`.
    # The `edit_polymorphic_path` helper would try to call the path helper
    # with a plural: `edit_groups_path(instance)` or `edit_projects_path(instance)`
    # while our methods are `edit_group_path` or `edit_group_path`
    public_send("edit_#{type}_path", instance) # rubocop:disable GitlabSecurity/PublicSend
25 26
  end

27
  expose :relative_path do |instance|
28
    polymorphic_path(instance)
29 30
  end

31
  expose :permission do |instance|
32
    membership&.human_access
33 34 35
  end

  # Project only attributes
36
  expose :star_count, :archived,
37 38 39
         if: lambda { |_instance, _options| project? }

  # Group only attributes
40
  expose :children_count, :parent_id, :project_count, :subgroup_count,
41 42
         unless: lambda { |_instance, _options| project? }

43 44
  expose :leave_path, unless: lambda { |_instance, _options| project? } do |instance|
    leave_group_members_path(instance)
45 46
  end

47
  expose :can_leave, unless: lambda { |_instance, _options| project? } do |instance|
48
    if membership
49 50 51 52 53 54
      can?(request.current_user, :destroy_group_member, membership)
    else
      false
    end
  end

55 56
  expose :number_projects_with_delimiter, unless: lambda { |_instance, _options| project? } do |instance|
    number_with_delimiter(instance.project_count)
57 58
  end

59 60
  expose :number_users_with_delimiter, unless: lambda { |_instance, _options| project? } do |instance|
    number_with_delimiter(instance.member_count)
61
  end
62

63 64 65 66
  expose :markdown_description do |instance|
    markdown_description
  end

67 68
  private

69
  # rubocop: disable CodeReuse/ActiveRecord
70 71 72
  def membership
    return unless request.current_user

73
    @membership ||= request.current_user.members.find_by(source: object)
74
  end
75
  # rubocop: enable CodeReuse/ActiveRecord
76 77 78 79

  def project?
    object.is_a?(Project)
  end
80 81 82 83

  def type
    object.class.name.downcase
  end
84 85 86 87

  def markdown_description
    markdown_field(object, :description)
  end
88 89 90 91 92 93 94 95 96 97 98 99 100

  def can_edit?
    return false unless request.respond_to?(:current_user)

    if project?
      # Avoid checking rights for each project, as it might be expensive if the
      # user cannot read cross project.
      can?(request.current_user, :read_cross_project) &&
        can?(request.current_user, :admin_project, object)
    else
      can?(request.current_user, :admin_group, object)
    end
  end
101
end
102 103

GroupChildEntity.prepend_if_ee('EE::GroupChildEntity')