objectbouncer 0.1.1 → 0.1.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.
@@ -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
- def apply_policies
29
- policies.keys.each do |method|
30
- self.class.protect_method!(method)
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.each do |method|
80
- protect_method!(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.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-12 00:00:00 +01:00
13
+ date: 2011-04-13 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies: []
16
16