walruz-rails 0.0.10 → 0.0.11
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.
- data/README.rdoc +27 -22
- data/lib/walruz/controller_mixin.rb +110 -38
- data/spec/scenario.rb +35 -14
- data/spec/spec_helper.rb +6 -3
- metadata +71 -11
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= walruz-rails
|
2
2
|
|
3
|
-
Simple
|
3
|
+
Walruz[http://rdoc.info/projects/noomii/walruz]: Simple yet Powerful Policy Composition Authorization Framework
|
4
4
|
|
5
5
|
walruz-rails is a Walruz extension that allows you to integrate easily the Walruz authorization framework with Ruby on Rails.
|
6
6
|
|
@@ -11,6 +11,29 @@ For more information about the functionality of walruz please check the walruz w
|
|
11
11
|
* It provides generators to setup easily your authorization policies
|
12
12
|
* It provides filters for ActionController that enhances the invocations for verification of authorizations
|
13
13
|
|
14
|
+
== INSTALL
|
15
|
+
|
16
|
+
Installation can be done in two ways, either as a gem configuring the dependency in environment.rb
|
17
|
+
|
18
|
+
config.gem 'walruz-rails'
|
19
|
+
|
20
|
+
or as a plugin through script/plugin install
|
21
|
+
|
22
|
+
$ script/plugin install git://github.com/noomii/walruz-rails.git
|
23
|
+
|
24
|
+
Afterwards execute the generator to enable walruz on your project:
|
25
|
+
|
26
|
+
$ script/generate walruz
|
27
|
+
|
28
|
+
This will generate the policies structure on the lib/ folder, and also it will add an initializer that setups your models for Walruz (config/initializers/walruz_intializer.rb).
|
29
|
+
|
30
|
+
If you want to generate new policies, you may do so executing:
|
31
|
+
|
32
|
+
$ script/generate walruz_policy policy_name
|
33
|
+
|
34
|
+
|
35
|
+
All policies will be stored on the `lib/walruz/policies` folder. To organize your policies you may use the `lib/walruz/policies` file.
|
36
|
+
|
14
37
|
|
15
38
|
== HOW TO USE THE FILTERS
|
16
39
|
|
@@ -34,28 +57,10 @@ All this invocations will get translated to:
|
|
34
57
|
|
35
58
|
The result of this invocation will be on a controller method called `policy_params`.
|
36
59
|
|
37
|
-
==
|
38
|
-
|
39
|
-
Installation can be done in two ways, either as a gem configuring the dependency in environment.rb
|
40
|
-
|
41
|
-
config.gem 'walruz-rails'
|
42
|
-
|
43
|
-
or as a plugin through script/plugin install
|
44
|
-
|
45
|
-
$ script/plugin install git://github.com/noomii/walruz-rails.git
|
46
|
-
|
47
|
-
Afterwards execute the generator to enable walruz on your project:
|
48
|
-
|
49
|
-
$ script/generate walruz
|
50
|
-
|
51
|
-
This will generate the policies structure on the lib/ folder, and also it will add an initializer that setups your models for Walruz (config/initializers/walruz_intializer.rb).
|
60
|
+
== Links
|
52
61
|
|
53
|
-
|
54
|
-
|
55
|
-
$ script/generate walruz_policy policy_name
|
56
|
-
|
57
|
-
|
58
|
-
All policies will be stored on the `lib/walruz/policies` folder. To organize your policies you may use the `lib/walruz/policies` file.
|
62
|
+
"Walruz on Github"[http://github.com/noomii/walruz]
|
63
|
+
"Walruz Documentation"[http://rdoc.info/projects/noomii/walruz]
|
59
64
|
|
60
65
|
== Copyright
|
61
66
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Walruz
|
2
2
|
module ControllerMixin
|
3
|
-
|
3
|
+
|
4
4
|
def self.included(base)
|
5
5
|
base.class_eval do
|
6
6
|
include InstanceMethods
|
@@ -8,32 +8,36 @@ module Walruz
|
|
8
8
|
helper_method(:policy_params)
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
module InstanceMethods
|
13
|
-
|
13
|
+
|
14
14
|
def set_policy_params!(params)
|
15
15
|
@_policy_params = params
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def policy_params
|
19
19
|
@_policy_params
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
module ClassMethods
|
25
|
-
|
25
|
+
|
26
|
+
#
|
27
|
+
# Creates a before filter that will check if the actor returned by the
|
28
|
+
# method `current_user` can execute the given action on the given
|
29
|
+
# subject.
|
30
|
+
#
|
26
31
|
#
|
27
|
-
# Returns a before filter that will check if the actor returned by the method `current_user` can execute the
|
28
|
-
# given action on the given subject.
|
29
|
-
#
|
30
32
|
# Requirements:
|
31
|
-
# - The controller must have a method called `current_user` that
|
33
|
+
# - The controller must have a method called `current_user` that
|
34
|
+
# returns the authenticated user
|
32
35
|
#
|
33
36
|
# Parameters:
|
34
|
-
# - action: Symbol that represents the action wich will be executed
|
35
|
-
#
|
36
|
-
#
|
37
|
+
# - action: Symbol that represents the action wich will be executed
|
38
|
+
# on the subject
|
39
|
+
# - subject: Symbol that indicates an instance variable or method on
|
40
|
+
# the controller that returns the subject
|
37
41
|
#
|
38
42
|
# Returns:
|
39
43
|
# A proc that will be executed as a before_filter method
|
@@ -41,9 +45,12 @@ module Walruz
|
|
41
45
|
# Example:
|
42
46
|
#
|
43
47
|
# class UserController < ActionController::Base
|
44
|
-
#
|
45
|
-
# before_filter check_authorization!(:create, :user),
|
46
|
-
#
|
48
|
+
#
|
49
|
+
# before_filter check_authorization!(:create, :user),
|
50
|
+
# :only => [:new, :create]
|
51
|
+
# before_filter check_authorization!(:destroy,
|
52
|
+
# :complicated_method_that_returns_a_user),
|
53
|
+
# :only => :destroy
|
47
54
|
#
|
48
55
|
# def complicated_method_that_returns_a_user
|
49
56
|
# # some complex logic here
|
@@ -54,43 +61,107 @@ module Walruz
|
|
54
61
|
def check_authorization!(action, subject)
|
55
62
|
lambda do |controller|
|
56
63
|
# we get the subject
|
57
|
-
subject_instance =
|
64
|
+
subject_instance =
|
65
|
+
if controller.instance_variable_defined?("@%s" % subject)
|
58
66
|
controller.instance_variable_get("@%s" % subject)
|
59
67
|
elsif controller.respond_to?(subject)
|
60
68
|
controller.send(subject)
|
61
69
|
else
|
62
|
-
error_message = "There is neither an instance variable
|
70
|
+
error_message = "There is neither an instance variable \
|
71
|
+
@%s nor a instance method %s on the %s instance\
|
72
|
+
context" % [subject, subject, controller.class.name]
|
63
73
|
raise ArgumentError.new(error_message)
|
64
74
|
end
|
65
|
-
params = Walruz.authorize!(controller.send(:current_user),
|
75
|
+
params = Walruz.authorize!(controller.send(:current_user),
|
76
|
+
action,
|
77
|
+
subject_instance)
|
66
78
|
controller.set_policy_params!(params)
|
67
79
|
end
|
68
80
|
end
|
69
|
-
|
70
|
-
|
81
|
+
|
82
|
+
#
|
83
|
+
# Creates a before filter that will check the policy represented
|
84
|
+
# by the given symbol, using `current_user` as the actor
|
85
|
+
#
|
71
86
|
#
|
72
|
-
# Generates dynamically all the before filters needed for authorizations on a CRUD model.
|
73
|
-
#
|
74
87
|
# Requirements:
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
88
|
+
# - The controller must have a method called `current_user` that
|
89
|
+
# returns the authenticated user
|
90
|
+
#
|
78
91
|
# Parameters:
|
79
|
-
# -
|
80
|
-
#
|
92
|
+
# - policy_label: Symbol that represents the policy wich will be
|
93
|
+
# executed on the subject
|
94
|
+
#
|
95
|
+
# - subject: Symbol that indicates an instance variable or method on
|
96
|
+
# the controller that returns the subject
|
97
|
+
#
|
98
|
+
# Returns:
|
99
|
+
# A proc that will be executed as a before_filter method
|
100
|
+
#
|
101
|
+
# Example:
|
102
|
+
#
|
103
|
+
# class UserController < ActionController::Base
|
104
|
+
#
|
105
|
+
# before_filter check_policy!(:is_admin, :user),
|
106
|
+
# :only => [:new, :create]
|
107
|
+
# before_filter check_policy!(:can_read_posts,
|
108
|
+
# :complicated_method_that_returns_a_user),
|
109
|
+
# :only => :destroy
|
110
|
+
#
|
111
|
+
# def complicated_method_that_returns_a_user
|
112
|
+
# # some complex logic here
|
113
|
+
# return user
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
def check_policy!(policy_label, subject = nil)
|
118
|
+
lambda do |controller|
|
119
|
+
subject_instance = nil
|
120
|
+
if subject
|
121
|
+
subject_instance =
|
122
|
+
if controller.instance_variable_defined?("@%s" % subject)
|
123
|
+
controller.instance_variable_get("@%s" % subject)
|
124
|
+
elsif controller.respond_to?(:"#{subject}")
|
125
|
+
controller.send(:"#{subject}")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
params = Walruz.satisfies!(controller.send(:current_user),
|
129
|
+
policy_label,
|
130
|
+
subject_instance)
|
131
|
+
controller.set_policy_params!(params)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Generates dynamically all the before filters needed for authorizations
|
137
|
+
# on a CRUD model.
|
138
|
+
#
|
139
|
+
# Requirements:
|
140
|
+
# - The controller must have a method called `current_user` that returns
|
141
|
+
# the authenticated user
|
142
|
+
# - The subject must implement the four actions (:create, :read,
|
143
|
+
# :update, :destroy) or have a :default action
|
144
|
+
#
|
145
|
+
# Parameters:
|
146
|
+
# - subject: Symbol that indicates an instance variable or method on
|
147
|
+
# the controller that returns the subject
|
81
148
|
#
|
82
149
|
# Example:
|
83
150
|
#
|
84
151
|
# class CommentController < ActionController::Base
|
85
|
-
#
|
152
|
+
#
|
86
153
|
# before_check_crud_authorizations_on :@comment
|
87
154
|
#
|
88
155
|
# # This would be the same as:
|
89
|
-
# # before_filter check_authorization!(:create, :@comment),
|
90
|
-
#
|
91
|
-
# # before_filter check_authorization!(:
|
92
|
-
#
|
93
|
-
#
|
156
|
+
# # before_filter check_authorization!(:create, :@comment),
|
157
|
+
# :only => [:new, :create]
|
158
|
+
# # before_filter check_authorization!(:read, :@comment),
|
159
|
+
# :only => :show
|
160
|
+
# # before_filter check_authorization!(:update, :@comment),
|
161
|
+
# :only => [:edit, :update]
|
162
|
+
# # before_filter check_authorization!(:destroy, :@comment),
|
163
|
+
# :only => :destroy
|
164
|
+
#
|
94
165
|
# end
|
95
166
|
#
|
96
167
|
def before_check_crud_authorizations_on(subject)
|
@@ -100,11 +171,12 @@ module Walruz
|
|
100
171
|
[:update, ['edit', 'update']],
|
101
172
|
[:destroy, 'destroy']
|
102
173
|
].each do |(actor_action, actions)|
|
103
|
-
before_filter(check_authorization!(actor_action, subject),
|
174
|
+
before_filter(check_authorization!(actor_action, subject),
|
175
|
+
:only => actions)
|
104
176
|
end
|
105
177
|
end
|
106
|
-
|
178
|
+
|
107
179
|
end
|
108
|
-
|
180
|
+
|
109
181
|
end
|
110
182
|
end
|
data/spec/scenario.rb
CHANGED
@@ -55,7 +55,16 @@ class Colaboration
|
|
55
55
|
JOHN_GEORGE = self.new(Beatle::PAUL, Beatle::GEORGE)
|
56
56
|
end
|
57
57
|
|
58
|
+
class IsJohnLennon < Walruz::Policy
|
59
|
+
|
60
|
+
def authorized?(actor, _)
|
61
|
+
actor == Beatle::JOHN
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
58
66
|
class SubjectIsActorPolicy < Walruz::Policy
|
67
|
+
set_policy_label :actor_is_subject
|
59
68
|
|
60
69
|
def authorized?(actor, subject)
|
61
70
|
actor == subject
|
@@ -63,18 +72,6 @@ class SubjectIsActorPolicy < Walruz::Policy
|
|
63
72
|
|
64
73
|
end
|
65
74
|
|
66
|
-
# class AuthorPolicy < Walruz::Policy
|
67
|
-
#
|
68
|
-
# def authorized?(beatle, song)
|
69
|
-
# if song.author == beatle
|
70
|
-
# [true, { :owner => beatle }]
|
71
|
-
# else
|
72
|
-
# false
|
73
|
-
# end
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# end
|
77
|
-
|
78
75
|
AuthorPolicy = SubjectIsActorPolicy.for_subject(:author) do |authorized, params, actor, subject|
|
79
76
|
params.merge!(:owner => actor) if authorized
|
80
77
|
end
|
@@ -146,14 +143,29 @@ class Application < ActionController::Base
|
|
146
143
|
end
|
147
144
|
|
148
145
|
class SongsController < Application
|
149
|
-
|
146
|
+
|
147
|
+
before_filter :assign_song, :only => :sings
|
150
148
|
before_filter check_authorization!(:sing, :song), :only => :sings
|
149
|
+
|
150
|
+
before_filter :assign_singer, :only => :is
|
151
|
+
before_filter check_policy!(:actor_is_subject, :singer), :only => :is
|
152
|
+
|
153
|
+
before_filter check_policy!(:is_john_lennon), :only => :hi_to_john
|
151
154
|
|
152
155
|
def sings
|
153
156
|
text_to_render = '%s is singing %s' % [current_user.name,
|
154
157
|
@song.name]
|
155
158
|
render :text => text_to_render
|
156
159
|
end
|
160
|
+
|
161
|
+
def is
|
162
|
+
text_to_render = '%s is really %s' % [current_user.name, @singer.name]
|
163
|
+
render :text => text_to_render
|
164
|
+
end
|
165
|
+
|
166
|
+
def hi_to_john
|
167
|
+
render :text => 'Hey John, I thought you were dead already!'
|
168
|
+
end
|
157
169
|
|
158
170
|
protected
|
159
171
|
|
@@ -164,6 +176,14 @@ class SongsController < Application
|
|
164
176
|
nil
|
165
177
|
end
|
166
178
|
end
|
179
|
+
|
180
|
+
def assign_singer
|
181
|
+
@singer = if params[:singer] == 'John'
|
182
|
+
Beatle::JOHN
|
183
|
+
else
|
184
|
+
nil
|
185
|
+
end
|
186
|
+
end
|
167
187
|
|
168
188
|
end
|
169
189
|
|
@@ -244,4 +264,5 @@ end
|
|
244
264
|
##### End of scenario
|
245
265
|
|
246
266
|
ActionController::Routing::Routes.reload!
|
247
|
-
ActionController::Routing::Routes.
|
267
|
+
ActionController::Routing::Routes.
|
268
|
+
draw { |map| map.connect '/:controller/:action' }
|
data/spec/spec_helper.rb
CHANGED
@@ -3,14 +3,17 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
3
3
|
|
4
4
|
begin
|
5
5
|
require 'rubygems'
|
6
|
+
require 'bundler/setup'
|
7
|
+
Bundler.require(:default, :test)
|
6
8
|
require 'action_controller'
|
7
9
|
require 'action_controller/test_process'
|
8
10
|
require 'active_record'
|
9
11
|
require 'initializer'
|
10
|
-
require 'spec'
|
11
|
-
require 'walruz'
|
12
12
|
|
13
|
-
|
13
|
+
tmp_dir = File.dirname(__FILE__) + '/../tmp'
|
14
|
+
Dir.mkdir(tmp_dir) unless File.exist?(tmp_dir)
|
15
|
+
RAILS_ROOT = tmp_dir
|
16
|
+
|
14
17
|
module Rails
|
15
18
|
|
16
19
|
def self.configuration
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: walruz-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 9
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 11
|
10
|
+
version: 0.0.11
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Roman Gonzalez
|
@@ -9,10 +15,55 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-07-12 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
name: jeweler
|
33
|
+
version_requirements: *id001
|
34
|
+
prerelease: false
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
type: :runtime
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 11
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 0
|
46
|
+
- 10
|
47
|
+
version: 0.0.10
|
48
|
+
name: walruz
|
49
|
+
version_requirements: *id002
|
50
|
+
prerelease: false
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
type: :runtime
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - "="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 21
|
59
|
+
segments:
|
60
|
+
- 2
|
61
|
+
- 3
|
62
|
+
- 11
|
63
|
+
version: 2.3.11
|
64
|
+
name: rails
|
65
|
+
version_requirements: *id003
|
66
|
+
prerelease: false
|
16
67
|
description:
|
17
68
|
email: roman@noomii.com
|
18
69
|
executables: []
|
@@ -111,35 +162,44 @@ files:
|
|
111
162
|
- rails_generators/walruz_policy_generator.rb
|
112
163
|
- LICENSE
|
113
164
|
- README.rdoc
|
165
|
+
- spec/spec_helper.rb
|
166
|
+
- spec/scenario.rb
|
167
|
+
- spec/controller_mixin_spec.rb
|
114
168
|
has_rdoc: true
|
115
169
|
homepage: http://github.com/noomii/walruz-rails
|
116
170
|
licenses: []
|
117
171
|
|
118
172
|
post_install_message:
|
119
|
-
rdoc_options:
|
120
|
-
|
173
|
+
rdoc_options: []
|
174
|
+
|
121
175
|
require_paths:
|
122
176
|
- lib
|
123
177
|
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
124
179
|
requirements:
|
125
180
|
- - ">="
|
126
181
|
- !ruby/object:Gem::Version
|
182
|
+
hash: 3
|
183
|
+
segments:
|
184
|
+
- 0
|
127
185
|
version: "0"
|
128
|
-
version:
|
129
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
none: false
|
130
188
|
requirements:
|
131
189
|
- - ">="
|
132
190
|
- !ruby/object:Gem::Version
|
191
|
+
hash: 3
|
192
|
+
segments:
|
193
|
+
- 0
|
133
194
|
version: "0"
|
134
|
-
version:
|
135
195
|
requirements: []
|
136
196
|
|
137
197
|
rubyforge_project: walruz-rails
|
138
|
-
rubygems_version: 1.
|
198
|
+
rubygems_version: 1.6.2
|
139
199
|
signing_key:
|
140
200
|
specification_version: 3
|
141
201
|
summary: Gem for easy integration between walruz and the Ruby on Rails framework
|
142
202
|
test_files:
|
143
|
-
- spec/controller_mixin_spec.rb
|
144
|
-
- spec/scenario.rb
|
145
203
|
- spec/spec_helper.rb
|
204
|
+
- spec/scenario.rb
|
205
|
+
- spec/controller_mixin_spec.rb
|