objectbouncer 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
data/lib/objectbouncer/base.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'thread'
|
1
2
|
module ObjectBouncer
|
2
3
|
def self.enforce!
|
3
4
|
@enforce = true
|
@@ -25,9 +26,14 @@ module ObjectBouncer
|
|
25
26
|
@current_user ||= self.class.current_user
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
|
30
|
+
def apply_policies(key = nil)
|
31
|
+
if key && policies.keys.include?(key)
|
32
|
+
self.class.protect_method!(key, force = true)
|
33
|
+
else
|
34
|
+
policies.keys.each do |method|
|
35
|
+
self.class.protect_method!(method)
|
36
|
+
end
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
@@ -39,19 +45,16 @@ module ObjectBouncer
|
|
39
45
|
klass.extend ClassMethods
|
40
46
|
klass.overwrite_initialize
|
41
47
|
klass.instance_eval do
|
42
|
-
def method_added(name)
|
43
|
-
overwrite_initialize if name == :initialize
|
44
|
-
end
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
51
|
private
|
49
52
|
|
50
53
|
def call_denied?(meth, *args)
|
51
|
-
if enforced? && current_user.nil?
|
54
|
+
if ObjectBouncer.enforced? && current_user.nil?
|
52
55
|
raise ObjectBouncer::ArgumentError.new("You need to specify the user to execute the method as. e.g., #{self.class.to_s}.as(@some_user).#{meth.to_s}(....)")
|
53
56
|
end
|
54
|
-
return false if current_user.nil? && !enforced?
|
57
|
+
return false if current_user.nil? && !ObjectBouncer.enforced?
|
55
58
|
if meth_policies = policies[meth]
|
56
59
|
if !meth_policies[:unless].empty?
|
57
60
|
return false if meth_policies[:unless].detect{|policy| policy.call(current_user, self, *args) rescue nil}
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module ObjectBouncer
|
2
2
|
module Doorman
|
3
3
|
module ClassMethods
|
4
|
+
|
5
|
+
def ignoring_added_methods
|
6
|
+
ignoring_added_methods = @ignoring_added_methods
|
7
|
+
@ignoring_added_methods = true
|
8
|
+
yield
|
9
|
+
ensure
|
10
|
+
@ignoring_added_methods = ignoring_added_methods
|
11
|
+
end
|
12
|
+
|
13
|
+
def ignoring_added_methods?
|
14
|
+
@ignoring_added_methods
|
15
|
+
end
|
16
|
+
|
4
17
|
def overwrite_initialize
|
5
18
|
class_eval do
|
6
19
|
unless method_defined?(:objectbouncer_initialize)
|
@@ -31,10 +44,6 @@ module ObjectBouncer
|
|
31
44
|
{ :if => [], :unless => [] }
|
32
45
|
end
|
33
46
|
|
34
|
-
def enforced?
|
35
|
-
ObjectBouncer.enforced?
|
36
|
-
end
|
37
|
-
|
38
47
|
def current_user=(user)
|
39
48
|
@current_user = user
|
40
49
|
end
|
@@ -75,16 +84,21 @@ module ObjectBouncer
|
|
75
84
|
end
|
76
85
|
end
|
77
86
|
|
78
|
-
def apply_policies
|
79
|
-
policies.keys.
|
80
|
-
protect_method!(
|
87
|
+
def apply_policies(key = nil)
|
88
|
+
if key && policies.keys.include?(key)
|
89
|
+
protect_method!(key, force = true)
|
90
|
+
else
|
91
|
+
policies.keys.each do |method|
|
92
|
+
protect_method!(method)
|
93
|
+
end
|
81
94
|
end
|
82
95
|
end
|
83
96
|
|
84
|
-
def protect_method!(method)
|
97
|
+
def protect_method!(method, force = false)
|
85
98
|
renamed_method = "#{method}_without_objectbouncer".to_sym
|
86
99
|
if method_defined?(method)
|
87
100
|
return if method_defined?(renamed_method)
|
101
|
+
return if !force && method_defined?(renamed_method)
|
88
102
|
alias_method renamed_method, method
|
89
103
|
define_method method do |*args, &block|
|
90
104
|
if call_denied?(method, *args)
|
@@ -94,8 +108,18 @@ module ObjectBouncer
|
|
94
108
|
end
|
95
109
|
end
|
96
110
|
end
|
111
|
+
end
|
97
112
|
|
113
|
+
def method_added(name)
|
114
|
+
return if ignoring_added_methods?
|
115
|
+
Thread.exclusive do
|
116
|
+
ignoring_added_methods do
|
117
|
+
overwrite_initialize if name == :initialize
|
118
|
+
apply_policies(name) if policies && policies.keys.include?(name)
|
119
|
+
end
|
120
|
+
end
|
98
121
|
end
|
122
|
+
|
99
123
|
end
|
100
124
|
end
|
101
125
|
end
|
@@ -9,7 +9,12 @@ class Book < ActiveRecord::Base
|
|
9
9
|
door_policy do
|
10
10
|
deny :save, :unless => Proc.new{|person| person.is_a?(Author) }
|
11
11
|
deny :save!, :unless => Proc.new{|person| person.is_a?(Author) }
|
12
|
+
deny :destroy
|
12
13
|
end
|
14
|
+
|
15
|
+
#def destroy
|
16
|
+
# super
|
17
|
+
#end
|
13
18
|
end
|
14
19
|
|
15
20
|
class Author
|
@@ -65,6 +70,13 @@ class ActiveRecordTest < Test::Unit::TestCase
|
|
65
70
|
@book_as_reader = Book.as(@author).find(@book.id)
|
66
71
|
end
|
67
72
|
|
73
|
+
should "prevent all users from destroying (even with an overridden method)" do
|
74
|
+
@book.current_user = @author
|
75
|
+
assert_raise ObjectBouncer::PermissionDenied do
|
76
|
+
@book.destroy
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
68
80
|
should "prevent reading of individual attributes" do
|
69
81
|
end
|
70
82
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: objectbouncer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Glenn Gillen
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-13 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|