active_restrictors 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +4 -0
- data/README.rdoc +5 -0
- data/lib/active_restrictors/active_restrictor.rb +58 -54
- data/lib/active_restrictors/version.rb +1 -1
- metadata +4 -4
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -105,4 +105,9 @@ The second is on Fubar instances:
|
|
105
105
|
|
106
106
|
- TODO
|
107
107
|
|
108
|
+
== Bugs/Features
|
108
109
|
|
110
|
+
* Please report any bugs via gihub issues
|
111
|
+
|
112
|
+
Currently 'User' is static within the code. This will be removed in the future to allow restrictors
|
113
|
+
to be applied to any two models.
|
@@ -67,10 +67,10 @@ module ActiveRestrictor
|
|
67
67
|
# hash:: Restrictor hash
|
68
68
|
# Provides class of restrictor
|
69
69
|
def restrictor_class(hash)
|
70
|
-
if(
|
71
|
-
|
70
|
+
if(hash[:class].present?)
|
71
|
+
hash[:class]
|
72
72
|
else
|
73
|
-
self.relect_on_association(
|
73
|
+
self.relect_on_association(hash[:name]).klass
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -145,65 +145,69 @@ module ActiveRestrictor
|
|
145
145
|
def self.included(klass)
|
146
146
|
# Patch up the model we have been called on
|
147
147
|
([klass] + klass.descendants).compact.each do |base|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
148
|
+
base.class_eval do
|
149
|
+
cattr_accessor :restrictors
|
150
|
+
|
151
|
+
extend ClassMethods
|
152
|
+
include InstanceMethods
|
152
153
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
154
|
+
scope :allowed_for, lambda{|*args|
|
155
|
+
user = args.detect{|item|item.is_a?(User)}
|
156
|
+
where("#{table_name}.id IN (#{user.send("allowed_#{base.name.tableize}").select(:id).to_sql})")
|
157
|
+
}
|
158
|
+
end
|
157
159
|
end
|
158
160
|
# Patch up the user to provide restricted methods
|
159
|
-
([User] + User.descendants).compact.each do
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
#
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
161
|
+
([User] + User.descendants).compact.each do |user_klass|
|
162
|
+
user_klass.class_eval do
|
163
|
+
# This patches a method onto the User instance to
|
164
|
+
# provide access to the allowed instance of the model
|
165
|
+
# in use. For example, if the restrictor module is
|
166
|
+
# included into the Fubar model, it will
|
167
|
+
# provide User#allowed_fubars
|
168
|
+
define_method("allowed_#{klass.name.tableize}") do
|
169
|
+
# First we perform a basic check against the User to see
|
170
|
+
# if this user instance is even allowed by default
|
171
|
+
user_scope = User.scoped
|
172
|
+
klass.basic_restrictors.each do |restriction|
|
173
|
+
if(restriction[:condition].is_a?(ActiveRecord::Relation))
|
174
|
+
user_scope = user_scope.merge(restriction[:condition])
|
175
|
+
elsif(restriction[:condition].respond_to?(:call))
|
176
|
+
user_scope = user_scope.merge(restriction[:condition].call)
|
177
|
+
elsif(restriction[:condition].present?)
|
178
|
+
user_scope = user_scope.where(restriction[:condition])
|
179
|
+
end
|
180
|
+
if(restriction[:include].is_a?(ActiveRecord::Relation))
|
181
|
+
user_scope = user_scope.merge(restriction[:include])
|
182
|
+
elsif(restriction[:include].present?)
|
183
|
+
user_scope = user_scope.join(restriction[:include])
|
184
|
+
end
|
181
185
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
186
|
+
if(user_scope.count > 0)
|
187
|
+
scope = klass.scoped
|
188
|
+
klass.full_restrictors.each do |restrictor|
|
189
|
+
next if restrictor[:model_custom].present?
|
190
|
+
rtable_name = restrictor[:table_name] || klass.restrictor_class(restrictor).table_name
|
191
|
+
r_scope = self.send(restrictor[:name]).scoped.select("#{rtable_name}.id")
|
192
|
+
r_scope.arel.ast.cores.first.projections.delete_at(0) # gets rid of the association_name.* rails insists upon
|
193
|
+
if(restrictor[:default_view_all])
|
194
|
+
scope = scope.includes(restrictor[:name]) if restrictor[:name].present?
|
195
|
+
else
|
196
|
+
scope = scope.joins(restrictor[:name]) if restrictor[:name].present?
|
197
|
+
end
|
198
|
+
scope = scope.where(
|
199
|
+
"#{rtable_name}.id IN (#{r_scope.to_sql})#{
|
200
|
+
" OR #{rtable_name}.id IS NULL" if restrictor[:default_view_all]
|
201
|
+
}"
|
202
|
+
)
|
194
203
|
end
|
195
|
-
|
196
|
-
"#{rtable_name}.id IN (#{r_scope.to_sql})#{
|
197
|
-
" OR #{rtable_name}.id IS NULL" if restrictor[:default_view_all]
|
198
|
-
}"
|
199
|
-
)
|
200
|
-
if((methods = klass.restrictors.find_all{|res| res[:model_custom]}).size > 0)
|
204
|
+
if((methods = klass.restrictors.map{|res| res[:model_custom]}.compact).size > 0)
|
201
205
|
scope = methods.inject(scope){|result,func| func.call(result, self)}
|
202
206
|
end
|
207
|
+
scope
|
208
|
+
else
|
209
|
+
klass.where('false')
|
203
210
|
end
|
204
|
-
scope
|
205
|
-
else
|
206
|
-
klass.where('false')
|
207
211
|
end
|
208
212
|
end
|
209
213
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_restrictors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Chris Roberts
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-09 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|