base_scope.rb 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. # Abstract base class for various "types" of ticket access.
  3. #
  4. # Do NOT instantiate directly; instead,
  5. # choose the appropriate subclass from below
  6. # (see commit message for details).
  7. class TicketPolicy < ApplicationPolicy
  8. class BaseScope < ApplicationPolicy::Scope
  9. # overwrite PunditPolicy#initialize to make `context` optional and use Ticket as default
  10. def initialize(user, context = Ticket)
  11. super
  12. end
  13. def resolve # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  14. raise NoMethodError, <<~ERR.chomp if instance_of?(TicketPolicy::BaseScope)
  15. specify an access type using a subclass of TicketPolicy::BaseScope
  16. ERR
  17. sql = []
  18. bind = []
  19. if user.permissions?('ticket.agent')
  20. sql.push('group_id IN (?)')
  21. bind.push(user.group_ids_access(self.class::ACCESS_TYPE))
  22. end
  23. if user.permissions?('ticket.customer')
  24. if user.organization&.shared
  25. sql.push('(tickets.customer_id = ? OR tickets.organization_id = ?)')
  26. bind.push(user.id, user.organization.id)
  27. else
  28. sql.push('tickets.customer_id = ?')
  29. bind.push(user.id)
  30. end
  31. end
  32. # The report permission can access all tickets.
  33. if sql.empty? && !user.permissions?('report')
  34. sql.push '0 = 1' # Forbid unlimited access for all other permissions.
  35. end
  36. scope.where sql.join(' OR '), *bind
  37. end
  38. # #resolve is UNDEFINED BEHAVIOR for the abstract base class (but not its subclasses)
  39. def respond_to?(*args)
  40. return false if args.first.to_s == 'resolve' && instance_of?(TicketPolicy::BaseScope)
  41. super(*args)
  42. end
  43. end
  44. end