walruz-rails 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +31 -0
- data/Rakefile +49 -0
- data/VERSION.yml +4 -0
- data/examples/rails/README +243 -0
- data/examples/rails/Rakefile +10 -0
- data/examples/rails/app/controllers/application_controller.rb +10 -0
- data/examples/rails/app/helpers/application_helper.rb +3 -0
- data/examples/rails/app/models/beatle.rb +26 -0
- data/examples/rails/app/models/colaboration.rb +6 -0
- data/examples/rails/app/models/song.rb +10 -0
- data/examples/rails/config/boot.rb +110 -0
- data/examples/rails/config/database.yml +22 -0
- data/examples/rails/config/environment.rb +43 -0
- data/examples/rails/config/environments/development.rb +17 -0
- data/examples/rails/config/environments/production.rb +28 -0
- data/examples/rails/config/environments/test.rb +28 -0
- data/examples/rails/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/rails/config/initializers/inflections.rb +10 -0
- data/examples/rails/config/initializers/mime_types.rb +5 -0
- data/examples/rails/config/initializers/new_rails_defaults.rb +19 -0
- data/examples/rails/config/initializers/session_store.rb +15 -0
- data/examples/rails/config/initializers/walruz_initializer.rb +23 -0
- data/examples/rails/config/locales/en.yml +5 -0
- data/examples/rails/config/routes.rb +43 -0
- data/examples/rails/db/development.sqlite3 +0 -0
- data/examples/rails/db/migrate/20090604201506_create_beatles.rb +12 -0
- data/examples/rails/db/migrate/20090604201512_create_songs.rb +15 -0
- data/examples/rails/db/migrate/20090604201527_create_colaborations.rb +17 -0
- data/examples/rails/db/schema.rb +44 -0
- data/examples/rails/db/test.sqlite3 +0 -0
- data/examples/rails/doc/README_FOR_APP +2 -0
- data/examples/rails/lib/tasks/rspec.rake +165 -0
- data/examples/rails/lib/walruz/policies/author_policy.rb +9 -0
- data/examples/rails/lib/walruz/policies/colaboration_policy.rb +22 -0
- data/examples/rails/lib/walruz/policies.rb +33 -0
- data/examples/rails/log/development.log +1347 -0
- data/examples/rails/log/production.log +0 -0
- data/examples/rails/log/server.log +0 -0
- data/examples/rails/log/test.log +354 -0
- data/examples/rails/public/404.html +30 -0
- data/examples/rails/public/422.html +30 -0
- data/examples/rails/public/500.html +30 -0
- data/examples/rails/public/favicon.ico +0 -0
- data/examples/rails/public/images/rails.png +0 -0
- data/examples/rails/public/index.html +275 -0
- data/examples/rails/public/javascripts/application.js +2 -0
- data/examples/rails/public/javascripts/controls.js +963 -0
- data/examples/rails/public/javascripts/dragdrop.js +973 -0
- data/examples/rails/public/javascripts/effects.js +1128 -0
- data/examples/rails/public/javascripts/prototype.js +4320 -0
- data/examples/rails/public/robots.txt +5 -0
- data/examples/rails/public/unathorized.html +9 -0
- data/examples/rails/script/about +4 -0
- data/examples/rails/script/autospec +6 -0
- data/examples/rails/script/console +3 -0
- data/examples/rails/script/dbconsole +3 -0
- data/examples/rails/script/destroy +3 -0
- data/examples/rails/script/generate +3 -0
- data/examples/rails/script/performance/benchmarker +3 -0
- data/examples/rails/script/performance/profiler +3 -0
- data/examples/rails/script/plugin +3 -0
- data/examples/rails/script/runner +3 -0
- data/examples/rails/script/server +3 -0
- data/examples/rails/script/spec +10 -0
- data/examples/rails/script/spec_server +9 -0
- data/examples/rails/spec/fixtures/beatles.yml +7 -0
- data/examples/rails/spec/fixtures/colaborations.yml +7 -0
- data/examples/rails/spec/fixtures/songs.yml +7 -0
- data/examples/rails/spec/models/beatle_spec.rb +47 -0
- data/examples/rails/spec/models/colaboration_spec.rb +4 -0
- data/examples/rails/spec/models/song_spec.rb +4 -0
- data/examples/rails/spec/rcov.opts +2 -0
- data/examples/rails/spec/spec.opts +4 -0
- data/examples/rails/spec/spec_helper.rb +48 -0
- data/examples/rails/test/performance/browsing_test.rb +9 -0
- data/examples/rails/test/test_helper.rb +38 -0
- data/lib/walruz/controller_mixin.rb +107 -0
- data/lib/walruz_rails.rb +10 -0
- data/spec/controller_mixin_spec.rb +92 -0
- data/spec/scenario.rb +247 -0
- data/spec/spec_helper.rb +29 -0
- metadata +169 -0
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
|
3
|
+
ENV['RSPEC'] = 'true' # allows autotest to discover rspec
|
4
|
+
ENV['AUTOTEST'] = 'true' # allows autotest to run w/ color on linux
|
5
|
+
system((RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV) ||
|
6
|
+
$stderr.puts("Unable to find autotest. Please install ZenTest or fix your PATH")
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
if ARGV.any? {|arg| %w[--drb -X --generate-options -G --help -h --version -v].include?(arg)}
|
3
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
4
|
+
else
|
5
|
+
gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
|
6
|
+
ENV["RAILS_ENV"] ||= 'test'
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") unless defined?(RAILS_ROOT)
|
8
|
+
end
|
9
|
+
require 'spec/autorun'
|
10
|
+
exit ::Spec::Runner::CommandLine.run
|
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
|
3
|
+
|
4
|
+
puts "Loading Rails environment"
|
5
|
+
ENV["RAILS_ENV"] ||= 'test'
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") unless defined?(RAILS_ROOT)
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'spec/rails/spec_server'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Beatle do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@john = Beatle.create!(:name => 'John Lennon')
|
7
|
+
@paul = Beatle.create!(:name => 'Paul McCartney')
|
8
|
+
@george = Beatle.create!(:name => 'George Harrison')
|
9
|
+
@ringo = Beatle.create!(:name => 'Ringo Starr')
|
10
|
+
@john_paul = Colaboration.new
|
11
|
+
@john_paul.beatles << @john
|
12
|
+
@john_paul.beatles << @paul
|
13
|
+
@john_paul.save!
|
14
|
+
@a_day_in_life = Song.create!(:author => @john_paul, :name => 'A Day In Life')
|
15
|
+
@all_you_need_is_love = Song.create!(:author => @john, :name => 'All You Need Is Love')
|
16
|
+
@yesterday = Song.create!(:author => @paul, :name => 'Yesterday')
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "when wants to sing a song" do
|
20
|
+
|
21
|
+
it "should be able to do it when he is the author or a colaborator" do
|
22
|
+
@john.sings(@a_day_in_life).should == "I'll need Paul McCartney to perform this properly"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not be able to do it when he is not the author nor the colaborator" do
|
26
|
+
lambda do
|
27
|
+
@john.sings(@yesterday)
|
28
|
+
end.should raise_error(Walruz::NotAuthorized)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "when he wants to sell a song" do
|
34
|
+
|
35
|
+
it "should be able to do so if he is the only author" do
|
36
|
+
@john.sell(@all_you_need_is_love).should == "Who wants the rights of 'All You Need Is Love'?"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not be able to do so if he is on a colaboration" do
|
40
|
+
lambda do
|
41
|
+
@john.sell(@a_day_in_life)
|
42
|
+
end.should raise_error(Walruz::NotAuthorized)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
2
|
+
# from the project root directory.
|
3
|
+
ENV["RAILS_ENV"] ||= 'test'
|
4
|
+
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
5
|
+
require 'spec/autorun'
|
6
|
+
require 'spec/rails'
|
7
|
+
require 'walruz/policies'
|
8
|
+
|
9
|
+
Spec::Runner.configure do |config|
|
10
|
+
# If you're not using ActiveRecord you should remove these
|
11
|
+
# lines, delete config/database.yml and disable :active_record
|
12
|
+
# in your config/boot.rb
|
13
|
+
config.use_transactional_fixtures = true
|
14
|
+
config.use_instantiated_fixtures = false
|
15
|
+
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
|
16
|
+
|
17
|
+
# == Fixtures
|
18
|
+
#
|
19
|
+
# You can declare fixtures for each example_group like this:
|
20
|
+
# describe "...." do
|
21
|
+
# fixtures :table_a, :table_b
|
22
|
+
#
|
23
|
+
# Alternatively, if you prefer to declare them only once, you can
|
24
|
+
# do so right here. Just uncomment the next line and replace the fixture
|
25
|
+
# names with your fixtures.
|
26
|
+
#
|
27
|
+
# config.global_fixtures = :table_a, :table_b
|
28
|
+
#
|
29
|
+
# If you declare global fixtures, be aware that they will be declared
|
30
|
+
# for all of your examples, even those that don't use them.
|
31
|
+
#
|
32
|
+
# You can also declare which fixtures to use (for example fixtures for test/fixtures):
|
33
|
+
#
|
34
|
+
# config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
|
35
|
+
#
|
36
|
+
# == Mock Framework
|
37
|
+
#
|
38
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
39
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
40
|
+
#
|
41
|
+
# config.mock_with :mocha
|
42
|
+
# config.mock_with :flexmock
|
43
|
+
# config.mock_with :rr
|
44
|
+
#
|
45
|
+
# == Notes
|
46
|
+
#
|
47
|
+
# For more information take a look at Spec::Runner::Configuration and Spec::Runner
|
48
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
3
|
+
require 'test_help'
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
# Transactional fixtures accelerate your tests by wrapping each test method
|
7
|
+
# in a transaction that's rolled back on completion. This ensures that the
|
8
|
+
# test database remains unchanged so your fixtures don't have to be reloaded
|
9
|
+
# between every test method. Fewer database queries means faster tests.
|
10
|
+
#
|
11
|
+
# Read Mike Clark's excellent walkthrough at
|
12
|
+
# http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
|
13
|
+
#
|
14
|
+
# Every Active Record database supports transactions except MyISAM tables
|
15
|
+
# in MySQL. Turn off transactional fixtures in this case; however, if you
|
16
|
+
# don't care one way or the other, switching from MyISAM to InnoDB tables
|
17
|
+
# is recommended.
|
18
|
+
#
|
19
|
+
# The only drawback to using transactional fixtures is when you actually
|
20
|
+
# need to test transactions. Since your test is bracketed by a transaction,
|
21
|
+
# any transactions started in your code will be automatically rolled back.
|
22
|
+
self.use_transactional_fixtures = true
|
23
|
+
|
24
|
+
# Instantiated fixtures are slow, but give you @david where otherwise you
|
25
|
+
# would need people(:david). If you don't want to migrate your existing
|
26
|
+
# test cases which use the @david style and don't mind the speed hit (each
|
27
|
+
# instantiated fixtures translates to a database query per test method),
|
28
|
+
# then set this back to true.
|
29
|
+
self.use_instantiated_fixtures = false
|
30
|
+
|
31
|
+
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
32
|
+
#
|
33
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
34
|
+
# -- they do not yet inherit this setting
|
35
|
+
fixtures :all
|
36
|
+
|
37
|
+
# Add more helper methods to be used by all tests here...
|
38
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Walruz
|
2
|
+
module ControllerMixin
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
|
11
|
+
def set_policy_params!(params)
|
12
|
+
@_policy_params = params
|
13
|
+
end
|
14
|
+
|
15
|
+
def policy_params
|
16
|
+
@_policy_params
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
|
23
|
+
#
|
24
|
+
# Returns a before filter that will check if the actor returned by the method `current_user` can execute the
|
25
|
+
# given action on the given subject.
|
26
|
+
#
|
27
|
+
# Requirements:
|
28
|
+
# - The controller must have a method called `current_user` that returns the authenticated user
|
29
|
+
#
|
30
|
+
# Parameters:
|
31
|
+
# - action: Symbol that represents the action wich will be executed on the subject
|
32
|
+
# - subject: Symbol that indicates an instance variable or method on the controller that
|
33
|
+
# returns the subject
|
34
|
+
#
|
35
|
+
# Returns:
|
36
|
+
# A proc that will be executed as a before_filter method
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# class UserController < ActionController::Base
|
41
|
+
#
|
42
|
+
# before_filter check_authorization!(:create, :user), :only => [:new, :create]
|
43
|
+
# before_filter check_authorization!(:destroy, :complicated_method_that_returns_a_user), :only => :destroy
|
44
|
+
#
|
45
|
+
# def complicated_method_that_returns_a_user
|
46
|
+
# # some complex logic here
|
47
|
+
# return user
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
def check_authorization!(action, subject)
|
52
|
+
lambda do |controller|
|
53
|
+
# we get the subject
|
54
|
+
subject_instance = if controller.instance_variable_defined?("@%s" % subject)
|
55
|
+
controller.instance_variable_get("@%s" % subject)
|
56
|
+
elsif controller.respond_to?(subject)
|
57
|
+
controller.send(subject)
|
58
|
+
else
|
59
|
+
error_message = "There is neither an instance variable @%s nor a instance method %s on the %s instance context" % [subject, subject, controller.class.name]
|
60
|
+
raise ArgumentError.new(error_message)
|
61
|
+
end
|
62
|
+
params = controller.send(:current_user).can!(action, subject_instance)
|
63
|
+
controller.set_policy_params!(params)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
#
|
69
|
+
# Generates dynamically all the before filters needed for authorizations on a CRUD model.
|
70
|
+
#
|
71
|
+
# Requirements:
|
72
|
+
# - The controller must have a method called `current_user` that returns the authenticated user
|
73
|
+
# - The subject must implement the four actions (:create, :read, :update, :destroy) or have a :default action
|
74
|
+
#
|
75
|
+
# Parameters:
|
76
|
+
# - subject: Symbol that indicates an instance variable or method on the controller that
|
77
|
+
# returns the subject
|
78
|
+
#
|
79
|
+
# Example:
|
80
|
+
#
|
81
|
+
# class CommentController < ActionController::Base
|
82
|
+
#
|
83
|
+
# before_check_crud_authorizations_on :@comment
|
84
|
+
#
|
85
|
+
# # This would be the same as:
|
86
|
+
# # before_filter check_authorization!(:create, :@comment), :only => [:new, :create]
|
87
|
+
# # before_filter check_authorization!(:read, :@comment), :only => :show
|
88
|
+
# # before_filter check_authorization!(:update, :@comment), :only => [:edit, :update]
|
89
|
+
# # before_filter check_authorization!(:destroy, :@comment), :only => :destroy
|
90
|
+
#
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
def before_check_crud_authorizations_on(subject)
|
94
|
+
[
|
95
|
+
[:create, ['new', 'create']],
|
96
|
+
[:read, 'show'],
|
97
|
+
[:update, ['edit', 'update']],
|
98
|
+
[:destroy, 'destroy']
|
99
|
+
].each do |(actor_action, actions)|
|
100
|
+
before_filter(check_authorization!(actor_action, subject), :only => actions)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/lib/walruz_rails.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'walruz'
|
3
|
+
require 'active_support'
|
4
|
+
require File.dirname(__FILE__) + '/walruz/controller_mixin'
|
5
|
+
|
6
|
+
if defined?(Rails)
|
7
|
+
Rails.configuration.after_initialize do
|
8
|
+
ActionController::Base.class_eval { include Walruz::ControllerMixin }
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Walruz::ControllerMixin do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@controller = SongsController.new
|
7
|
+
@request = ActionController::TestRequest.new
|
8
|
+
@response = ActionController::TestResponse.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should provide a check_authorization! method" do
|
12
|
+
@controller.class.should respond_to(:check_authorization!)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should provide a before_check_crud_authorizations_on method" do
|
16
|
+
@controller.class.should respond_to(:before_check_crud_authorizations_on)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should provide a policy_params instance method" do
|
20
|
+
@controller.should respond_to(:policy_params)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#check_authorization!' do
|
24
|
+
|
25
|
+
describe "with current_user authorized" do
|
26
|
+
|
27
|
+
before(:each) do
|
28
|
+
@controller.stub!(:current_user).and_return(Beatle::PAUL)
|
29
|
+
post(:sings, :song => 'Yesterday')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should invoke the authorization with the current_user successfuly" do
|
33
|
+
@response.body.should == 'Paul is singing Yesterday'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should provide the policy return hash on the policy_params instance method" do
|
37
|
+
@controller.policy_params.should_not be_nil
|
38
|
+
@controller.policy_params[:author_policy?].should == true
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when the specified user is not setted on the context" do
|
44
|
+
|
45
|
+
before(:each) do
|
46
|
+
@controller.stub!(:assign_song)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise an argument error" do
|
50
|
+
post(:sings, :song => 'Yesterday')
|
51
|
+
@response.body.should =~ /There is neither an instance variable/
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "with current_user not authorized" do
|
57
|
+
|
58
|
+
before(:each) do
|
59
|
+
@controller.stub!(:current_user).and_return(Beatle::JOHN)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should invoke the authorization with the current_user successfuly" do
|
63
|
+
post(:sings, :song => 'Yesterday')
|
64
|
+
@response.body.should == 'Unauthorized'
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#before_check_crud_authorizations_on' do
|
73
|
+
|
74
|
+
before(:each) do
|
75
|
+
@controller = PostsController.new
|
76
|
+
@request = ActionController::TestRequest.new
|
77
|
+
@response = ActionController::TestResponse.new
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should generate before filters for each CRUD action" do
|
81
|
+
PostsController.before_filters.should have(5).filters # + 1 of the get_post
|
82
|
+
OtherPostsController.before_filters.should have(5).filters
|
83
|
+
end
|
84
|
+
|
85
|
+
it "every action should work correctly" do
|
86
|
+
post :destroy, :method => '_delete'
|
87
|
+
@response.body.should =~ /Unauthorized/
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|