active_restrictors 0.1.0 → 0.1.1
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.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
|
|