objectbouncer 0.0.3 → 0.0.4
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/README.mdown +10 -2
- data/lib/objectbouncer/base.rb +10 -9
- data/test/objectbouncer/base_test.rb +19 -0
- metadata +2 -2
data/README.mdown
CHANGED
@@ -15,6 +15,10 @@ Let's say we have a President who is protected by the SecretService:
|
|
15
15
|
def high_five
|
16
16
|
"high five!"
|
17
17
|
end
|
18
|
+
|
19
|
+
def give(gift)
|
20
|
+
"thanks"
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
And the following people:
|
@@ -46,10 +50,12 @@ To protect the President we'd define a SecretService class like so:
|
|
46
50
|
class SecretService
|
47
51
|
include ObjectBouncer::Doorman
|
48
52
|
door_policy do
|
49
|
-
deny :shake_hands,
|
53
|
+
deny :shake_hands, :if => Proc.new{|person| person.dictator? }
|
50
54
|
allow :shake_hands, :if => Proc.new{|person| person.democrat? }
|
51
|
-
deny :high_five,
|
55
|
+
deny :high_five, :unless => Proc.new{|person, president|
|
52
56
|
person.friend?(president) }
|
57
|
+
deny :give, :unless => Proc.new{|person, president, *args|
|
58
|
+
args.first == :donation }
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
@@ -66,6 +72,8 @@ the President through SecretService first:
|
|
66
72
|
SecretService.new(@tommy_chong, @president).shake_hands # Allowed
|
67
73
|
SecretService.new(@joe_biden, @president).high_five # Allowed
|
68
74
|
SecretService.new(@tommy_chong, @president).high_five # Raises PermissionDenied
|
75
|
+
SecretService.new(@gaddafi, @president).give(:donation) # Allowed
|
76
|
+
SecretService.new(@gaddafi, @president).give(:suspect_package) # Raises PermissionDenied
|
69
77
|
|
70
78
|
## Why would I want to use this?
|
71
79
|
|
data/lib/objectbouncer/base.rb
CHANGED
@@ -57,15 +57,16 @@ module ObjectBouncer
|
|
57
57
|
def initialize(accessee, object)
|
58
58
|
@accessee = accessee
|
59
59
|
@object = object
|
60
|
+
super(nil)
|
60
61
|
self
|
61
62
|
end
|
62
63
|
|
63
64
|
def method_missing(meth, *args, &block)
|
64
65
|
if respond_to?(meth)
|
65
66
|
raise "TODO!!!" if self.class.policies.nil? or self.class.policies.empty?
|
66
|
-
if call_allowed?(meth)
|
67
|
+
if call_allowed?(meth, *args)
|
67
68
|
@object.send(meth, *args, &block)
|
68
|
-
elsif call_denied?(meth)
|
69
|
+
elsif call_denied?(meth, *args)
|
69
70
|
raise ObjectBouncer::PermissionDenied.new
|
70
71
|
end
|
71
72
|
else
|
@@ -78,19 +79,19 @@ module ObjectBouncer
|
|
78
79
|
end
|
79
80
|
|
80
81
|
private
|
81
|
-
def call_allowed?(meth)
|
82
|
+
def call_allowed?(meth, *args)
|
82
83
|
if policies = self.class.policies[meth]
|
83
|
-
return true if !policies[:allow][:unless].empty? && !policies[:allow][:unless].detect{|policy| policy.call(@accessee, @object) rescue nil}
|
84
|
-
return true if policies[:allow][:if].detect{|policy| policy.call(@accessee, @object) rescue nil}
|
85
|
-
return true if policies[:deny][:unless].detect{|policy| policy.call(@accessee, @object) rescue nil}
|
84
|
+
return true if !policies[:allow][:unless].empty? && !policies[:allow][:unless].detect{|policy| policy.call(@accessee, @object, *args) rescue nil}
|
85
|
+
return true if policies[:allow][:if].detect{|policy| policy.call(@accessee, @object, *args) rescue nil}
|
86
|
+
return true if policies[:deny][:unless].detect{|policy| policy.call(@accessee, @object, *args) rescue nil}
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
|
-
def call_denied?(meth)
|
90
|
+
def call_denied?(meth, *args)
|
90
91
|
return true if self.class.lockdown?
|
91
92
|
if policies = self.class.policies[meth]
|
92
|
-
return true if policies[:allow][:unless].detect{|policy| policy.call(@accessee, @object) rescue nil}
|
93
|
-
return true if policies[:deny][:if].detect{|policy| policy.call(@accessee, @object) rescue nil}
|
93
|
+
return true if policies[:allow][:unless].detect{|policy| policy.call(@accessee, @object, *args) rescue nil}
|
94
|
+
return true if policies[:deny][:if].detect{|policy| policy.call(@accessee, @object, *args) rescue nil}
|
94
95
|
return true if !policies[:deny][:unless].empty? && !call_allowed?(meth)
|
95
96
|
end
|
96
97
|
end
|
@@ -7,6 +7,7 @@ class SecretService
|
|
7
7
|
deny :shake_hands, :if => Proc.new{|person, president| person != president}
|
8
8
|
allow :shake_hands, :if => Proc.new{|person, president| person.class == MichelleObama}
|
9
9
|
deny :high_five, :unless => Proc.new{|person, president| person.who? == "it's me, Joe!"}
|
10
|
+
deny :give, :unless => Proc.new{|person, president, *args| args.first == :campaign_donation }
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -30,6 +31,10 @@ class President
|
|
30
31
|
def watch_tv_appearance
|
31
32
|
"I'm on your TV!"
|
32
33
|
end
|
34
|
+
|
35
|
+
def give(gift)
|
36
|
+
"thanks"
|
37
|
+
end
|
33
38
|
end
|
34
39
|
|
35
40
|
class MichelleObama
|
@@ -79,6 +84,20 @@ class ObjectBouncerTest < Test::Unit::TestCase
|
|
79
84
|
end
|
80
85
|
end
|
81
86
|
|
87
|
+
should "let the public give a donation" do
|
88
|
+
joe_public = JoePublic.new
|
89
|
+
secret_service = SecretService.new(joe_public, @president)
|
90
|
+
assert_equal "thanks", secret_service.give(:campaign_donation)
|
91
|
+
end
|
92
|
+
|
93
|
+
should "not let the public give a package" do
|
94
|
+
joe_public = JoePublic.new
|
95
|
+
secret_service = SecretService.new(joe_public, @president)
|
96
|
+
assert_raise ObjectBouncer::PermissionDenied do
|
97
|
+
secret_service.give(:suspect_package)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
82
101
|
end
|
83
102
|
|
84
103
|
context "going into complete lockdown" do
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: objectbouncer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.4
|
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-03-
|
13
|
+
date: 2011-03-25 00:00:00 +00:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|