mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
71 lines
1.7 KiB
Ruby
71 lines
1.7 KiB
Ruby
# Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/
|
|
|
|
class Auth::Permissions
|
|
attr_reader :object, :query
|
|
|
|
def initialize(object, query)
|
|
@object = object
|
|
@query = Array(query)
|
|
end
|
|
|
|
def self.authorized?(object, query)
|
|
Auth::RequestCache.fetch_value(cache_key(object, query)) do
|
|
new(object, query).authorized?
|
|
end
|
|
rescue URI::GID::MissingModelIdError
|
|
new(object, query).authorized?
|
|
end
|
|
|
|
def self.cache_key(object, query)
|
|
object_key = object.to_global_id.to_s
|
|
query_key = Array(query).join('|')
|
|
|
|
"permissions/#{object_key}_#{query_key}"
|
|
end
|
|
private_class_method :cache_key
|
|
|
|
def authorized?
|
|
query.any? do |elem|
|
|
check_single_permission_option(elem)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def check_single_permission_option(input)
|
|
input
|
|
.split('+')
|
|
.all? do |elem|
|
|
check_single_permission_option_component(elem)
|
|
end
|
|
end
|
|
|
|
def check_single_permission_option_component(input)
|
|
if input.exclude?('.')
|
|
return permissions_cache.include?(input)
|
|
end
|
|
|
|
# See "chain-of-ancestry quirk" in spec file
|
|
if !input.end_with?('.*') && Permission.lookup(name: input)&.active == false
|
|
return
|
|
end
|
|
|
|
Permission
|
|
.with_parents(input)
|
|
.any? do |parent_or_self|
|
|
check_permission_name_in_ancestry_chain(parent_or_self)
|
|
end
|
|
end
|
|
|
|
def check_permission_name_in_ancestry_chain(input)
|
|
if input.end_with?('.*')
|
|
permissions_cache.any? { |elem| elem.starts_with?(input.delete_suffix('*')) }
|
|
else
|
|
permissions_cache.include?(input)
|
|
end
|
|
end
|
|
|
|
def permissions_cache
|
|
@permissions_cache ||= object.permissions.pluck(:name)
|
|
end
|
|
end
|