objectbouncer 0.0.1 → 0.0.2
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 -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
|