base_scope.rb 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. # Copyright (C) 2012-2024 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
  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. sql.push('tickets.customer_id = ?')
  25. bind.push(user.id)
  26. if user.all_organization_ids.present?
  27. Organization.where(id: user.all_organization_ids).select(&:shared).each do |organization|
  28. sql.push('tickets.organization_id = ?')
  29. bind.push(organization.id)
  30. end
  31. end
  32. end
  33. # The report permission can access all tickets.
  34. if sql.empty? && !user.permissions?('report')
  35. sql.push '0 = 1' # Forbid unlimited access for all other permissions.
  36. end
  37. scope.where sql.join(' OR '), *bind
  38. end
  39. # #resolve is UNDEFINED BEHAVIOR for the abstract base class (but not its subclasses)
  40. def respond_to?(*args)
  41. return false if args.first.to_s == 'resolve' && instance_of?(TicketPolicy::BaseScope)
  42. super
  43. end
  44. end
  45. end