objectbouncer 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.mdown +10 -6
- data/lib/objectbouncer/base.rb +11 -27
- data/test/objectbouncer/base_test.rb +13 -19
- metadata +5 -15
data/README.mdown
CHANGED
@@ -61,11 +61,11 @@ the President through SecretService first:
|
|
61
61
|
@joe_biden = VicePresident.new
|
62
62
|
@tommy_chong = Hippie.new
|
63
63
|
|
64
|
-
SecretService.
|
65
|
-
SecretService.
|
66
|
-
SecretService.
|
67
|
-
SecretService.
|
68
|
-
SecretService.
|
64
|
+
SecretService.new(@gaddafi, @president).shake_hands # Raises PermissionDenied
|
65
|
+
SecretService.new(@joe_biden, @president).shake_hands # Allowed
|
66
|
+
SecretService.new(@tommy_chong, @president).shake_hands # Allowed
|
67
|
+
SecretService.new(@joe_biden, @president).high_five # Allowed
|
68
|
+
SecretService.new(@tommy_chong, @president).high_five # Raises PermissionDenied
|
69
69
|
|
70
70
|
## Why would I want to use this?
|
71
71
|
|
@@ -84,7 +84,11 @@ Test suite has currently only been confirmed on the following platforms:
|
|
84
84
|
## Contributions
|
85
85
|
|
86
86
|
Patches gladly accepted. Please fork this repo, add a relevant test, and send
|
87
|
-
me a pull request.
|
87
|
+
me a pull request. Kudos to the following for design, advice, input, etc.:
|
88
|
+
|
89
|
+
* Pedro Belo
|
90
|
+
* Ryan Smith
|
91
|
+
* Graham Ashton
|
88
92
|
|
89
93
|
## Status
|
90
94
|
|
data/lib/objectbouncer/base.rb
CHANGED
@@ -46,18 +46,6 @@ module ObjectBouncer
|
|
46
46
|
@policies
|
47
47
|
end
|
48
48
|
|
49
|
-
def as(person)
|
50
|
-
doorman = new
|
51
|
-
doorman.send(:person=, person)
|
52
|
-
doorman
|
53
|
-
end
|
54
|
-
|
55
|
-
def on(object)
|
56
|
-
doorman = new
|
57
|
-
doorman.send(:object=, object)
|
58
|
-
doorman
|
59
|
-
end
|
60
|
-
|
61
49
|
def blank_policy_template
|
62
50
|
{ :allow => { :if => [], :unless => [] },
|
63
51
|
:deny => { :if => [], :unless => [] }
|
@@ -66,19 +54,15 @@ module ObjectBouncer
|
|
66
54
|
|
67
55
|
end
|
68
56
|
|
69
|
-
def
|
57
|
+
def initialize(accessee, object)
|
58
|
+
@accessee = accessee
|
70
59
|
@object = object
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
def as(person)
|
75
|
-
@person = person
|
76
|
-
self
|
60
|
+
super
|
77
61
|
end
|
78
62
|
|
79
63
|
def method_missing(meth, *args, &block)
|
80
64
|
if respond_to?(meth)
|
81
|
-
raise "
|
65
|
+
raise "TODO!!!" if self.class.policies.nil? or self.class.policies.empty?
|
82
66
|
if call_allowed?(meth)
|
83
67
|
@object.send(meth, *args, &block)
|
84
68
|
elsif call_denied?(meth)
|
@@ -96,23 +80,23 @@ module ObjectBouncer
|
|
96
80
|
private
|
97
81
|
def call_allowed?(meth)
|
98
82
|
if policies = self.class.policies[meth]
|
99
|
-
return true if !policies[:allow][:unless].empty? && !policies[:allow][:unless].detect{|policy| policy.call(@
|
100
|
-
return true if policies[:allow][:if].detect{|policy| policy.call(@
|
101
|
-
return true if policies[:deny][:unless].detect{|policy| policy.call(@
|
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}
|
102
86
|
end
|
103
87
|
end
|
104
88
|
|
105
89
|
def call_denied?(meth)
|
106
90
|
return true if self.class.lockdown?
|
107
91
|
if policies = self.class.policies[meth]
|
108
|
-
return true if policies[:allow][:unless].detect{|policy| policy.call(@
|
109
|
-
return true if policies[:deny][:if].detect{|policy| policy.call(@
|
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}
|
110
94
|
return true if !policies[:deny][:unless].empty? && !call_allowed?(meth)
|
111
95
|
end
|
112
96
|
end
|
113
97
|
|
114
|
-
def
|
115
|
-
@
|
98
|
+
def accessee=(val)
|
99
|
+
@accessee = val
|
116
100
|
end
|
117
101
|
|
118
102
|
def object=(val)
|
@@ -53,25 +53,29 @@ class ObjectBouncerTest < Test::Unit::TestCase
|
|
53
53
|
|
54
54
|
should "not let the public shake hands" do
|
55
55
|
joe_public = JoePublic.new
|
56
|
+
secret_service = SecretService.new(joe_public, @president)
|
56
57
|
assert_raise ObjectBouncer::PermissionDenied do
|
57
|
-
|
58
|
+
secret_service.shake_hands
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
62
|
should "let the first lady get in close" do
|
62
63
|
first_lady = MichelleObama.new
|
63
|
-
|
64
|
+
secret_service = SecretService.new(first_lady, @president)
|
65
|
+
assert_equal "shaking hands", secret_service.shake_hands
|
64
66
|
end
|
65
67
|
|
66
68
|
should "high five Biden" do
|
67
69
|
vice_pres = JoeBiden.new
|
68
|
-
|
70
|
+
secret_service = SecretService.new(vice_pres, @president)
|
71
|
+
assert_equal "high five!", secret_service.high_five
|
69
72
|
end
|
70
73
|
|
71
74
|
should "not let the public high five" do
|
72
75
|
joe_public = JoePublic.new
|
76
|
+
secret_service = SecretService.new(joe_public, @president)
|
73
77
|
assert_raise ObjectBouncer::PermissionDenied do
|
74
|
-
|
78
|
+
secret_service.high_five
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
@@ -85,30 +89,20 @@ class ObjectBouncerTest < Test::Unit::TestCase
|
|
85
89
|
|
86
90
|
should "deny everything by default" do
|
87
91
|
joe_public = JoePublic.new
|
92
|
+
coast_guard = CoastGuard.new(joe_public, @president)
|
88
93
|
assert_raise ObjectBouncer::PermissionDenied do
|
89
|
-
|
94
|
+
coast_guard.high_five
|
90
95
|
end
|
91
96
|
assert_raise ObjectBouncer::PermissionDenied do
|
92
|
-
|
97
|
+
coast_guard.shake_hands
|
93
98
|
end
|
94
99
|
end
|
95
100
|
|
96
101
|
should "allow if explictly said it's ok" do
|
97
102
|
joe_public = JoePublic.new
|
98
|
-
|
103
|
+
coast_guard = CoastGuard.new(joe_public, @president)
|
104
|
+
assert_equal "I'm on your TV!", coast_guard.watch_tv_appearance
|
99
105
|
end
|
100
106
|
end
|
101
107
|
|
102
|
-
context "having a forgiving API" do
|
103
|
-
|
104
|
-
setup do
|
105
|
-
@president = President.new
|
106
|
-
end
|
107
|
-
|
108
|
-
should "let people chain methods either order" do
|
109
|
-
joe_public = JoePublic.new
|
110
|
-
assert_equal "I'm on your TV!", CoastGuard.as(joe_public).on(@president).watch_tv_appearance
|
111
|
-
assert_equal "I'm on your TV!", CoastGuard.on(@president).as(joe_public).watch_tv_appearance
|
112
|
-
end
|
113
|
-
end
|
114
108
|
end
|
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.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Glenn Gillen
|
@@ -12,19 +12,9 @@ cert_chain: []
|
|
12
12
|
|
13
13
|
date: 2011-03-07 00:00:00 +00:00
|
14
14
|
default_executable:
|
15
|
-
dependencies:
|
16
|
-
|
17
|
-
|
18
|
-
prerelease: false
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
-
none: false
|
21
|
-
requirements:
|
22
|
-
- - "="
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: 0.6.1
|
25
|
-
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
description: ""
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: A simple DSL and object proxy to restrict access to instances of your classes based on any conditional you provide
|
28
18
|
email: glenn@rubypond.com
|
29
19
|
executables: []
|
30
20
|
|
@@ -68,7 +58,7 @@ rubyforge_project:
|
|
68
58
|
rubygems_version: 1.6.0
|
69
59
|
signing_key:
|
70
60
|
specification_version: 2
|
71
|
-
summary:
|
61
|
+
summary: A simple object proxy to restrict access to methods and attributes
|
72
62
|
test_files:
|
73
63
|
- test/objectbouncer/base_test.rb
|
74
64
|
- test/test_helper.rb
|