12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/erp_tech_svcs/extensions/active_record/protected_with_capabilities.rb', line 12
def protected_with_capabilities(options = {})
extend ProtectedByCapabilities::SingletonMethods
include ProtectedByCapabilities::InstanceMethods
has_many :capabilities, :as => :capability_resource
class_attribute :protect_all_instances
self.protect_all_instances = (options[:protect_all_instances].nil? ? false : options[:protect_all_instances])
scope :with_query_security, lambda{|*args|
raise ArgumentError if args.empty? || args.size > 2
user = args.first
capability_type_iids = args.second || []
capability_type_iids = [capability_type_iids] if capability_type_iids.is_a?(String)
scope_type = ScopeType.find_by_internal_identifier('query')
granted_capabilities = user.all_capabilities.where(:scope_type_id => scope_type.id).where(:capability_resource_type => self.name)
unless capability_type_iids.empty?
capability_type_ids = capability_type_iids.collect{|type| convert_capability_type(type).id }
granted_capabilities = granted_capabilities.where("capability_type_id IN (?)", capability_type_ids.join(','))
end
query = nil
granted_capabilities.each do |scope_capability|
query = query.nil? ? where(scope_capability.scope_query) : query.where(scope_capability.scope_query)
end
query
}
scope :with_instance_security, lambda{|*args|
raise ArgumentError if args.empty? || args.size > 2
user = args.first
capability_type_iids = args.second || []
capability_type_iids = [capability_type_iids] if capability_type_iids.is_a?(String)
scope_type = ScopeType.find_by_internal_identifier('instance')
granted_capabilities = user.all_capabilities.where(:scope_type_id => scope_type.id).where(:capability_resource_type => self.name)
unless capability_type_iids.empty?
capability_type_ids = capability_type_iids.collect{|type| convert_capability_type(type).id }
granted_capabilities = granted_capabilities.where("capability_type_id IN (#{capability_type_ids.join(',')})")
end
denied_capabilities = instance_capabilities.select('capabilities.id').where("capabilities.id NOT IN (#{granted_capabilities.select('capabilities.id').to_sql})")
deny_count = denied_capabilities.count
join_type = (self.protect_all_instances ? 'JOIN' : 'LEFT JOIN')
query = joins("#{join_type} capabilities AS c ON c.capability_resource_id = #{self.table_name}.id AND c.capability_resource_type = '#{self.name}'").
group(columns.collect{|c| "#{self.table_name}.#{c.name}" })
query = (deny_count == 0 ? query.where("c.id NOT IN (SELECT id FROM capabilities) OR c.id = c.id") : query.where("c.id NOT IN (SELECT id FROM capabilities) OR c.id NOT IN (#{denied_capabilities.to_sql})"))
query
}
scope :with_user_security, lambda{|*args|
raise ArgumentError if args.empty? || args.size > 2
with_instance_security(*args).with_query_security(*args)
}
end
|