activeaclplus 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -0
- data/README.rdoc +125 -49
- data/Rakefile +13 -14
- data/{generators/active_acl/templates → app}/controllers/privileges_controller.rb +1 -1
- data/{lib → app/models}/active_acl/acl.rb +5 -5
- data/{lib → app/models}/active_acl/acl_section.rb +3 -3
- data/{lib → app/models}/active_acl/controller_action.rb +1 -1
- data/{lib → app/models}/active_acl/controller_group.rb +1 -1
- data/{lib → app/models}/active_acl/privilege.rb +0 -0
- data/{lib → app/models}/active_acl/requester_group_link.rb +0 -0
- data/{lib → app/models}/active_acl/requester_link.rb +0 -0
- data/{lib → app/models}/active_acl/target_group_link.rb +0 -0
- data/{lib → app/models}/active_acl/target_link.rb +0 -0
- data/{generators/active_acl/templates/views → app/view}/privileges/_privilege_form.rhtml +0 -0
- data/{generators/active_acl/templates/views → app/view}/privileges/edit.rhtml +0 -0
- data/{generators/active_acl/templates/views → app/view}/privileges/list.rhtml +0 -0
- data/db/migrate/001_base_table_setup.rb +7 -4
- data/init.rb +7 -1
- data/lib/active_acl/acts_as_access_group.rb +17 -22
- data/lib/active_acl/acts_as_access_object.rb +41 -208
- data/lib/active_acl/base.rb +17 -0
- data/lib/active_acl/cache/memcache_adapter.rb +12 -10
- data/lib/active_acl/cache/no_cache_adapter.rb +5 -5
- data/lib/active_acl/db/active_record_adapter.rb +3 -3
- data/lib/active_acl/db/mysql_adapter.rb +2 -2
- data/lib/active_acl/grant.rb +38 -0
- data/lib/active_acl/handler/nested_set.rb +33 -0
- data/lib/active_acl/handler/object_handler.rb +250 -0
- data/lib/active_acl/load_controller_actions.rb +1 -3
- data/lib/active_acl/privilege_const_set.rb +2 -2
- data/lib/active_acl.rb +11 -5
- metadata +35 -27
- data/generators/active_acl/active_acl_generator.rb +0 -29
@@ -1,3 +1,5 @@
|
|
1
|
+
#require 'direct_handler'
|
2
|
+
|
1
3
|
module ActiveAcl #:nodoc:
|
2
4
|
module Acts #:nodoc:
|
3
5
|
module AccessObject #:nodoc:
|
@@ -6,7 +8,7 @@ module ActiveAcl #:nodoc:
|
|
6
8
|
base.extend(ClassMethods)
|
7
9
|
end
|
8
10
|
|
9
|
-
module ClassMethods
|
11
|
+
module ClassMethods
|
10
12
|
|
11
13
|
# Extend self with access object capabilites. See README for details
|
12
14
|
# on usage. Accepts the following options as a hash:
|
@@ -15,133 +17,49 @@ module ActiveAcl #:nodoc:
|
|
15
17
|
# join_table:: name of the join table
|
16
18
|
# foreign_key:: foreign key of self in the join table
|
17
19
|
# association_foreign_key:: foreign_key of the group class
|
18
|
-
# habtm:: set to <code>true</code> if the grup is joined with a habtm association.
|
20
|
+
# habtm:: set to <code>true</code> if the grup is joined with a habtm association.
|
21
|
+
# If not specified, the plugin tries to guess if the association is
|
22
|
+
# has_and_belongs_to_many or belongs_to by creating the singular form of the
|
23
|
+
# :grouped_by option and comparing it to itself: If it matches, it assumes a belongs_to association.
|
19
24
|
def acts_as_access_object(options = {})
|
20
|
-
configuration = {
|
21
|
-
:controller => ActiveAcl::OPTIONS[:default_selector_controller],
|
22
|
-
:action => ActiveAcl::OPTIONS[:default_selector_action]
|
23
|
-
}
|
24
|
-
if options[:grouped_by]
|
25
|
-
configuration[:group_class_name] = options[:grouped_by].to_s.classify
|
26
|
-
configuration[:join_table] = [name.pluralize.underscore, configuration[:group_class_name].pluralize.underscore].sort.join('_')
|
27
|
-
configuration[:foreign_key] = "#{name.underscore}_id"
|
28
|
-
configuration[:association_foreign_key] = "#{configuration[:group_class_name].underscore}_id"
|
29
|
-
configuration[:habtm] = (options[:grouped_by].to_s.demodulize.singularize != options[:grouped_by].to_s.demodulize)
|
30
|
-
end
|
31
25
|
|
32
|
-
|
26
|
+
handler=ObjectHandler.new(self,options)
|
33
27
|
|
34
|
-
ActiveAcl::ACCESS_CLASSES[self.name] =
|
28
|
+
ActiveAcl::ACCESS_CLASSES[self.name] = handler
|
35
29
|
|
36
30
|
has_many :requester_links, :as => :requester, :dependent => :delete_all, :class_name => 'ActiveAcl::RequesterLink'
|
37
31
|
has_many :requester_acls, :through => :requester_links, :source => :acl, :class_name => 'ActiveAcl::Acl'
|
38
|
-
|
32
|
+
|
39
33
|
has_many :target_links, :as => :target, :dependent => :delete_all, :class_name => 'ActiveAcl::TargetLink'
|
40
34
|
has_many :target_acls, :through => :target_links, :source => :acl, :class_name => 'ActiveAcl::Acl'
|
41
35
|
|
42
36
|
include InstanceMethods
|
43
37
|
extend SingletonMethods
|
44
|
-
|
45
|
-
|
46
|
-
x.split('::').join('/').underscore.pluralize.to_sym
|
47
|
-
end
|
48
|
-
|
38
|
+
include ActiveAcl::Acts::Grant
|
39
|
+
|
49
40
|
ActiveAcl::Acl.instance_eval do
|
50
|
-
has_many_polymorphs :requesters, {:from => from_classes,
|
41
|
+
has_many_polymorphs :requesters, {:from => ActiveAcl.from_classes,
|
51
42
|
:through => :"active_acl/requester_links",
|
52
43
|
:rename_individual_collections => true}
|
53
|
-
|
54
|
-
has_many_polymorphs :targets, {:from => from_classes,
|
44
|
+
|
45
|
+
has_many_polymorphs :targets, {:from => ActiveAcl.from_classes,
|
55
46
|
:through => :"active_acl/target_links",
|
56
|
-
:rename_individual_collections => true}
|
47
|
+
:rename_individual_collections => true}
|
57
48
|
end
|
58
|
-
|
49
|
+
|
59
50
|
self.module_eval do
|
60
51
|
# checks if method is defined to not break tests
|
61
52
|
unless instance_methods.include? "reload_before_gacl"
|
62
53
|
alias :reload_before_gacl :reload
|
63
54
|
|
64
55
|
# Redefines reload, making shure privilege caches are cleared on reload
|
65
|
-
def reload
|
56
|
+
def reload #:nodoc:
|
66
57
|
clear_cached_permissions
|
67
58
|
reload_before_gacl
|
68
59
|
end
|
69
60
|
end
|
70
61
|
end
|
71
|
-
|
72
|
-
# build ACL query strings once, so we don't need to do this on every request
|
73
|
-
requester_groups_table = configuration[:group_class_name].constantize.table_name
|
74
|
-
requester_group_type = configuration[:group_class_name].constantize.name
|
75
|
-
requester_join_table = configuration[:join_table]
|
76
|
-
requester_assoc_fk = configuration[:association_foreign_key]
|
77
|
-
requester_fk = configuration[:foreign_key]
|
78
|
-
requester_group_left = ActiveAcl::GROUP_CLASSES[configuration[:group_class_name]][:left_column].to_s
|
79
|
-
requester_group_right = ActiveAcl::GROUP_CLASSES[configuration[:group_class_name]][:right_column].to_s
|
80
|
-
requester_type = self.base_class.name
|
81
|
-
|
82
|
-
# last join is necessary to weed out rules associated with targets groups
|
83
|
-
query = <<-QUERY
|
84
|
-
SELECT acls.id, acls.allow, privileges.id AS privilege_id FROM #{ActiveAcl::OPTIONS[:acls_table]} acls
|
85
|
-
LEFT JOIN #{ActiveAcl::OPTIONS[:acls_privileges_table]} acls_privileges ON acls_privileges.acl_id=acls.id
|
86
|
-
LEFT JOIN #{ActiveAcl::OPTIONS[:privileges_table]} privileges ON privileges.id = acls_privileges.privilege_id
|
87
|
-
LEFT JOIN #{ActiveAcl::OPTIONS[:requester_links_table]} r_links ON r_links.acl_id=acls.id
|
88
|
-
LEFT JOIN #{ActiveAcl::OPTIONS[:requester_group_links_table]} r_g_links ON acls.id = r_g_links.acl_id AND r_g_links.requester_group_type = '#{requester_group_type}'
|
89
|
-
LEFT JOIN #{requester_groups_table} r_groups ON r_g_links.requester_group_id = r_groups.id
|
90
|
-
LEFT JOIN #{ActiveAcl::OPTIONS[:target_group_links_table]} t_g_links ON t_g_links.acl_id=acls.id
|
91
|
-
QUERY
|
92
|
-
|
93
|
-
acl_query_on_target = '' << query
|
94
|
-
acl_query_prefetch = '' << query
|
95
|
-
|
96
|
-
# if there are no target groups, don't bother doing the join
|
97
|
-
# else append type condition
|
98
|
-
acl_query_on_target << " AND t_g_links.target_group_type = '%{target_group_type}' "
|
99
|
-
acl_query_on_target << " LEFT JOIN #{ActiveAcl::OPTIONS[:target_links_table]} t_links ON t_links.acl_id=acls.id"
|
100
|
-
acl_query_on_target << " LEFT JOIN %{target_groups_table} t_groups ON t_groups.id=t_g_links.target_group_id"
|
101
62
|
|
102
|
-
acl_query_on_target << " WHERE acls.enabled = #{connection.quote(true)} AND (privileges.id = %{privilege_id}) "
|
103
|
-
acl_query_prefetch << " WHERE acls.enabled = #{connection.quote(true)} "
|
104
|
-
|
105
|
-
query = " AND (((r_links.requester_id=%{requester_id} ) AND (r_links.requester_type='#{requester_type}')) OR (r_g_links.requester_group_id IN "
|
106
|
-
|
107
|
-
if configuration[:habtm]
|
108
|
-
configuration[:query_group] = <<-QUERY
|
109
|
-
(SELECT DISTINCT g2.id FROM #{requester_join_table} ml
|
110
|
-
LEFT JOIN #{requester_groups_table} g1 ON ml.#{requester_assoc_fk} = g1.id CROSS JOIN #{requester_groups_table} g2
|
111
|
-
WHERE ml.#{requester_fk} = %{requester_id} AND (g2.#{requester_group_left} <= g1.#{requester_group_left} AND g2.#{requester_group_right} >= g1.#{requester_group_right})))
|
112
|
-
QUERY
|
113
|
-
else
|
114
|
-
configuration[:query_group] = <<-QUERY
|
115
|
-
(SELECT DISTINCT g2.id FROM #{requester_groups_table} g1 CROSS JOIN #{requester_groups_table} g2
|
116
|
-
WHERE g1.id = %{requester_group_id} AND (g2.#{requester_group_left} <= g1.#{requester_group_left} AND g2.#{requester_group_right} >= g1.#{requester_group_right})))
|
117
|
-
QUERY
|
118
|
-
end
|
119
|
-
|
120
|
-
query << configuration[:query_group]
|
121
|
-
query << " ) AND ( "
|
122
|
-
|
123
|
-
acl_query_on_target << query
|
124
|
-
acl_query_prefetch << query
|
125
|
-
|
126
|
-
query = "(t_links.target_id=%{target_id} AND t_links.target_type = '%{target_type}' ) OR t_g_links.target_group_id IN %{target_group_query} "
|
127
|
-
|
128
|
-
acl_query_on_target << query
|
129
|
-
acl_query_prefetch << '(t_g_links.acl_id IS NULL)) '
|
130
|
-
|
131
|
-
# The ordering is always very tricky and makes all the difference in the world.
|
132
|
-
# Order (CASE WHEN r_links.requester_type = \'Group\' THEN 1 ELSE 0 END) ASC
|
133
|
-
# should put ACLs given to specific AROs ahead of any ACLs given to groups.
|
134
|
-
# This works well for exceptions to groups.
|
135
|
-
order_by_on_target = ['(CASE WHEN r_g_links.acl_id IS NULL THEN 0 ELSE 1 END) ASC ', "r_groups.#{requester_group_left} - r_groups.#{requester_group_right} ASC",
|
136
|
-
'(CASE WHEN t_g_links.acl_id IS NULL THEN 0 ELSE 1 END) ASC', 't_groups.%{target_group_left} - t_groups.%{target_group_right} ASC', 'acls.updated_at DESC']
|
137
|
-
order_by_prefetch = ['privileges.id', '(CASE WHEN r_g_links.acl_id IS NULL THEN 0 ELSE 1 END) ASC ', "r_groups.#{requester_group_left} - r_groups.#{requester_group_right} ASC", 'acls.updated_at DESC']
|
138
|
-
|
139
|
-
acl_query_on_target << 'ORDER BY ' + order_by_on_target.join(',') + ' LIMIT 1'
|
140
|
-
acl_query_prefetch << 'ORDER BY ' + order_by_prefetch.join(',')
|
141
|
-
|
142
|
-
# save query string to configuration
|
143
|
-
configuration[:query_target] = acl_query_on_target.gsub(/\n+/, "\n")
|
144
|
-
configuration[:query_simple] = acl_query_prefetch.gsub(/\n+/, "\n")
|
145
63
|
end
|
146
64
|
end
|
147
65
|
|
@@ -158,121 +76,36 @@ module ActiveAcl #:nodoc:
|
|
158
76
|
# Option :on defines the target object.
|
159
77
|
def has_privilege?(privilege, options = {})
|
160
78
|
target = options[:on] #TODO: add error handling if not a hash
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
166
|
-
|
167
|
-
unless (target.nil? or (target.class.respond_to?(:base_class) and ActiveAcl::ACCESS_CLASSES.has_key?(target.class.base_class.name)))
|
168
|
-
# no need to check anything if target is no Access Object
|
169
|
-
return false
|
170
|
-
end
|
79
|
+
# no need to check anything if privilege is not a Privilege
|
80
|
+
raise "first Argument has to be a Privilege" unless privilege.is_a?(Privilege)
|
81
|
+
# no need to check anything if target is no Access Object
|
82
|
+
raise "target hast to be an AccessObject" if target and !(target.class.respond_to?(:base_class) and ActiveAcl::ACCESS_CLASSES.has_key?(target.class.base_class.name))
|
171
83
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
return false
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
if value.nil? # still a cache miss?
|
192
|
-
|
193
|
-
value = false
|
194
|
-
|
195
|
-
r_config = ActiveAcl::ACCESS_CLASSES[self.class.base_class.name]
|
196
|
-
|
197
|
-
if target
|
198
|
-
qry = r_config[:query_target].clone
|
199
|
-
|
200
|
-
t_config = ActiveAcl::ACCESS_CLASSES[target.class.base_class.name]
|
201
|
-
|
202
|
-
qry.gsub!('%{target_group_type}', t_config[:group_class_name])
|
203
|
-
qry.gsub!('%{target_groups_table}', t_config[:group_class_name].constantize.table_name)
|
204
|
-
qry.gsub!('%{target_group_left}', ActiveAcl::GROUP_CLASSES[t_config[:group_class_name]][:left_column].to_s)
|
205
|
-
qry.gsub!('%{target_group_right}', ActiveAcl::GROUP_CLASSES[t_config[:group_class_name]][:right_column].to_s)
|
206
|
-
qry.gsub!('%{target_type}', target.class.base_class.name)
|
207
|
-
qry.gsub!('%{target_id}', target.id.to_s)
|
208
|
-
|
209
|
-
group_query = t_config[:query_group].clone
|
210
|
-
group_query.gsub!('%{requester_id}', target.id.to_s)
|
211
|
-
group_query.gsub!('%{requester_group_id}', target.send(t_config[:association_foreign_key]).to_s) unless t_config[:habtm]
|
212
|
-
|
213
|
-
qry.gsub!('%{target_group_query}', group_query)
|
214
|
-
else
|
215
|
-
qry = r_config[:query_simple].clone
|
216
|
-
end
|
217
|
-
|
218
|
-
# substitute variables
|
219
|
-
qry.gsub!('%{requester_id}', self.id.to_s)
|
220
|
-
qry.gsub!('%{privilege_id}', privilege.id.to_s)
|
221
|
-
qry.gsub!('%{requester_group_id}', self.send(r_config[:association_foreign_key]).to_s) unless r_config[:habtm]
|
222
|
-
results = ActiveAcl::OPTIONS[:db].query(qry)
|
223
|
-
|
224
|
-
if target.nil?
|
225
|
-
# prefetch privileges
|
226
|
-
privilegevalue = nil
|
227
|
-
@gacl_instance_cache = {}
|
228
|
-
|
229
|
-
results.each do |row|
|
230
|
-
if row['privilege_id'] != privilegevalue
|
231
|
-
privilegevalue = row['privilege_id']
|
232
|
-
c_id = [privilegevalue, self.class.base_class.name, id, '', ''].join('-')
|
233
|
-
@gacl_instance_cache[c_id] = ((row['allow'] == '1') or (row['allow'] == 't'))
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
value = @gacl_instance_cache[query_id]
|
238
|
-
@gacl_instance_cache[:prefetch_done] = true
|
239
|
-
|
240
|
-
elsif not results.empty?
|
241
|
-
# normal gacl query without prefetching
|
242
|
-
value = ((results[0]['allow'].to_s == '1') or (results[0]['allow'].to_s == 't'))
|
243
|
-
@gacl_instance_cache ||= {} # create if not exists
|
244
|
-
|
245
|
-
@gacl_instance_cache[query_id] = value
|
246
|
-
end
|
247
|
-
|
248
|
-
# nothing found, deny access
|
249
|
-
@gacl_instance_cache[query_id] = value = false if value.nil?
|
250
|
-
|
251
|
-
# save to second level cache
|
252
|
-
cache.set(cache_id, @gacl_instance_cache, ActiveAcl::OPTIONS[:cache_privilege_timeout])
|
253
|
-
|
254
|
-
logger.debug 'GACL::INSTANCE_CACHE::' + (value ? 'GRANT ' : 'DENY ') + query_id if logger.debug?
|
255
|
-
|
256
|
-
end # cache miss
|
257
|
-
return value
|
84
|
+
active_acl_handler.has_privilege?(self,privilege,target)
|
85
|
+
end
|
86
|
+
def active_acl_handler
|
87
|
+
ActiveAcl::ACCESS_CLASSES[self.class.name]
|
88
|
+
end
|
89
|
+
#returns a key value store
|
90
|
+
def active_acl_instance_cache
|
91
|
+
@active_acl_instance_cache ||= active_acl_handler.get_instance_cache(self)
|
92
|
+
end
|
93
|
+
#returns if the 2d acls are already cached
|
94
|
+
def active_acl_cached_2d?
|
95
|
+
!!active_acl_instance_cache[:prefetched_2d]
|
96
|
+
end
|
97
|
+
def active_acl_cached_2d!
|
98
|
+
active_acl_instance_cache[:prefetched_2d]=true
|
258
99
|
end
|
259
100
|
|
101
|
+
def active_acl_clear_cache!
|
102
|
+
@active_acl_instance_cache ={} #clear the lokal cache
|
103
|
+
active_acl_handler.delete_cached(self) #clear the 2 level cache
|
104
|
+
end
|
260
105
|
# override this to customize the description in the interface
|
261
106
|
def active_acl_description
|
262
107
|
to_s
|
263
108
|
end
|
264
|
-
|
265
|
-
# link to model selector
|
266
|
-
def self.model_selector_link params
|
267
|
-
AclsController.url_for(:action => :show_group_members, :clazz => self.class, *params)
|
268
|
-
end
|
269
|
-
|
270
|
-
# clears the permission caches (instance and memory cache)
|
271
|
-
def clear_cached_permissions
|
272
|
-
@gacl_instance_cache = nil
|
273
|
-
ActiveAcl::OPTIONS[:cache].delete('gacl_instance-' + self.class.name + '-' + id.to_s)
|
274
|
-
end
|
275
|
-
|
276
109
|
end
|
277
110
|
end
|
278
111
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActiveAcl
|
2
|
+
CONTROLLERS={}
|
3
|
+
GROUP_CLASSES={}
|
4
|
+
ACCESS_CLASSES={}
|
5
|
+
|
6
|
+
def self.is_access_group?(klass)
|
7
|
+
!!ActiveAcl::GROUP_CLASSES[klass.name]
|
8
|
+
end
|
9
|
+
def self.is_access_object?(klass)
|
10
|
+
!!ActiveAcl::ACCESS_CLASSES[klass.name]
|
11
|
+
end
|
12
|
+
def self.from_classes
|
13
|
+
ActiveAcl::ACCESS_CLASSES.keys.collect do |x|
|
14
|
+
x.split('::').join('/').underscore.pluralize.to_sym
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,43 +1,45 @@
|
|
1
1
|
# This is a cache adapter for the second level cache
|
2
2
|
# using the memcache daemon (http://www.danga.com/memcached).
|
3
3
|
# Sets itself as the cache adapter if the source file is loaded so a simple
|
4
|
-
# require is enough to activate the memcache. Before using the memcache, make
|
4
|
+
# require is enough to activate the memcache. Before using the memcache, make sure to set MemcacheAdapter.cache.
|
5
5
|
#
|
6
6
|
# In environment.rb:
|
7
7
|
# require 'active_acl/cache/memcache_adapter'
|
8
8
|
# ActiveAcl::Cache::MemcacheAdapter.cache = MemCache.new('localhost:11211', :namespace => 'my_namespace')
|
9
|
-
#
|
9
|
+
# you can also set the time to leave:
|
10
|
+
# ActiveAcl::OPTIONS[:cache_privilege_timeout]= time_in_seconds
|
11
|
+
#
|
10
12
|
# Detailed instructions on how to set up the server can be found at http://dev.robotcoop.com/Libraries/memcache-client.
|
11
13
|
class ActiveAcl::Cache::MemcacheAdapter
|
12
14
|
|
13
15
|
# returns the memcache server
|
14
|
-
def self.cache
|
16
|
+
def self.cache #:nodoc:
|
15
17
|
@@cache
|
16
18
|
end
|
17
19
|
|
18
20
|
# sets the memcache server
|
19
|
-
def self.cache=
|
21
|
+
def self.cache=(cache) #:nodoc:
|
20
22
|
@@cache = cache
|
21
23
|
end
|
22
24
|
|
23
25
|
# get a value from the cache
|
24
|
-
def self.get(key)
|
26
|
+
def self.get(key) #:nodoc:
|
25
27
|
value = @@cache.get(key)
|
26
|
-
|
28
|
+
Rails.logger.debug 'GACL::SECOND_LEVEL_CACHE::' + (value.nil? ? 'MISS ' : 'HIT ')+ key.to_s
|
27
29
|
value
|
28
30
|
end
|
29
31
|
|
30
32
|
# set a value to the cache, specifying the time to live (ttl).
|
31
33
|
# Set ttl to 0 for unlimited.
|
32
|
-
def self.set(key, value, ttl)
|
34
|
+
def self.set(key, value, ttl) #:nodoc:
|
33
35
|
@@cache.set(key, value, ttl)
|
34
|
-
|
36
|
+
Rails.logger.debug 'GACL::SECOND_LEVEL_CACHE::SET ' + key.to_s + ' TO ' + value.inspect.to_s + ' TTL ' + ttl.to_s
|
35
37
|
end
|
36
38
|
|
37
39
|
# purge data from cache.
|
38
|
-
def self.delete(key)
|
40
|
+
def self.delete(key) #:nodoc:
|
39
41
|
@@cache.delete(key)
|
40
|
-
|
42
|
+
Rails.logger.debug 'GACL::SECOND_LEVEL_CACHE::DELETE ' + key.to_s
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -1,22 +1,22 @@
|
|
1
1
|
# This module contains different second level cache implementations. The second
|
2
2
|
# level cache caches the instance cache of an access object between requests.
|
3
3
|
# Cache adapter can be set with ActiveAcl::OPTIONS[:cache].
|
4
|
-
module ActiveAcl::Cache
|
4
|
+
module ActiveAcl::Cache #:nodoc:
|
5
5
|
|
6
6
|
# The default second level cache dummy implementation, not implementing any
|
7
7
|
# caching functionality at all.
|
8
|
-
class NoCacheAdapter
|
8
|
+
class NoCacheAdapter #:nodoc:
|
9
9
|
def self.get(key)
|
10
|
-
|
10
|
+
Rails.logger.debug 'ACTIVE_ACL::SECOND_LEVEL_CACHE::DISABLED::MISS ' + key.to_s
|
11
11
|
nil
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.set(key, value, ttl)
|
15
|
-
|
15
|
+
Rails.logger.debug 'ACTIVE_ACL::SECOND_LEVEL_CACHE::DISABLED::SET ' + key.to_s + ' TO ' + value.inspect + ' TTL ' + ttl.to_s
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.delete(key)
|
19
|
-
|
19
|
+
Rails.logger.debug 'ACTIVE_ACL::SECOND_LEVEL_CACHE::DISABLED::DELETE ' + key.to_s
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# Includes different DBMS adapters, some of them using C extensions to speed up DB access.
|
2
2
|
# DB adapter can be set with ActiveAcl::OPTIONS[:db].
|
3
|
-
module ActiveAcl::DB
|
3
|
+
module ActiveAcl::DB #:nodoc:
|
4
4
|
|
5
5
|
# Uses ActiveRecord for privilege queries. Should be compatible to all
|
6
6
|
# db types.
|
7
|
-
class ActiveRecordAdapter
|
7
|
+
class ActiveRecordAdapter #:nodoc:
|
8
8
|
# Execute sql query against the DB, returning an array of results.
|
9
|
-
def self.query(sql)
|
9
|
+
def self.query(sql)
|
10
10
|
ActiveRecord::Base.connection.select_all(sql)
|
11
11
|
end
|
12
12
|
end
|
@@ -8,11 +8,11 @@ end
|
|
8
8
|
# Uses the native MySQL connection to do privilege selects. Should be around 20 % faster than
|
9
9
|
# ActiveRecord adapter. Sets itself as the DB adapter if the source file is loaded, so requiring it
|
10
10
|
# is enough to get it activated.
|
11
|
-
class ActiveAcl::DB::MySQLAdapter
|
11
|
+
class ActiveAcl::DB::MySQLAdapter #:nodoc:
|
12
12
|
|
13
13
|
# Execute sql query against the DB, returning an array of results.
|
14
14
|
def self.query(sql)
|
15
|
-
|
15
|
+
Rails.logger.debug 'GACL::DB::EXECUTING QUERY ' + sql if Rails.logger.debug?
|
16
16
|
connection = ActiveRecord::Base.connection.connection
|
17
17
|
connection.query_with_result = true
|
18
18
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ActiveAcl
|
2
|
+
module Acts
|
3
|
+
module Grant
|
4
|
+
# grant_permission!(Blog::DELETE,
|
5
|
+
# :on => blog,
|
6
|
+
# :section_name => 'blogging'
|
7
|
+
# :acl_name => 'blogging_of_admins'
|
8
|
+
def grant_permission!(privilege,options={})
|
9
|
+
section_name = options[:section_name] || 'generic'
|
10
|
+
target = options[:on]
|
11
|
+
iname = options[:acl_name] || "#{privilege.active_acl_description}"
|
12
|
+
acl=nil
|
13
|
+
ActiveAcl::Acl.transaction do
|
14
|
+
section = ActiveAcl::AclSection.find_or_create_by_iname(section_name)
|
15
|
+
section.save! if section.new_record?
|
16
|
+
acl = ActiveAcl::Acl.create :section => section,:iname => iname
|
17
|
+
acl.save!
|
18
|
+
|
19
|
+
acl.privileges << privilege
|
20
|
+
if ActiveAcl.is_access_group?(self.class)
|
21
|
+
acl.requester_groups << self
|
22
|
+
else
|
23
|
+
acl.requesters << self
|
24
|
+
end
|
25
|
+
if target
|
26
|
+
if ActiveAcl.is_access_group?(target.class)
|
27
|
+
acl.target_groups << target
|
28
|
+
else
|
29
|
+
acl.targets << target
|
30
|
+
end
|
31
|
+
end
|
32
|
+
active_acl_clear_cache! if ActiveAcl.is_access_object?(self.class)
|
33
|
+
end
|
34
|
+
acl
|
35
|
+
end
|
36
|
+
end #module
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActiveAcl
|
2
|
+
module Acts #:nodoc:
|
3
|
+
module AccessGroup #:nodoc:
|
4
|
+
class NestedSet #:nodoc:
|
5
|
+
attr_reader :left_column,:right_column
|
6
|
+
def initialize(options)
|
7
|
+
|
8
|
+
@left_column = options[:left_column] || :lft
|
9
|
+
@right_column = options[:right_column] || :rgt
|
10
|
+
# :controller => ActiveAcl::OPTIONS[:default_group_selector_controller],
|
11
|
+
# :action => ActiveAcl::OPTIONS[:default_group_selector_action]}
|
12
|
+
|
13
|
+
end
|
14
|
+
def group_sql(object_handler,target = false)
|
15
|
+
target_requester = (target ? 'target' : 'requester')
|
16
|
+
if object_handler.habtm?
|
17
|
+
"(SELECT DISTINCT g2.id FROM #{object_handler.join_table} ml
|
18
|
+
LEFT JOIN #{object_handler.group_table_name} g1 ON ml.#{object_handler.association_foreign_key} = g1.id CROSS JOIN #{object_handler.group_table_name} g2
|
19
|
+
WHERE ml.#{object_handler.foreign_key} = %{#{target_requester}_id} AND (g2.#{left_column} <= g1.#{left_column} AND g2.#{right_column} >= g1.#{right_column}))"
|
20
|
+
else
|
21
|
+
"(SELECT DISTINCT g2.id FROM #{object_handler.group_table_name} g1 CROSS JOIN #{object_handler.group_table_name} g2
|
22
|
+
WHERE g1.id = %{#{target_requester}_group_id} AND (g2.#{left_column} <= g1.#{left_column} AND g2.#{right_column} >= g1.#{right_column}))"
|
23
|
+
end
|
24
|
+
#"r_groups.#{left_column} - r_groups.#{right_column} ASC"
|
25
|
+
end
|
26
|
+
def order_by(object_handler,target=false)
|
27
|
+
target_requester = (target ? 't' : 'r')
|
28
|
+
"#{target_requester}_groups.#{left_column} - #{target_requester}_groups.#{right_column} ASC"
|
29
|
+
end
|
30
|
+
end #class
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|