objectbouncer 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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