stonewall 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/rails/active_record.rb +21 -1
- data/lib/stonewall/access_violation_exception.rb +5 -0
- data/lib/stonewall/helpers.rb +1 -1
- data/lib/stonewall/parser.rb +12 -2
- data/lib/stonewall/stonewall.rb +12 -4
- data/lib/stonewall.rb +1 -0
- data/test/helper.rb +30 -0
- data/test/test_active_record_extensions.rb +30 -1
- data/test/test_guarded_collection.rb +23 -0
- metadata +21 -10
- data/.gitignore +0 -21
data/Rakefile
CHANGED
@@ -10,10 +10,10 @@ begin
|
|
10
10
|
gem.email = "dbock@codesherpas.com"
|
11
11
|
gem.homepage = "http://github.com/bokmann/stonewall"
|
12
12
|
gem.authors = ["bokmann"]
|
13
|
-
gem.add_dependency('activerecord','>= 2.0.0')
|
13
|
+
gem.add_dependency('activerecord', '>= 2.0.0', '< 2.4.0')
|
14
14
|
gem.add_dependency('sentient_user','>= 0.1.0')
|
15
15
|
|
16
|
-
gem.add_development_dependency "
|
16
|
+
gem.add_development_dependency "shoulda", ">= 2.11.3"
|
17
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
18
|
end
|
19
19
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.1
|
data/lib/rails/active_record.rb
CHANGED
@@ -3,7 +3,16 @@ ActiveRecord::Base.class_eval do
|
|
3
3
|
def method_missing_with_stonewall(symb, *args)
|
4
4
|
method_name = symb.to_s
|
5
5
|
if method_name =~ /^may_(.+?)[\!\?]$/
|
6
|
-
|
6
|
+
guard = $1
|
7
|
+
if guard.ends_with?("_any")
|
8
|
+
guard = guard.gsub("_any", "")
|
9
|
+
args.first.any?{ |o| o.class.stonewall.actions[guard.to_sym].call(o, self) }
|
10
|
+
elsif guard.ends_with?("_all")
|
11
|
+
guard = guard.gsub("_all", "")
|
12
|
+
args.first.all?{ |o| o.class.stonewall.actions[guard.to_sym].call(o, self) }
|
13
|
+
else
|
14
|
+
args.first.class.stonewall.actions[guard.to_sym].call(args.first, self)
|
15
|
+
end
|
7
16
|
else
|
8
17
|
method_missing_without_stonewall(symb, *args)
|
9
18
|
end
|
@@ -15,6 +24,15 @@ ActiveRecord::Base.class_eval do
|
|
15
24
|
# need to fix the update_attributes, read_attribute, and write_attribute problem here.
|
16
25
|
|
17
26
|
def update_attributes_with_stonewall(*args)
|
27
|
+
if respond_to?(:stonewall)
|
28
|
+
args[0].keys.each do |attribute|
|
29
|
+
attribute = attribute.to_sym unless attribute.class == Symbol
|
30
|
+
|
31
|
+
if stonewall.guarded_attributes.include?(attribute)
|
32
|
+
raise Stonewall::AccessViolationException.new " \n User id: #{User.current.id}\n User role info: #{User.current.stonewall_role_info}\n Number of Roles for User: #{User.current.stonewall_role_info.length}\n Class: #{self.class.name}\n Object id: #{self.id}\n Method: #{attribute}=" unless allowed?((attribute.to_s + "=").to_sym)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
18
36
|
update_attributes_without_stonewall(*args)
|
19
37
|
end
|
20
38
|
alias_method_chain :update_attributes, :stonewall
|
@@ -23,4 +41,6 @@ ActiveRecord::Base.class_eval do
|
|
23
41
|
# it is intentional that we are not blocking read_attribute and write_attribute methods.
|
24
42
|
# These are rare in real world rails apps, and where they are being used, permissions
|
25
43
|
# would generally be a hinderance.
|
44
|
+
|
45
|
+
|
26
46
|
end
|
data/lib/stonewall/helpers.rb
CHANGED
@@ -54,7 +54,7 @@ module StoneWall
|
|
54
54
|
if stonewall.allowed?(self, User.current, m)
|
55
55
|
self.send(unchecked_method, *args)
|
56
56
|
else
|
57
|
-
raise "
|
57
|
+
raise Stonewall::AccessViolationException.new " \n User id: #{User.current.id}\n User Role Info: #{User.current.stonewall_role_info}\n Number of Roles for User: #{User.current.stonewall_role_info.length}\n Class: #{self.class.name}\n Object id: #{self.id}\n Method: #{checked_method}"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
# -------------- end of bizzaro meta-juju
|
data/lib/stonewall/parser.rb
CHANGED
@@ -12,7 +12,7 @@ module StoneWall
|
|
12
12
|
@parent.stonewall.add_grant(@role, @variant, m)
|
13
13
|
end
|
14
14
|
else
|
15
|
-
@parent.stonewall.add_grant(@role, @variant,
|
15
|
+
@parent.stonewall.add_grant(@role, @variant, allowed)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -28,7 +28,17 @@ module StoneWall
|
|
28
28
|
def action(action_name, &guard)
|
29
29
|
@parent.stonewall.actions[action_name] = guard
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
|
+
def guard_aasm_events
|
33
|
+
@parent.aasm_events.keys.each do |event|
|
34
|
+
@parent.stonewall.actions[event] = Proc.new { |object, user|
|
35
|
+
User.do_as(user) {
|
36
|
+
object.send(("may_" + event.to_s + "?").to_sym)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
def role(role_name)
|
33
43
|
yield Parser.new(@parent, role_name)
|
34
44
|
end
|
data/lib/stonewall/stonewall.rb
CHANGED
@@ -12,7 +12,15 @@ module StoneWall
|
|
12
12
|
"/user_extensions.rb"
|
13
13
|
cattr_accessor :stonewall
|
14
14
|
self.stonewall = StoneWall::AccessController.new(self)
|
15
|
-
|
15
|
+
parser = StoneWall::Parser.new(self)
|
16
|
+
yield parser
|
17
|
+
|
18
|
+
# if we are being used with acts_as_state_machine (at least, our patched
|
19
|
+
# version), then we also want the on_transition guards to function as
|
20
|
+
# action guards in stonewall.
|
21
|
+
if self.respond_to?(:aasm_events)
|
22
|
+
parser.guard_aasm_events
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
# --------------
|
@@ -23,9 +31,9 @@ module StoneWall
|
|
23
31
|
define_attribute_methods_without_stonewall
|
24
32
|
StoneWall::Helpers.fix_aliases_for(self) # if a stonewall enhanced class?
|
25
33
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
34
|
+
|
35
|
+
unless respond_to?(:define_attribute_methods_without_stonewall)
|
36
|
+
class << self
|
29
37
|
alias_method_chain :define_attribute_methods, :stonewall
|
30
38
|
end
|
31
39
|
end
|
data/lib/stonewall.rb
CHANGED
@@ -3,5 +3,6 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
3
3
|
$:.include?(File.expand_path(File.dirname(__FILE__)))
|
4
4
|
|
5
5
|
require File.expand_path(File.dirname(__FILE__)) + "/stonewall/stonewall.rb"
|
6
|
+
require File.expand_path(File.dirname(__FILE__)) + "/stonewall/access_violation_exception.rb"
|
6
7
|
require File.expand_path(File.dirname(__FILE__)) + "/stonewall/user_extensions.rb"
|
7
8
|
require 'rails/active_record'
|
data/test/helper.rb
CHANGED
@@ -10,3 +10,33 @@ require 'stonewall'
|
|
10
10
|
|
11
11
|
class Test::Unit::TestCase
|
12
12
|
end
|
13
|
+
|
14
|
+
ActiveRecord::Base.establish_connection(
|
15
|
+
:adapter => "sqlite3",
|
16
|
+
:database => ":memory:"
|
17
|
+
)
|
18
|
+
|
19
|
+
class Doodad < ActiveRecord::Base
|
20
|
+
include StoneWall
|
21
|
+
stonewall do |s|
|
22
|
+
s.action :pop do
|
23
|
+
true
|
24
|
+
end
|
25
|
+
s.action :whiz do
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
class User < ActiveRecord::Base; end
|
31
|
+
|
32
|
+
class CreateDoodads < ActiveRecord::Migration
|
33
|
+
def self.up
|
34
|
+
create_table :doodads do |t|
|
35
|
+
t.string :thingy
|
36
|
+
end
|
37
|
+
create_table :users do |t|
|
38
|
+
t.string :name
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
catch_output = CreateDoodads.up
|
@@ -9,6 +9,35 @@ class TestActiveRecordExtensions < Test::Unit::TestCase
|
|
9
9
|
should "define a method_missing_with_stonewall"
|
10
10
|
|
11
11
|
should "call a stored action when we call a non-existent 'may_' method"
|
12
|
-
|
12
|
+
|
13
13
|
should "chain method_missing"
|
14
|
+
|
15
|
+
context 'may_ methods' do
|
16
|
+
should 'call the stonewall action' do
|
17
|
+
assert User.new.may_pop?(Doodad.new)
|
18
|
+
end
|
19
|
+
should 'raise an error if the given action does not exist' do
|
20
|
+
assert_raise(NoMethodError){
|
21
|
+
User.new.may_be_awesome?(Doodad.new)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
context "ending in '_any?'" do
|
25
|
+
should 'call the stonewall action' do
|
26
|
+
doodads = Array.new
|
27
|
+
doodads << Doodad.new
|
28
|
+
doodads << Doodad.new
|
29
|
+
assert User.new.may_pop_any?(doodads)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "ending in '_all?'" do
|
34
|
+
should 'call the stonewall action' do
|
35
|
+
doodads = Array.new
|
36
|
+
doodads << Doodad.new
|
37
|
+
doodads << Doodad.new
|
38
|
+
assert User.new.may_pop_all?(doodads)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
14
43
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestGuardedCollection < Test::Unit::TestCase
|
4
|
+
|
5
|
+
should "return true just to be a bad boy until my testing is in place" do
|
6
|
+
assert true
|
7
|
+
end
|
8
|
+
|
9
|
+
context "with a homogenous collection of guarded objects" do
|
10
|
+
context "where all allow a particular action" do
|
11
|
+
should "return true with may_schpoo_any?"
|
12
|
+
should "return true with may_schpoo_all?"
|
13
|
+
end
|
14
|
+
context "where only one allows a particular action" do
|
15
|
+
should "return true with may_schpoo_any?"
|
16
|
+
should "return false with may_schpoo_all?"
|
17
|
+
end
|
18
|
+
context "where none allows a particular action" do
|
19
|
+
should "return false with may_schpoo_any?"
|
20
|
+
should "return false with may_schpoo_all?"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- bokmann
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-12-22 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -29,6 +29,13 @@ dependencies:
|
|
29
29
|
- 0
|
30
30
|
- 0
|
31
31
|
version: 2.0.0
|
32
|
+
- - <
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
segments:
|
35
|
+
- 2
|
36
|
+
- 4
|
37
|
+
- 0
|
38
|
+
version: 2.4.0
|
32
39
|
type: :runtime
|
33
40
|
version_requirements: *id001
|
34
41
|
- !ruby/object:Gem::Dependency
|
@@ -46,15 +53,17 @@ dependencies:
|
|
46
53
|
type: :runtime
|
47
54
|
version_requirements: *id002
|
48
55
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
56
|
+
name: shoulda
|
50
57
|
prerelease: false
|
51
58
|
requirement: &id003 !ruby/object:Gem::Requirement
|
52
59
|
requirements:
|
53
60
|
- - ">="
|
54
61
|
- !ruby/object:Gem::Version
|
55
62
|
segments:
|
56
|
-
-
|
57
|
-
|
63
|
+
- 2
|
64
|
+
- 11
|
65
|
+
- 3
|
66
|
+
version: 2.11.3
|
58
67
|
type: :development
|
59
68
|
version_requirements: *id003
|
60
69
|
description: The acl from StoneWall, now as a shiny new gem!
|
@@ -68,7 +77,6 @@ extra_rdoc_files:
|
|
68
77
|
- README.rdoc
|
69
78
|
files:
|
70
79
|
- .document
|
71
|
-
- .gitignore
|
72
80
|
- LICENSE
|
73
81
|
- README.rdoc
|
74
82
|
- Rakefile
|
@@ -77,6 +85,7 @@ files:
|
|
77
85
|
- lib/rails/active_record.rb
|
78
86
|
- lib/stonewall.rb
|
79
87
|
- lib/stonewall/access_controller.rb
|
88
|
+
- lib/stonewall/access_violation_exception.rb
|
80
89
|
- lib/stonewall/helpers.rb
|
81
90
|
- lib/stonewall/parser.rb
|
82
91
|
- lib/stonewall/stonewall.rb
|
@@ -85,6 +94,7 @@ files:
|
|
85
94
|
- test/test_access_controller.rb
|
86
95
|
- test/test_active_record_extensions.rb
|
87
96
|
- test/test_guarded_class.rb
|
97
|
+
- test/test_guarded_collection.rb
|
88
98
|
- test/test_helpers.rb
|
89
99
|
- test/test_parser.rb
|
90
100
|
- test/test_stonewall.rb
|
@@ -94,8 +104,8 @@ homepage: http://github.com/bokmann/stonewall
|
|
94
104
|
licenses: []
|
95
105
|
|
96
106
|
post_install_message:
|
97
|
-
rdoc_options:
|
98
|
-
|
107
|
+
rdoc_options: []
|
108
|
+
|
99
109
|
require_paths:
|
100
110
|
- lib
|
101
111
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -124,6 +134,7 @@ test_files:
|
|
124
134
|
- test/test_access_controller.rb
|
125
135
|
- test/test_active_record_extensions.rb
|
126
136
|
- test/test_guarded_class.rb
|
137
|
+
- test/test_guarded_collection.rb
|
127
138
|
- test/test_helpers.rb
|
128
139
|
- test/test_parser.rb
|
129
140
|
- test/test_stonewall.rb
|