activeaclplus 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|