stffn-declarative_authorization 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/CHANGELOG +9 -0
  2. data/README.rdoc +22 -6
  3. data/app/controllers/authorization_rules_controller.rb +135 -14
  4. data/app/helpers/authorization_rules_helper.rb +96 -13
  5. data/app/views/authorization_rules/_change.erb +49 -0
  6. data/app/views/authorization_rules/_show_graph.erb +37 -0
  7. data/app/views/authorization_rules/_suggestion.erb +9 -0
  8. data/app/views/authorization_rules/_suggestions.erb +24 -0
  9. data/app/views/authorization_rules/change.html.erb +124 -0
  10. data/app/views/authorization_rules/graph.dot.erb +23 -4
  11. data/app/views/authorization_rules/graph.html.erb +1 -0
  12. data/app/views/authorization_rules/index.html.erb +3 -2
  13. data/app/views/authorization_usages/index.html.erb +2 -11
  14. data/config/routes.rb +2 -1
  15. data/lib/declarative_authorization/authorization.rb +87 -35
  16. data/lib/declarative_authorization/development_support/analyzer.rb +252 -0
  17. data/lib/declarative_authorization/development_support/change_analyzer.rb +253 -0
  18. data/lib/declarative_authorization/development_support/change_supporter.rb +578 -0
  19. data/lib/declarative_authorization/development_support/development_support.rb +243 -0
  20. data/lib/declarative_authorization/helper.rb +6 -2
  21. data/lib/declarative_authorization/in_controller.rb +254 -26
  22. data/lib/declarative_authorization/in_model.rb +27 -2
  23. data/lib/declarative_authorization/maintenance.rb +22 -8
  24. data/lib/declarative_authorization/obligation_scope.rb +14 -9
  25. data/lib/declarative_authorization/reader.rb +10 -2
  26. data/test/authorization_test.rb +44 -0
  27. data/test/controller_filter_resource_access_test.rb +385 -0
  28. data/test/controller_test.rb +14 -6
  29. data/test/helper_test.rb +21 -0
  30. data/test/maintenance_test.rb +26 -0
  31. data/test/model_test.rb +28 -0
  32. data/test/test_helper.rb +14 -1
  33. metadata +15 -5
  34. data/lib/declarative_authorization/authorization_rules_analyzer.rb +0 -138
  35. data/test/authorization_rules_analyzer_test.rb +0 -123
@@ -2,12 +2,8 @@ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
2
 
3
3
 
4
4
  class LoadMockObject < MockDataObject
5
- def self.find(*args)
6
- new :id => args[0]
7
- end
8
5
  end
9
6
 
10
-
11
7
  ##################
12
8
  class SpecificMocksController < MocksController
13
9
  filter_access_to :test_action, :require => :test, :context => :permissions
@@ -26,7 +22,6 @@ end
26
22
  class BasicControllerTest < ActionController::TestCase
27
23
  tests SpecificMocksController
28
24
 
29
-
30
25
  def test_filter_access_to_receiving_an_explicit_array
31
26
  reader = Authorization::Reader::DSLReader.new
32
27
 
@@ -153,6 +148,20 @@ class BasicControllerTest < ActionController::TestCase
153
148
  @controller.send(:instance_variable_get, :"@load_mock_object")
154
149
  assert @controller.authorized?
155
150
  end
151
+
152
+ def test_permitted_to_without_context
153
+ reader = Authorization::Reader::DSLReader.new
154
+ reader.parse %{
155
+ authorization do
156
+ role :test_role do
157
+ has_permission_on :specific_mocks, :to => :test
158
+ end
159
+ end
160
+ }
161
+ @controller.current_user = MockUser.new(:test_role)
162
+ @controller.authorization_engine = Authorization::Engine.new(reader)
163
+ assert @controller.permitted_to?(:test)
164
+ end
156
165
  end
157
166
 
158
167
 
@@ -358,4 +367,3 @@ class HierachicalControllerTest < ActionController::TestCase
358
367
  assert !@controller.authorized?
359
368
  end
360
369
  end
361
-
data/test/helper_test.rb CHANGED
@@ -63,6 +63,27 @@ class HelperTest < ActionController::TestCase
63
63
  assert permitted_to?(:show, :mocks)
64
64
  assert !permitted_to?(:show, mock_2)
65
65
  end
66
+
67
+ def test_permit_with_object_and_context
68
+ reader = Authorization::Reader::DSLReader.new
69
+ reader.parse %{
70
+ authorization do
71
+ role :test_role do
72
+ has_permission_on :other_mocks do
73
+ to :show
74
+ if_attribute :test_attr => is {user.test_attr}
75
+ end
76
+ end
77
+ end
78
+ }
79
+ user = MockUser.new(:test_role, :test_attr => 1)
80
+ mock = MockDataObject.new(:test_attr => 1)
81
+ mock_2 = MockDataObject.new(:test_attr => 2)
82
+ request!(user, :action, reader)
83
+
84
+ assert permitted_to?(:show, mock, :context => :other_mocks)
85
+ assert !permitted_to?(:show, mock_2, :context => :other_mocks)
86
+ end
66
87
 
67
88
  def test_has_role
68
89
  reader = Authorization::Reader::DSLReader.new
@@ -12,4 +12,30 @@ class MaintenanceTest < Test::Unit::TestCase
12
12
  include?(usage_test_controller)
13
13
  end
14
14
 
15
+ def test_without_access_control
16
+ reader = Authorization::Reader::DSLReader.new
17
+ reader.parse %{
18
+ authorization do
19
+ role :test_role do
20
+ has_permission_on :permissions, :to => :test
21
+ end
22
+ end
23
+ }
24
+ engine = Authorization::Engine.new(reader)
25
+ assert !engine.permit?(:test_2, :context => :permissions,
26
+ :user => MockUser.new(:test_role))
27
+ Authorization::Maintenance::without_access_control do
28
+ assert engine.permit?(:test_2, :context => :permissions,
29
+ :user => MockUser.new(:test_role))
30
+ end
31
+ Authorization::Maintenance::without_access_control do
32
+ Authorization::Maintenance::without_access_control do
33
+ assert engine.permit?(:test_2, :context => :permissions,
34
+ :user => MockUser.new(:test_role))
35
+ end
36
+ assert engine.permit?(:test_2, :context => :permissions,
37
+ :user => MockUser.new(:test_role))
38
+ end
39
+ end
40
+
15
41
  end
data/test/model_test.rb CHANGED
@@ -168,6 +168,34 @@ class ModelTest < Test::Unit::TestCase
168
168
  TestModel.delete_all
169
169
  end
170
170
 
171
+ def test_named_scope_with_is_nil
172
+ reader = Authorization::Reader::DSLReader.new
173
+ reader.parse %{
174
+ authorization do
175
+ role :test_role do
176
+ has_permission_on :test_models, :to => :read do
177
+ if_attribute :content => nil
178
+ end
179
+ end
180
+ role :test_role_not_nil do
181
+ has_permission_on :test_models, :to => :read do
182
+ if_attribute :content => is_not { nil }
183
+ end
184
+ end
185
+ end
186
+ }
187
+ Authorization::Engine.instance(reader)
188
+
189
+ test_model_1 = TestModel.create!
190
+ test_model_2 = TestModel.create! :content => "Content"
191
+
192
+ assert_equal test_model_1, TestModel.with_permissions_to(:read,
193
+ :context => :test_models, :user => MockUser.new(:test_role)).first
194
+ assert_equal test_model_2, TestModel.with_permissions_to(:read,
195
+ :context => :test_models, :user => MockUser.new(:test_role_not_nil)).first
196
+ TestModel.delete_all
197
+ end
198
+
171
199
  def test_named_scope_with_not_is
172
200
  reader = Authorization::Reader::DSLReader.new
173
201
  reader.parse %{
data/test/test_helper.rb CHANGED
@@ -41,12 +41,21 @@ class MockDataObject
41
41
  def self.table_name
42
42
  "mocks"
43
43
  end
44
+
45
+ def self.find(*args)
46
+ raise "Couldn't find #{self.name} with id #{args[0].inspect}" unless args[0]
47
+ new :id => args[0]
48
+ end
44
49
  end
45
50
 
46
51
  class MockUser < MockDataObject
47
52
  def initialize (*roles)
48
53
  options = roles.last.is_a?(::Hash) ? roles.pop : {}
49
- super(options.merge(:role_symbols => roles))
54
+ super(options.merge(:role_symbols => roles, :login => hash))
55
+ end
56
+
57
+ def initialize_copy (other)
58
+ @role_symbols = @role_symbols.clone
50
59
  end
51
60
  end
52
61
 
@@ -66,6 +75,10 @@ class MocksController < ActionController::Base
66
75
  end
67
76
  end
68
77
  end
78
+
79
+ def self.define_resource_actions
80
+ define_action_methods :index, :show, :edit, :update, :new, :create, :destroy
81
+ end
69
82
 
70
83
  def logger (*args)
71
84
  Class.new do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stffn-declarative_authorization
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steffen Bartsch
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-08 00:00:00 -07:00
12
+ date: 2009-05-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -43,8 +43,13 @@ files:
43
43
  - app/helpers/authorization_rules_helper.rb
44
44
  - app/views/authorization_usages/index.html.erb
45
45
  - app/views/authorization_rules/index.html.erb
46
+ - app/views/authorization_rules/_show_graph.erb
47
+ - app/views/authorization_rules/_change.erb
48
+ - app/views/authorization_rules/_suggestions.erb
46
49
  - app/views/authorization_rules/graph.dot.erb
50
+ - app/views/authorization_rules/change.html.erb
47
51
  - app/views/authorization_rules/graph.html.erb
52
+ - app/views/authorization_rules/_suggestion.erb
48
53
  - config/routes.rb
49
54
  - lib/declarative_authorization.rb
50
55
  - lib/declarative_authorization/in_controller.rb
@@ -53,7 +58,10 @@ files:
53
58
  - lib/declarative_authorization/obligation_scope.rb
54
59
  - lib/declarative_authorization/in_model.rb
55
60
  - lib/declarative_authorization/helper.rb
56
- - lib/declarative_authorization/authorization_rules_analyzer.rb
61
+ - lib/declarative_authorization/development_support/analyzer.rb
62
+ - lib/declarative_authorization/development_support/change_analyzer.rb
63
+ - lib/declarative_authorization/development_support/change_supporter.rb
64
+ - lib/declarative_authorization/development_support/development_support.rb
57
65
  - lib/declarative_authorization/authorization.rb
58
66
  - lib/declarative_authorization/maintenance.rb
59
67
  - test/authorization_test.rb
@@ -61,12 +69,14 @@ files:
61
69
  - test/maintenance_test.rb
62
70
  - test/model_test.rb
63
71
  - test/controller_test.rb
72
+ - test/development_support
64
73
  - test/helper_test.rb
65
74
  - test/dsl_reader_test.rb
75
+ - test/controller_filter_resource_access_test.rb
66
76
  - test/test_helper.rb
67
- - test/authorization_rules_analyzer_test.rb
68
77
  has_rdoc: true
69
78
  homepage: http://github.com/stffn/declarative_authorization
79
+ licenses:
70
80
  post_install_message:
71
81
  rdoc_options: []
72
82
 
@@ -87,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
97
  requirements: []
88
98
 
89
99
  rubyforge_project:
90
- rubygems_version: 1.2.0
100
+ rubygems_version: 1.3.5
91
101
  signing_key:
92
102
  specification_version: 2
93
103
  summary: declarative_authorization is a Rails plugin for authorization based on readable authorization rules.
@@ -1,138 +0,0 @@
1
- begin
2
- require "ruby_parser"
3
- #require "parse_tree"
4
- #require "parse_tree_extensions"
5
- require "sexp_processor"
6
- rescue LoadError
7
- raise "Authorization::Analyzer requires ruby_parser gem"
8
- end
9
-
10
- module Authorization
11
-
12
- class Analyzer
13
- attr_reader :engine
14
-
15
- def initialize (engine)
16
- @engine = engine
17
- end
18
-
19
- def analyze (rules)
20
- sexp_array = RubyParser.new.parse(rules)
21
- #sexp_array = ParseTree.translate(rules)
22
- @reports = []
23
- [MergeableRulesProcessor].each do |parser|
24
- parser.new(self).analyze(sexp_array)
25
- end
26
- #p @reports
27
- end
28
-
29
- def reports
30
- @reports or raise "No rules analyzed!"
31
- end
32
-
33
- class GeneralAuthorizationProcessor < SexpProcessor
34
- def initialize(analyzer)
35
- super()
36
- self.auto_shift_type = true
37
- self.require_empty = false
38
- self.strict = false
39
- @analyzer = analyzer
40
- end
41
-
42
- def analyze (sexp_array)
43
- process(sexp_array)
44
- analyze_rules
45
- end
46
-
47
- def analyze_rules
48
- # to be implemented by specific processor
49
- end
50
-
51
- def process_iter (exp)
52
- s(:iter, process(exp.shift), process(exp.shift), process(exp.shift))
53
- end
54
-
55
- def process_arglist (exp)
56
- s(exp.collect {|inner_exp| process(inner_exp).shift})
57
- end
58
-
59
- def process_hash (exp)
60
- s(Hash[*exp.collect {|inner_exp| process(inner_exp).shift}])
61
- end
62
-
63
- def process_lit (exp)
64
- s(exp.shift)
65
- end
66
- end
67
-
68
- class MergeableRulesProcessor < GeneralAuthorizationProcessor
69
- def analyze_rules
70
- if @has_permission
71
- #p @has_permission
72
- permissions_by_context_and_rules = @has_permission.inject({}) do |memo, permission|
73
- key = [permission[:context], permission[:rules]]
74
- memo[key] ||= []
75
- memo[key] << permission
76
- memo
77
- end
78
-
79
- permissions_by_context_and_rules.each do |key, rules|
80
- if rules.length > 1
81
- rule_lines = rules.collect {|rule| rule[:line] }
82
- rules.each do |rule|
83
- @analyzer.reports << Report.new(:mergeable_rules, "", rule[:line],
84
- "Similar rules already in line(s) " +
85
- rule_lines.reject {|l| l == rule[:line] } * ", ")
86
- end
87
- end
88
- end
89
- end
90
- end
91
-
92
- def process_call (exp)
93
- klass = exp.shift
94
- name = exp.shift
95
- case name
96
- when :role
97
- analyze_rules
98
- @has_permission = []
99
- s(:call, klass, name)
100
- when :has_permission_on
101
- arglist_line = exp[0].line
102
- arglist = process(exp.shift).shift
103
- context = arglist.shift
104
- args_hash = arglist.shift
105
- @has_permission << {
106
- :context => context,
107
- :rules => [],
108
- :privilege => args_hash && args_hash[:to],
109
- # a hack: call exp line seems to be wrong
110
- :line => arglist_line
111
- }
112
- s(:call, klass, name)
113
- when :to
114
- @has_permission.last[:privilege] = process(exp.shift).shift if @has_permission
115
- s(:call, klass, name)
116
- when :if_attribute
117
- @in_if_attribute = true
118
- rules = process(exp.shift).shift
119
- @has_permission.last[:rules] << rules if @has_permission
120
- @in_if_attribute = false
121
- s(:call, klass, name)
122
- else
123
- s(:call, klass, name, process(exp.shift))
124
- end
125
- end
126
- end
127
-
128
- class Report
129
- attr_reader :type, :filename, :line, :message
130
- def initialize (type, filename, line, msg)
131
- @type = type
132
- @filename = filename
133
- @line = line
134
- @message = msg
135
- end
136
- end
137
- end
138
- end
@@ -1,123 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
- require File.join(File.dirname(__FILE__), %w{.. lib declarative_authorization authorization_rules_analyzer})
3
-
4
- class AuthorizationRulesAnalyzerTest < Test::Unit::TestCase
5
-
6
- def test_analyzing_complex_rules
7
- assert_nothing_raised do
8
- engine, analyzer = engine_analyzer_for %{
9
- authorization do
10
- role :guest do
11
- has_permission_on :conferences, :to => :read do
12
- if_attribute :published => true
13
- end
14
- has_permission_on :talks, :to => :read do
15
- if_permitted_to :read, :conference
16
- end
17
- has_permission_on :users, :to => :create
18
- has_permission_on :authorization_rules, :to => :read
19
- has_permission_on :authorization_usages, :to => :read
20
- end
21
-
22
- role :user do
23
- includes :guest
24
- has_permission_on :conference_attendees, :to => :create do
25
- if_attribute :user => is {user},
26
- :conference => { :published => true }
27
- end
28
- has_permission_on :conference_attendees, :to => :delete do
29
- if_attribute :user => is {user},
30
- :conference => { :attendees => contains {user} }
31
- end
32
- has_permission_on :talk_attendees, :to => :create do
33
- if_attribute :talk => { :conference => { :attendees => contains {user} }}
34
- end
35
- has_permission_on :talk_attendees, :to => :delete do
36
- if_attribute :user => is {user}
37
- end
38
- end
39
-
40
- role :conference_organizer do
41
- has_permission_on :conferences do
42
- to :manage
43
- # if...
44
- end
45
- has_permission_on [:conference_attendees, :talks, :talk_attendees], :to => :manage
46
- end
47
-
48
- role :admin do
49
- has_permission_on [:conferences, :users, :talks], :to => :manage
50
- has_permission_on :authorization_rules, :to => :read
51
- has_permission_on :authorization_usages, :to => :read
52
- end
53
- end
54
-
55
- privileges do
56
- privilege :manage, :includes => [:create, :read, :update, :delete]
57
- privilege :read, :includes => [:index, :show]
58
- privilege :create, :includes => :new
59
- privilege :update, :includes => :edit
60
- privilege :delete, :includes => :destroy
61
- end
62
- }
63
- end
64
- end
65
-
66
- def test_mergeable_rules_without_constraints
67
- engine, analyzer = engine_analyzer_for %{
68
- authorization do
69
- role :test_role do
70
- has_permission_on :permissions, :to => :test
71
- has_permission_on :permissions, :to => :test2
72
- end
73
- end
74
- }
75
-
76
- report = analyzer.reports.find {|report| report.type == :mergeable_rules}
77
- assert report
78
- assert_equal 4, report.line
79
- end
80
-
81
- def test_mergeable_rules_with_in_block_to
82
- assert_nothing_raised do
83
- engine, analyzer = engine_analyzer_for %{
84
- authorization do
85
- role :test_role do
86
- has_permission_on :permissions do
87
- to :test
88
- end
89
- end
90
- end
91
- }
92
- end
93
- end
94
-
95
- def test_no_mergeable_rules_with_constraints
96
- engine, analyzer = engine_analyzer_for %{
97
- authorization do
98
- role :test_role do
99
- has_permission_on :permissions, :to => :test do
100
- if_attribute :some_attr => is {bla}
101
- end
102
- has_permission_on :permissions, :to => :test2 do
103
- if_attribute :some_attr_2 => is {bla}
104
- end
105
- end
106
- end
107
- }
108
-
109
- assert !analyzer.reports.find {|report| report.type == :mergeable_rules}
110
- end
111
-
112
- protected
113
- def engine_analyzer_for (rules)
114
- reader = Authorization::Reader::DSLReader.new
115
- reader.parse rules
116
- engine = Authorization::Engine.new(reader)
117
-
118
- analyzer = Authorization::Analyzer.new(engine)
119
- analyzer.analyze rules
120
-
121
- [engine, analyzer]
122
- end
123
- end