request_cache.rb 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. class Auth
  3. class RequestCache < ActiveSupport::CurrentAttributes
  4. attribute :permission_cache
  5. def self.permissions?(authorizable, auth_query)
  6. self.permission_cache ||= {}
  7. begin
  8. authorizable_key = authorizable.to_global_id.to_s
  9. rescue
  10. return instance.permissions?(authorizable, auth_query)
  11. end
  12. auth_query_key = Array(auth_query).join('|')
  13. self.permission_cache[authorizable_key] ||= {}
  14. self.permission_cache[authorizable_key][auth_query_key] ||= instance.permissions?(authorizable, auth_query)
  15. end
  16. def permissions?(authorizable, auth_query)
  17. verbatim, wildcards = acceptable_permissions_for(auth_query)
  18. authorizable.permissions.where(name: verbatim).then do |base_query|
  19. wildcards.reduce(base_query) do |query, name|
  20. query.or(authorizable.permissions.where('permissions.name LIKE ?', name.sub('.*', '.%')))
  21. end
  22. end.exists?
  23. end
  24. private
  25. def acceptable_permissions_for(auth_query)
  26. Array(auth_query)
  27. .reject { |name| Permission.lookup(name: name)&.active == false } # See "chain-of-ancestry quirk" in spec file
  28. .flat_map { |name| Permission.with_parents(name) }.uniq
  29. .partition { |name| name.end_with?('.*') }.reverse
  30. end
  31. end
  32. end