permissions.rb 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Auth::Permissions
  3. attr_reader :object, :query
  4. def initialize(object, query)
  5. @object = object
  6. @query = Array(query)
  7. end
  8. def self.authorized?(object, query)
  9. Auth::RequestCache.fetch_value(cache_key(object, query)) do
  10. new(object, query).authorized?
  11. end
  12. rescue URI::GID::MissingModelIdError
  13. new(object, query).authorized?
  14. end
  15. def self.cache_key(object, query)
  16. object_key = object.to_global_id.to_s
  17. query_key = Array(query).join('|')
  18. "permissions/#{object_key}_#{query_key}"
  19. end
  20. private_class_method :cache_key
  21. def authorized?
  22. query.any? do |elem|
  23. check_single_permission_option(elem)
  24. end
  25. end
  26. private
  27. def check_single_permission_option(input)
  28. input
  29. .split('+')
  30. .all? do |elem|
  31. check_single_permission_option_component(elem)
  32. end
  33. end
  34. def check_single_permission_option_component(input)
  35. if input.exclude?('.')
  36. return permissions_cache.include?(input)
  37. end
  38. # See "chain-of-ancestry quirk" in spec file
  39. if !input.end_with?('.*') && Permission.lookup(name: input)&.active == false
  40. return
  41. end
  42. Permission
  43. .with_parents(input)
  44. .any? do |parent_or_self|
  45. check_permission_name_in_ancestry_chain(parent_or_self)
  46. end
  47. end
  48. def check_permission_name_in_ancestry_chain(input)
  49. if input.end_with?('.*')
  50. permissions_cache.any? { |elem| elem.starts_with?(input.delete_suffix('*')) }
  51. else
  52. permissions_cache.include?(input)
  53. end
  54. end
  55. def permissions_cache
  56. @permissions_cache ||= object.permissions.pluck(:name)
  57. end
  58. end