request_cache.rb 1.5 KB

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