1# frozen_string_literal: true 2 3class GroupChildEntity < Grape::Entity 4 include ActionView::Helpers::NumberHelper 5 include RequestAwareEntity 6 include MarkupHelper 7 8 expose :id, :name, :description, :visibility, :full_name, 9 :created_at, :updated_at, :avatar_url 10 11 expose :type do |instance| 12 type 13 end 14 15 expose :can_edit do |instance| 16 can_edit? 17 end 18 19 expose :edit_path do |instance| 20 # We know `type` will be one either `project` or `group`. 21 # The `edit_polymorphic_path` helper would try to call the path helper 22 # with a plural: `edit_groups_path(instance)` or `edit_projects_path(instance)` 23 # while our methods are `edit_group_path` or `edit_project_path` 24 public_send("edit_#{type}_path", instance) # rubocop:disable GitlabSecurity/PublicSend 25 end 26 27 expose :relative_path do |instance| 28 polymorphic_path(instance) 29 end 30 31 expose :permission do |instance| 32 membership&.human_access 33 end 34 35 # Project only attributes 36 expose :star_count, :archived, 37 if: lambda { |_instance, _options| project? } 38 39 # Group only attributes 40 expose :children_count, :parent_id, 41 unless: lambda { |_instance, _options| project? } 42 43 expose :subgroup_count, if: lambda { |group| access_group_counts?(group) } 44 45 expose :project_count, if: lambda { |group| access_group_counts?(group) } 46 47 expose :leave_path, unless: lambda { |_instance, _options| project? } do |instance| 48 leave_group_members_path(instance) 49 end 50 51 expose :can_leave, unless: lambda { |_instance, _options| project? } do |instance| 52 if membership 53 can?(request.current_user, :destroy_group_member, membership) 54 else 55 false 56 end 57 end 58 59 expose :number_users_with_delimiter, unless: lambda { |_instance, _options| project? } do |instance| 60 number_with_delimiter(instance.member_count) 61 end 62 63 expose :markdown_description do |instance| 64 markdown_description 65 end 66 67 private 68 69 def access_group_counts?(group) 70 !project? && can?(request.current_user, :read_counts, group) 71 end 72 73 # rubocop: disable CodeReuse/ActiveRecord 74 def membership 75 return unless request.current_user 76 77 @membership ||= request.current_user.members.find_by(source: object) 78 end 79 # rubocop: enable CodeReuse/ActiveRecord 80 81 def project? 82 object.is_a?(Project) 83 end 84 85 def type 86 object.class.name.downcase 87 end 88 89 def markdown_description 90 markdown_field(object, :description) 91 end 92 93 def can_edit? 94 return false unless request.respond_to?(:current_user) 95 96 if project? 97 # Avoid checking rights for each project, as it might be expensive if the 98 # user cannot read cross project. 99 can?(request.current_user, :read_cross_project) && 100 can?(request.current_user, :admin_project, object) 101 else 102 can?(request.current_user, :admin_group, object) 103 end 104 end 105end 106 107GroupChildEntity.prepend_mod_with('GroupChildEntity') 108