annotation_security 1.0.1

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.
Files changed (62) hide show
  1. data/CHANGELOG +2 -0
  2. data/HOW-TO +261 -0
  3. data/MIT-LICENSE +18 -0
  4. data/README +39 -0
  5. data/Rakefile +56 -0
  6. data/assets/app/helpers/annotation_security_helper.rb +9 -0
  7. data/assets/config/initializers/annotation_security.rb +12 -0
  8. data/assets/config/security/relations.rb +20 -0
  9. data/assets/config/security/rights.yml +16 -0
  10. data/assets/vendor/plugins/annotation_security/init.rb +14 -0
  11. data/bin/annotation_security +8 -0
  12. data/lib/annotation_security/exceptions.rb +125 -0
  13. data/lib/annotation_security/exec.rb +189 -0
  14. data/lib/annotation_security/filters.rb +38 -0
  15. data/lib/annotation_security/includes/action_controller.rb +144 -0
  16. data/lib/annotation_security/includes/active_record.rb +28 -0
  17. data/lib/annotation_security/includes/helper.rb +215 -0
  18. data/lib/annotation_security/includes/resource.rb +85 -0
  19. data/lib/annotation_security/includes/role.rb +31 -0
  20. data/lib/annotation_security/includes/user.rb +27 -0
  21. data/lib/annotation_security/manager/policy_factory.rb +30 -0
  22. data/lib/annotation_security/manager/policy_manager.rb +80 -0
  23. data/lib/annotation_security/manager/relation_loader.rb +273 -0
  24. data/lib/annotation_security/manager/resource_manager.rb +36 -0
  25. data/lib/annotation_security/manager/right_loader.rb +88 -0
  26. data/lib/annotation_security/model_observer.rb +61 -0
  27. data/lib/annotation_security/policy/abstract_policy.rb +345 -0
  28. data/lib/annotation_security/policy/abstract_static_policy.rb +76 -0
  29. data/lib/annotation_security/policy/all_resources_policy.rb +21 -0
  30. data/lib/annotation_security/policy/rule.rb +340 -0
  31. data/lib/annotation_security/policy/rule_set.rb +139 -0
  32. data/lib/annotation_security/rails.rb +39 -0
  33. data/lib/annotation_security/user_wrapper.rb +74 -0
  34. data/lib/annotation_security/utils.rb +142 -0
  35. data/lib/annotation_security.rb +98 -0
  36. data/lib/extensions/action_controller.rb +33 -0
  37. data/lib/extensions/active_record.rb +35 -0
  38. data/lib/extensions/filter.rb +134 -0
  39. data/lib/extensions/object.rb +11 -0
  40. data/lib/security_context.rb +551 -0
  41. data/spec/annotation_security/exceptions_spec.rb +17 -0
  42. data/spec/annotation_security/includes/helper_spec.rb +82 -0
  43. data/spec/annotation_security/manager/policy_manager_spec.rb +15 -0
  44. data/spec/annotation_security/manager/resource_manager_spec.rb +17 -0
  45. data/spec/annotation_security/manager/right_loader_spec.rb +17 -0
  46. data/spec/annotation_security/policy/abstract_policy_spec.rb +17 -0
  47. data/spec/annotation_security/policy/all_resources_policy_spec.rb +24 -0
  48. data/spec/annotation_security/policy/rule_set_spec.rb +112 -0
  49. data/spec/annotation_security/policy/rule_spec.rb +78 -0
  50. data/spec/annotation_security/policy/test_policy_spec.rb +81 -0
  51. data/spec/annotation_security/security_context_spec.rb +78 -0
  52. data/spec/annotation_security/utils_spec.rb +74 -0
  53. data/spec/helper/test_controller.rb +66 -0
  54. data/spec/helper/test_helper.rb +5 -0
  55. data/spec/helper/test_relations.rb +7 -0
  56. data/spec/helper/test_resource.rb +39 -0
  57. data/spec/helper/test_rights.yml +5 -0
  58. data/spec/helper/test_role.rb +22 -0
  59. data/spec/helper/test_user.rb +32 -0
  60. data/spec/rails_stub.rb +38 -0
  61. data/spec/spec_helper.rb +43 -0
  62. metadata +157 -0
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe AnnotationSecurity::AbstractPolicy do
4
+ # For more tests see test_policy_spec.rb
5
+
6
+ it 'should create a subclass for a resource type' do
7
+ klass = AnnotationSecurity::AbstractPolicy.new_subclass(:abs_policy_test)
8
+ (defined? AbsPolicyTestPolicy).should_not be_nil
9
+ klass.should eql(AbsPolicyTestPolicy)
10
+ klass.static?.should be_false
11
+
12
+ (defined? AbsPolicyTestStaticPolicy).should_not be_nil
13
+ klass.static_policy_class.should eql(AbsPolicyTestStaticPolicy)
14
+ klass.static_policy_class.static?.should be_true
15
+ end
16
+
17
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe AllResourcesPolicy do
4
+
5
+ it 'should provide :__self__ relation' do
6
+ user = TestUser.new
7
+ user2 = TestUser.new
8
+ policy = AllResourcesPolicy.new(user)
9
+ policy.with_resource(user).__self__?.should be_true
10
+ policy.with_resource(user.as_one_role).__self__?.should be_true
11
+ policy.with_resource(user2).__self__?.should be_false
12
+ end
13
+
14
+ it 'should provide :logged_in relation' do
15
+ AllResourcesPolicy.new(TestUser.new).logged_in?.should be_true
16
+ AllResourcesPolicy.new(nil).logged_in?.should be_false
17
+
18
+ AllResourcesPolicy.has_static_rule?(:logged_in).should be_true
19
+ AllResourcesPolicy.has_dynamic_rule?(:logged_in).should be_false
20
+ rule = AllResourcesPolicy.rule_set.get_static_rule(:logged_in)
21
+ rule.requires_credential?.should be_false
22
+ end
23
+
24
+ end
@@ -0,0 +1,112 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe AnnotationSecurity::RuleSet do
4
+
5
+ before(:all) do
6
+ AnnotationSecurity.define_relations(:rule_set_test,:rule_set_test2) do
7
+ sys_relation :system, "true"
8
+ res_relation :resource, "true"
9
+ pre_relation :pretest, "true"
10
+ end
11
+ # This rule set is not to be modified during the tests!
12
+ @rule_set2 = RuleSetTest2Policy.rule_set
13
+ end
14
+
15
+ before(:each) do
16
+ # Use a fresh rule set for each test.
17
+ # This will break some functions of RuleSet,
18
+ # in these cases @rule_set2 is used for testing.
19
+ @rule_set = AnnotationSecurity::RuleSet.new(RuleSetTestPolicy)
20
+ end
21
+
22
+ it 'should have a self explaining name' do
23
+ @rule_set.to_s.should eql('<RuleSet of RuleSetTestPolicy>')
24
+ end
25
+
26
+ it 'should manage static relations' do
27
+ rule = @rule_set.add_rule(:sys_relation, :system) { true }
28
+ rule.should be_instance_of(AnnotationSecurity::Rule)
29
+ @rule_set.get_rule(:sys_relation, true).should eql(rule)
30
+ @rule_set.get_rule(:sys_relation, false).should be_nil
31
+ end
32
+
33
+ it 'should manage dynamic relations' do
34
+ rule = @rule_set.add_rule(:res_relation, :resource) { true }
35
+ rule.should be_instance_of(AnnotationSecurity::Rule)
36
+ @rule_set.get_rule(:res_relation, false).should eql(rule)
37
+ @rule_set.get_rule(:res_relation, true).should be_nil
38
+ end
39
+
40
+ it 'should manage pretest relations' do
41
+ rule = @rule_set.add_rule(:pre_relation, :pretest) { true }
42
+ rule.should be_instance_of(AnnotationSecurity::Rule)
43
+ @rule_set.get_rule(:pre_relation, true).should eql(rule)
44
+ @rule_set.get_rule(:pre_relation, false).should eql(rule)
45
+ end
46
+
47
+ it 'should manage dynamic rights' do
48
+ rule = @rule_set.add_rule(:res_right, :right, "if res_relation")
49
+ rule.should be_instance_of(AnnotationSecurity::Rule)
50
+ @rule_set.get_rule(:res_right,false).should eql(rule)
51
+ @rule_set.get_rule(:res_right,true).should be_nil
52
+ end
53
+
54
+ it 'should manage static rights' do
55
+ rule = @rule_set.add_rule(:sys_right, :right, "if sys_relation")
56
+ rule.should be_instance_of(AnnotationSecurity::Rule)
57
+ @rule_set.get_rule(:sys_right,true).should eql(rule)
58
+ @rule_set.get_rule(:sys_right,false).should be_nil
59
+ end
60
+
61
+ it 'should manage pretest rights' do
62
+ rule = @rule_set.add_rule(:pre_right, :right, "if pre_relation")
63
+ rule.should be_instance_of(AnnotationSecurity::Rule)
64
+ @rule_set.get_rule(:pre_right,true).should eql(rule)
65
+ @rule_set.get_rule(:pre_right,false).should eql(rule)
66
+ end
67
+
68
+ it 'should be able to copy dynamic rules from other rule sets' do
69
+ rule = @rule_set.copy_rule_from(:res_relation, @rule_set2, false)
70
+ rule.should be_instance_of(AnnotationSecurity::Rule)
71
+ @rule_set.get_rule(:res_relation, false).should eql(rule)
72
+ @rule_set2.get_rule(:res_relation, false).should_not eql(rule)
73
+ end
74
+
75
+ it 'should not create dynamic copies of static rules from other rule sets' do
76
+ rule = @rule_set.copy_rule_from(:sys_relation, @rule_set2, false)
77
+ rule.should be_nil
78
+ end
79
+
80
+ it 'should be able to copy static rules from other rule sets' do
81
+ rule = @rule_set.copy_rule_from(:sys_relation, @rule_set2, true)
82
+ rule.should be_instance_of(AnnotationSecurity::Rule)
83
+ @rule_set.get_rule(:sys_relation, true).should eql(rule)
84
+ @rule_set2.get_rule(:sys_relation, true).should_not eql(rule)
85
+ end
86
+
87
+ it 'should not create static copies of dynamic rules from other rule sets' do
88
+ rule = @rule_set.copy_rule_from(:res_relation, @rule_set2, true)
89
+ rule.should be_nil
90
+ end
91
+
92
+ it 'should not allow rules with forbidden names' do
93
+ lambda {
94
+ @rule_set.add_rule(:get_rule) { }
95
+ }.should raise_error(AnnotationSecurity::RuleError)
96
+ end
97
+
98
+ it 'should not allow rules to be defined twice' do
99
+ @rule_set.add_rule(:test_rule) { }
100
+ lambda {
101
+ @rule_set.add_rule(:test_rule) { }
102
+ }.should raise_error(AnnotationSecurity::RuleError)
103
+ end
104
+
105
+ it 'should allow rules to be defined both statically and dynamically' do
106
+ r1 = @rule_set.add_rule(:test_rule, :system) { }
107
+ r2 = @rule_set.add_rule(:test_rule, :resource) { }
108
+ @rule_set.get_rule(:test_rule,true).should eql(r1)
109
+ @rule_set.get_rule(:test_rule,false).should eql(r2)
110
+ end
111
+
112
+ end
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe AnnotationSecurity::Rule do
4
+
5
+ before(:all) do
6
+ AnnotationSecurity.define_relations(:rule_test_res) do
7
+ res_dummy
8
+ sys_dummy(:system) { false }
9
+ pre_dummy :pretest
10
+ noc_dummy :system, :require_credential => false
11
+
12
+ res_dummy_test { has_res_dummy }
13
+ sys_dummy_test "if is_sys_dummy"
14
+ end
15
+ end
16
+
17
+ it 'should create valid dynamic relations' do
18
+ rule = AnnotationSecurity::Rule.new(:res_proc, RuleTestResPolicy) { |u,r| true }
19
+ rule.to_s.should == '<RuleTestResPolicy#res_proc[--du]>'
20
+ rule = AnnotationSecurity::Rule.new(:res, RuleTestResPolicy, :resource)
21
+ rule.to_s.should == '<RuleTestResPolicy#res[--du]>'
22
+ end
23
+
24
+ it 'should create valid static relations' do
25
+ rule = AnnotationSecurity::Rule.new(:sys_proc, RuleTestResPolicy, :system) { true }
26
+ rule.to_s.should == '<RuleTestResPolicy#sys_proc[-s-u]>'
27
+ end
28
+
29
+ it 'should create valid pretest relations' do
30
+ rule = AnnotationSecurity::Rule.new(:pre_proc, RuleTestResPolicy, :pretest) { true }
31
+ rule.to_s.should == '<RuleTestResPolicy#pre_proc[-sdu]>'
32
+ end
33
+
34
+ it 'should create valid relations without user' do
35
+ rule = AnnotationSecurity::Rule.new(:no_u, RuleTestResPolicy, :require_credential => false)
36
+ rule.to_s.should == '<RuleTestResPolicy#no_u[--d-]>'
37
+ rule = AnnotationSecurity::Rule.new(:no_u, RuleTestResPolicy,
38
+ :system, :require_credential => false)
39
+ rule.to_s.should == '<RuleTestResPolicy#no_u[-s--]>'
40
+ rule = AnnotationSecurity::Rule.new(:no_u, RuleTestResPolicy,
41
+ :pretest, :require_credential => false)
42
+ rule.to_s.should == '<RuleTestResPolicy#no_u[-sd-]>'
43
+ end
44
+
45
+ it 'should create valid rights' do
46
+ {
47
+ 'if res_dummy' => '-du',
48
+ 'if sys_dummy' => 's-u',
49
+ 'if pre_dummy' => 'sdu',
50
+ 'if res_dummy or sys_dummy' => '-du',
51
+ 'if res_dummy or pre_dummy' => '-du',
52
+ 'if sys_dummy or pre_dummy' => 'sdu',
53
+ 'if noc_dummy' => 's--',
54
+ 'if noc_dummy or sys_dummy' => 's-u',
55
+ 'if noc_dummy or res_dummy' => '-du',
56
+ 'if self' => '-du',
57
+ 'if other_right: resource_property' => '-du',
58
+ 'true' => 's--',
59
+ 'false or nil' => 's--'
60
+ }.each_pair do |condition,flags|
61
+ right = AnnotationSecurity::Rule.new(:right, RuleTestResPolicy, :right, condition)
62
+ right.flag_s.should == 'r???'
63
+ right.static? # trigger lazy initialization
64
+ right.flag_s.should == 'r'+flags
65
+ end
66
+ end
67
+
68
+ it 'should call referred rules when being executed' do
69
+ policy = RuleTestResPolicy.new(:user,:res)
70
+
71
+ policy.expects(:res_dummy).returns(true)
72
+ policy.res_dummy_test.should be_true
73
+
74
+ policy.expects(:sys_dummy).returns(false)
75
+ policy.sys_dummy_test?.should be_false
76
+ end
77
+
78
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ AnnotationSecurity.define_relations(:a_test) do
4
+ sys_relation :system
5
+ res_relation :resource
6
+ pre_relation :pretest
7
+ end
8
+
9
+ describe ATestPolicy do
10
+
11
+ it 'should be dynamic' do
12
+ ATestPolicy.static?.should be_false
13
+ end
14
+
15
+ it 'should have a static partner' do
16
+ ATestPolicy.static_policy_class.should eql(ATestStaticPolicy)
17
+ end
18
+
19
+ it 'should know its resource type' do
20
+ ATestPolicy.resource_type.should eql(:a_test)
21
+ end
22
+
23
+ it 'should have all rules' do
24
+ ATestPolicy.has_rule?(:sys_relation).should be_true
25
+ ATestPolicy.has_rule?(:res_relation).should be_true
26
+ ATestPolicy.has_rule?(:pre_relation).should be_true
27
+ end
28
+
29
+ it 'should be aware of the evaluation time of a rule' do
30
+ ATestPolicy.has_dynamic_rule?(:sys_relation).should be_false
31
+ ATestPolicy.has_dynamic_rule?(:res_relation).should be_true
32
+ ATestPolicy.has_dynamic_rule?(:pre_relation).should be_true
33
+
34
+ ATestPolicy.has_static_rule?(:sys_relation).should be_true
35
+ ATestPolicy.has_static_rule?(:res_relation).should be_false
36
+ ATestPolicy.has_static_rule?(:pre_relation).should be_true
37
+ end
38
+
39
+ it 'should have access to rules defined for all resources' do
40
+ ATestPolicy.has_rule?(:__self__).should be_true
41
+ ATestPolicy.has_rule?(:logged_in).should be_true
42
+ end
43
+ #
44
+ # it 'should be possible to add rules'
45
+ #
46
+ # it 'should be possible to evaluate a list of rules (static/dynamic/both)'
47
+
48
+ end
49
+
50
+ describe ATestStaticPolicy do
51
+
52
+ it 'should be static' do
53
+ ATestStaticPolicy.static?.should be_true
54
+ end
55
+
56
+ it 'should not have a static partner' do
57
+ lambda {
58
+ ATestStaticPolicy.static_policy_class
59
+ }.should raise_error(NameError)
60
+ end
61
+
62
+ it 'should know its resource type' do
63
+ ATestStaticPolicy.resource_type.should eql(:a_test)
64
+ end
65
+
66
+ it 'should use the rule set of the dynamic policy' do
67
+ ATestStaticPolicy.rule_set.should eql(ATestPolicy.rule_set)
68
+ end
69
+
70
+ it 'should have all static rules' do
71
+ ATestStaticPolicy.has_rule?(:sys_relation).should be_true
72
+ ATestStaticPolicy.has_rule?(:res_relation).should be_false
73
+ ATestStaticPolicy.has_rule?(:pre_relation).should be_true
74
+ end
75
+
76
+ it 'should have access to static rules defined for all resources' do
77
+ ATestStaticPolicy.has_rule?(:__self__).should be_false
78
+ ATestStaticPolicy.has_rule?(:logged_in).should be_true
79
+ end
80
+
81
+ end
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SecurityContext do
4
+
5
+ before(:each) do
6
+ @user1 = TestUser.new 'theuser'
7
+ @user2 = TestUser.new 'otheruser'
8
+ end
9
+
10
+ it "should check 'logged_in' for 'show'" do
11
+ request(@user1, :show, { :id => 'theuser' }).should succeed
12
+ request(@user2, :show, { :id => 'theuser' }).should succeed
13
+ request(nil, :show, { :id => 'theuser' }).should fail
14
+ end
15
+
16
+ it "should check 'owner' for 'edit'" do
17
+ request(@user1, :edit, { :id => 'theuser' }).should succeed
18
+ request(@user2, :edit, { :id => 'theuser' }).should fail
19
+ end
20
+
21
+ it "should check 'logged_in' and 'owner' for 'show_edit'" do
22
+ request(@user1, :show_edit, { :id => 'theuser' }).should succeed
23
+ request(@user2, :show_edit, { :id => 'theuser' }).should fail
24
+ end
25
+
26
+ it "should check 'owner' for 'delete' based on :id" do
27
+ request(@user1, :delete, { :id => 'theuser' }).should succeed
28
+ request(@user2, :delete, { :id => 'theuser' }).should fail
29
+ end
30
+
31
+ it "should not call action if check based on :id fails" do
32
+ TestController.expects(:enter_delete).never
33
+ request(@user2, :delete, { :id => 'theuser' }).should fail
34
+ end
35
+
36
+ it "should check 'owner' for 'list' based on @list" do
37
+ request(@user1, :list, { :id1 => 'theuser', :id2 => 'theuser' }).should succeed
38
+ request(@user1, :list, { :id1 => 'theuser', :id2 => 'otheruser' }).should fail
39
+ request(@user1, :list, { :id1 => 'otheruser', :id2 => 'theuser' }).should fail
40
+ end
41
+
42
+ it "should not be disturbed by calls to #render" do
43
+ TestController.expects(:exit_render).twice
44
+ request(@user1, :edit_with_render,
45
+ { :id1 => 'theuser', :id2 => 'theuser' }).should succeed
46
+ request(@user1, :edit_with_render,
47
+ { :id1 => 'theuser', :id2 => 'otheruser' }).should fail
48
+ end
49
+
50
+ it "should check rules before #render" do
51
+ TestController.expects(:exit_render).never
52
+ request(@user1, :edit_with_render,
53
+ { :id1 => 'otheruser', :id2 => 'theuser' }).should fail
54
+ end
55
+
56
+ # simulates an action invokation in rails
57
+ def request(user, action, params)
58
+ controller = TestController.new
59
+ controller.test_init(action, params)
60
+ SecurityContext.initialize(controller)
61
+ SecurityContext.credential = user
62
+ rules = controller.class.descriptions_of(action)
63
+ SecurityContext.current.send_with_security(rules, controller, action)
64
+ 'no_error'
65
+ rescue SecurityViolationError => sve
66
+ sve
67
+ end
68
+
69
+ def succeed
70
+ eql 'no_error'
71
+ end
72
+
73
+ def fail
74
+ be_instance_of SecurityViolationError
75
+ end
76
+
77
+ end
78
+
@@ -0,0 +1,74 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe AnnotationSecurity::Utils do
4
+
5
+ it 'should remove prefixes of the method body' do
6
+ %w{may_rule is_rule can_rule has_rule}.each do |method|
7
+ AnnotationSecurity::Utils.method_body(method).should eql('rule')
8
+ end
9
+ end
10
+
11
+ it 'should remove suffixes of the method body' do
12
+ %w{rule_for rule_of rule_in rule_to rule?}.each do |method|
13
+ AnnotationSecurity::Utils.method_body(method).should eql('rule')
14
+ end
15
+ end
16
+
17
+ it 'should return nil if the method body is clean' do
18
+ AnnotationSecurity::Utils.method_body('rule').should be_nil
19
+ end
20
+
21
+ it 'should ignore prefixes and suffixes without underscore in method body' do
22
+ %w{mayrule isrule rulefor ruleof canrulein hasruleto}.each do |method|
23
+ AnnotationSecurity::Utils.method_body(method).should eql(nil)
24
+ end
25
+ end
26
+
27
+ it 'should remove only prefix or suffix from the method body at a time' do
28
+ AnnotationSecurity::Utils.method_body('may_is_rule').should eql('is_rule')
29
+ AnnotationSecurity::Utils.method_body('rule_of_for').should eql('rule_of')
30
+ AnnotationSecurity::Utils.method_body('can_has_rule_to?').should eql('has_rule_to')
31
+ end
32
+
33
+ it 'should parse descriptions without bindings correctly' do
34
+ ['show a resource', 'show with some text ignored a resource',
35
+ 'show pluralized resources', '(ignoring comments) show a resource',
36
+ 'show a resource (with comment at the end)'].each do |s|
37
+ AnnotationSecurity::Utils.parse_description(s).
38
+ should == {:action => :show, :resource => :resource}
39
+ end
40
+ end
41
+
42
+ it 'should detect bindings of a description' do
43
+ {
44
+ 'show the resource in @res' =>
45
+ {:action => :show,:resource => :resource, :source => '@res'},
46
+ 'show the resource from :id' =>
47
+ {:action => :show,:resource => :resource, :source => :id},
48
+ }.each_pair do |key, value|
49
+ AnnotationSecurity::Utils.parse_description(key,true).should == value
50
+ end
51
+ end
52
+
53
+ it 'should raise an error if an unexpected binding is detected in a description' do
54
+ lambda {
55
+ AnnotationSecurity::Utils.parse_description('show the resource :id')
56
+ }.should raise_error(StandardError)
57
+ end
58
+
59
+ it 'should parse policy arguments like specified in SecurityContext.allowed?' do
60
+ obj = Object.new
61
+ def obj.__is_resource?; true; end
62
+ def obj.resource_type; :o_resource; end
63
+ {
64
+ [:show, :resource, obj] => [:show, :resource, obj],
65
+ [:show, obj] => [:show, :o_resource, obj],
66
+ ['show resource', obj] => [:show, :resource, obj],
67
+ [:show, :resource] => [:show, :resource],
68
+ [:administrate] => [:administrate, :all_resources]
69
+ }.each_pair do |key, value|
70
+ AnnotationSecurity::Utils.parse_policy_arguments(key).should == value
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,66 @@
1
+ class TestController < ActionController::Base
2
+
3
+ describe :show, 'shows a test_resource'
4
+ describe :edit, 'edit some test_resources'
5
+ describe :show_edit, 'shows a test_resource', 'edits a test_resource'
6
+ describe :edit_with_render, 'edits the test_resource in @resource'
7
+ describe :delete, 'delete test_resource by :id'
8
+ describe :list, 'list all test_resources in @list'
9
+
10
+
11
+ def test_init(action, params)
12
+ @action = action
13
+ @params = params
14
+ end
15
+
16
+ def action_name
17
+ @action
18
+ end
19
+
20
+ def params
21
+ @params
22
+ end
23
+
24
+ def show
25
+ @resource = TestResource.find params[:id]
26
+ end
27
+
28
+ def edit
29
+ @resource = TestResource.find params[:id]
30
+ end
31
+
32
+ def show_edit
33
+ @resource = TestResource.find params[:id]
34
+ end
35
+
36
+ def edit_with_render
37
+ @resource = TestResource.find params[:id1]
38
+ render 'view'
39
+ @resource = TestResource.find params[:id2]
40
+ end
41
+
42
+ def delete
43
+ self.class.enter_delete
44
+ @resource = TestResource.find params[:id]
45
+ end
46
+
47
+ def list
48
+ r1 = TestResource.find params[:id1]
49
+ r2 = TestResource.find params[:id2]
50
+ @list = [r1, r2]
51
+ end
52
+
53
+ def render(*args)
54
+ super(*args)
55
+ self.class.exit_render
56
+ end
57
+
58
+ # callbacks used for mocking
59
+
60
+ def self.enter_delete
61
+ end
62
+
63
+ def self.exit_render
64
+ end
65
+
66
+ end
@@ -0,0 +1,5 @@
1
+ class TestHelper
2
+
3
+ include AnnotationSecurity::Helper
4
+
5
+ end
@@ -0,0 +1,7 @@
1
+ AnnotationSecurity.define_relations(:test_resource) do
2
+
3
+ owner do |user, res|
4
+ user.name == res.name
5
+ end
6
+
7
+ end
@@ -0,0 +1,39 @@
1
+ class TestResource
2
+
3
+ include AnnotationSecurity::Resource
4
+
5
+ self.resource_type = :test_resource
6
+
7
+ def self.find(arg)
8
+ obj = new arg
9
+
10
+ # normally, this is done by a model observer
11
+ SecurityContext.observe obj
12
+
13
+ obj
14
+ end
15
+
16
+ def self.get_resource(arg)
17
+ return nil if arg.nil?
18
+ return arg if arg.is_a? self
19
+ new arg
20
+ end
21
+
22
+ def initialize(name = "")
23
+ @name = name
24
+ end
25
+
26
+ def name
27
+ @name
28
+ end
29
+
30
+ def ==(other)
31
+ return false unless other.is_a? self.class
32
+ name == other.name
33
+ end
34
+
35
+ def to_s
36
+ "<TestResource:#{name}>"
37
+ end
38
+
39
+ end
@@ -0,0 +1,5 @@
1
+ test_resource:
2
+ show: if logged_in
3
+ edit: if owner
4
+ delete: if may_edit
5
+ list: if owner
@@ -0,0 +1,22 @@
1
+ class TestRole
2
+
3
+ include AnnotationSecurity::Role
4
+
5
+ def initialize(name,user)
6
+ @name = name
7
+ @user = user
8
+ end
9
+
10
+ def role_name
11
+ @name
12
+ end
13
+
14
+ def name
15
+ role_name
16
+ end
17
+
18
+ def user
19
+ @user
20
+ end
21
+
22
+ end
@@ -0,0 +1,32 @@
1
+ class TestUser
2
+
3
+ include AnnotationSecurity::User
4
+
5
+ def initialize(name='user_name')
6
+ @name = name
7
+ @one_role = TestRole.new(:one,self)
8
+ @many_roles = [
9
+ TestRole.new(:a,self), TestRole.new(:b,self), TestRole.new(:c,self)]
10
+ end
11
+
12
+ def user_name
13
+ @name
14
+ end
15
+
16
+ def name
17
+ user_name
18
+ end
19
+
20
+ def as_one_role
21
+ @one_role
22
+ end
23
+
24
+ def as_many_roles
25
+ @many_roles
26
+ end
27
+
28
+ def to_s
29
+ "<TestUser:#{name}>"
30
+ end
31
+
32
+ end
@@ -0,0 +1,38 @@
1
+ # AnnoationSecurity requires rails.
2
+ # Here are some stubs to simulate a rails environment for testing.
3
+ #
4
+
5
+ RAILS_ROOT = ''
6
+ RAILS_ENV = {}
7
+
8
+ class ConfigStub
9
+ def config
10
+ self
11
+ end
12
+ end
13
+
14
+ module ActiveRecord
15
+ class Observer
16
+ def self.observe(*args)
17
+ end
18
+ end
19
+ end
20
+
21
+ module ActionController
22
+ class Base
23
+ def render(*args)
24
+ end
25
+ def redirect_to(*args)
26
+ end
27
+ end
28
+ module Routing
29
+ class Routes
30
+ end
31
+ end
32
+ module Filters
33
+ class Filter
34
+ end
35
+ class AroundFilter < Filter
36
+ end
37
+ end
38
+ end