Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #196 from doximity/rails4

Rails 4 (thanks to @divoxx, @zeiv, @gordonbisnor and @aepstein)
  • Loading branch information...
commit 45e91af20eba71b2828c5c84066bcce3ef032e8a 2 parents 549a8d3 + 963ae55
@stffn authored
Showing with 706 additions and 103 deletions.
  1. +4 −0 .gitignore
  2. +7 −4 .travis.yml
  3. +103 −0 README.rdoc
  4. +1 −1  Rakefile
  5. +1 −2  app/controllers/authorization_rules_controller.rb
  6. +1 −2  app/controllers/authorization_usages_controller.rb
  7. +2 −2 app/views/authorization_rules/_change.erb
  8. +1 −1  app/views/authorization_rules/_show_graph.erb
  9. +3 −3 app/views/authorization_rules/change.html.erb
  10. +2 −2 app/views/authorization_rules/graph.html.erb
  11. +1 −1  declarative_authorization.gemspec
  12. +8 −0 gemfiles/4.0.gemfile
  13. +7 −0 gemfiles/4.1.gemfile
  14. +13 −0 lib/declarative_authorization/adapters/active_record.rb
  15. 0  lib/declarative_authorization/adapters/active_record/base_extensions.rb
  16. 0  lib/declarative_authorization/adapters/active_record/obligation_scope_builder.rb
  17. +10 −1 lib/declarative_authorization/authorization.rb
  18. +14 −5 lib/declarative_authorization/development_support/analyzer.rb
  19. +68 −23 lib/declarative_authorization/in_controller.rb
  20. +1 −2  lib/declarative_authorization/in_model.rb
  21. +6 −3 lib/declarative_authorization/obligation_scope.rb
  22. +77 −0 lib/generators/authorization/install/install_generator.rb
  23. +14 −0 lib/generators/authorization/rules/rules_generator.rb
  24. +27 −0 lib/generators/authorization/rules/templates/authorization_rules.rb
  25. +70 −6 test/controller_filter_resource_access_test.rb
  26. +2 −1  test/development_support/analyzer_test.rb
  27. +123 −25 test/model_test.rb
  28. +1 −0  test/schema.sql
  29. +112 −19 test/test_helper.rb
  30. +27 −0 test/test_support/minitest_compatibility.rb
View
4 .gitignore
@@ -3,3 +3,7 @@ garlic
nbproject
rdoc
gemfiles/*.lock
+log/*
+*.sublime*
+
+
View
11 .travis.yml
@@ -2,16 +2,19 @@ language: ruby
script: bundle exec rake test
rvm:
- 1.8.7
- - 1.9.2
- 1.9.3
gemfile:
- gemfiles/2.3.gemfile
- gemfiles/3.0.gemfile
- gemfiles/3.1.gemfile
- gemfiles/3.2.gemfile
+ - gemfiles/4.0.gemfile
+ - gemfiles/4.1.gemfile
matrix:
- allow_failures:
- - rvm: 1.9.2
- gemfile: gemfiles/2.3.gemfile
+ exclude:
+ - rvm: 1.8.7
+ gemfile: gemfiles/4.0.gemfile
+ - rvm: 1.8.7
+ gemfile: gemfiles/4.1.gemfile
- rvm: 1.9.3
gemfile: gemfiles/2.3.gemfile
View
103 README.rdoc
@@ -21,6 +21,7 @@ Plugin features
* Authorize CRUD (Create, Read, Update, Delete) activities
* Query rewriting to automatically only fetch authorized records
* DSL for specifying Authorization rules in an authorization configuration
+* Support for Rails 4, with backwards compatibility through Rails 2
Requirements
@@ -36,6 +37,99 @@ There is a decl_auth screencast by Ryan Bates, nicely introducing the main conce
http://railscasts.com/episodes/188-declarative-authorization
+= Quick Start
+
+=== Installer
+
+Declarative Authorization comes with an installer to make setup easy.
+
+First, include declarative_authorization in your gemfile.
+
+ #! Gemfile
+ gem 'declarative_authorization'
+
+Next, bundle and install.
+
+ $ bundle
+ $ rails g authorization:install [UserModel=User] [field:type field:type ...] [--create-user --commit --user-belongs-to-role]
+
+This installer will create a Role model, an admin and a user role, and set a
+has_and_belongs_to_many relationship between the User model and the Role model.
+It will also add a `role_symbols` method to the user model to meet
+declarative_authorization's requirements. The default User model is User. You can override this by simply typing the name of a model as above.
+
+You can create the model with the fields provided by using the `--create-user` option.
+
+The `--commit` option will run `rake db:migrate` and `rake db:seed`.
+
+The `--user-belongs-to-role` option will set up a one-to-many relationship between Users and Roles.
+That is, each user has a role_id column and can only have one role. Role inheritance can be used
+in authorization rules.
+
+Finally, the installer also copies default authorization rules, as below.
+
+=== Generate Authorization Rules
+
+To copy a default set of authorization rules which includes CRUD priveleges, run:
+
+ $ rails g authorization:rules
+
+This command will copy the following to `config/authorization_rules.rb`. Remember
+to implement the requirements of this gem as described in the Installation section
+at the end of this README if you do not use the above installer.
+
+ authorization do
+ role :guest do
+ # add permissions for guests here, e.g.
+ # has_permission_on :conferences, :to => :read
+ end
+
+ # permissions on other roles, such as
+ # role :admin do
+ # has_permission_on :conferences, :to => :manage
+ # end
+ # role :user do
+ # has_permission_on :conferences, :to => [:read, :create]
+ # has_permission_on :conferences, :to => [:update, :delete] do
+ # if_attribute :user_id => is {user.id}
+ # end
+ # end
+ # See the readme or GitHub for more examples
+ end
+
+ privileges do
+ # default privilege hierarchies to facilitate RESTful Rails apps
+ privilege :manage, :includes => [:create, :read, :update, :delete]
+ privilege :create, :includes => :new
+ privilege :read, :includes => [:index, :show]
+ privilege :update, :includes => :edit
+ privilege :delete, :includes => :destroy
+ end
+
+=== Controller Authorization
+
+For RESTful controllers, add `filter_resource_access`:
+
+ class MyRestfulController < ApplicationController
+ filter_resource_access
+ ...
+ end
+
+For a non-RESTful controller, you can use `filter_access_to`:
+
+ class MyOtherController < ApplicationController
+ filter_access_to :all
+ # or a group: filter_access_to [:action1, :action2]
+ ...
+ end
+
+=== View Authorization
+
+Declarative Authorization will use `current_user` to check authorization.
+
+ <%= link_to 'Edit Post', edit_post_path(@post) if permitted_to? :update, @post %>
+
+
= Authorization Data Model
----- App domain ----|-------- Authorization conf ---------|------- App domain ------
@@ -92,6 +186,15 @@ filter_access_to with the appropriate parameters to protect the CRUD methods.
See Authorization::AuthorizationInController::ClassMethods for options on
nested resources and custom member and collection actions.
+By default, declarative_authorization will enable filter_resource_access compatibility with strong_parameters in Rails 4. If you want to disable this behavior, you can use the `:strong_parameters` option.
+
+ class EmployeesController < ApplicationController
+ filter_resource_access :strong_parameters => false
+ ...
+ end
+
+Simalarly, you can use `:strong_parameters => true` if you are using strong_parameters in Rails 3.
+
If you prefer less magic or your controller has no resemblance with the resource
controllers, directly calling filter_access_to may be the better option. Examples
are given in the following. E.g. the privilege index users is required for
View
2  Rakefile
@@ -1,6 +1,6 @@
require 'rake'
require 'rake/testtask'
-require 'rake/rdoctask'
+require 'rdoc/task'
desc 'Default: run unit tests against all versions.'
task :default => 'bundles:test'
View
3  app/controllers/authorization_rules_controller.rb
@@ -12,7 +12,6 @@
rescue LoadError; end
class AuthorizationRulesController < ApplicationController
- unloadable
filter_access_to :all, :require => :read
def index
@@ -256,4 +255,4 @@ def find_all_users
else
class AuthorizationRulesController < ApplicationController; end
-end # activate_authorization_rules_browser?
View
3  app/controllers/authorization_usages_controller.rb
@@ -3,7 +3,6 @@
require File.join(File.dirname(__FILE__), %w{.. .. lib declarative_authorization maintenance})
class AuthorizationUsagesController < ApplicationController
- unloadable
helper :authorization_rules
filter_access_to :all, :require => :read
@@ -20,4 +19,4 @@ def index
else
class AuthorizationUsagesController < ApplicationController; end
-end # activate_authorization_rules_browser?
View
4 app/views/authorization_rules/_change.erb
@@ -8,7 +8,7 @@
<%= select_tag :context, options_for_select(@contexts.map {|c| [human_context(c), c.to_s]}.sort, @context.to_s) %>
<br/>
<label></label>
- <%= link_to_function "Show current permissions", "show_current_permissions()", :class => 'unimportant' %>
+ <%= link_to "Show current permissions", '#', onclick: "show_current_permissions()", :class => 'unimportant' %>
<br/><br/>
How many users should be <strong>affected</strong>?
<br/>
@@ -53,6 +53,6 @@
<ul id="prohibited_actions"></ul>
<p class="submit">
- <%= button_to_function "Suggest Changes", "suggest_changes()" %>
+ <%= button_to "Suggest Changes", '#', onclick: "suggest_changes()" %>
</p>
</form>
View
2  app/views/authorization_rules/_show_graph.erb
@@ -39,6 +39,6 @@
}
<% end %>
<div id="graph-container" style="display:none">
-<%= link_to_function "Hide", "$('graph-container').hide()", :class => 'important' %><br/>
+<%= link_to '#', "Hide", onclick: "$('graph-container').hide()", :class => 'important' %><br/>
<object id="graph" data="" type="image/svg+xml" style="max-width:100%;margin-top: 0.5em"/>
</div>
View
6 app/views/authorization_rules/change.html.erb
@@ -1,9 +1,9 @@
<h1>Suggestions on Authorization Rules Change</h1>
<p><%= navigation %></p>
<div style="display:none" id="suggest-graph-container">
-<%= link_to_function "Hide", "$(this).up().hide()", :class => 'important' %>
-<%= link_to_function "Toggle stacked roles", "toggle_graph_params('suggest-graph', 'stacked_roles');" %>
-<%= link_to_function "Toggle only users' roles", "toggle_graph_params('suggest-graph', 'only_relevant_roles');" %><br/>
+<%= link_to "Hide", '#', onclick: "$(this).up().hide()", :class => 'important' %>
+<%= link_to "Toggle stacked roles", '#', onclick: "toggle_graph_params('suggest-graph', 'stacked_roles');" %>
+<%= link_to "Toggle only users' roles", '#', onclick: "toggle_graph_params('suggest-graph', 'only_relevant_roles');" %><br/>
<object id="suggest-graph" data="" type="image/svg+xml" style="max-width: 98%;max-height: 95%;margin-top: 0.5em"/>
</div>
<%= render 'show_graph' %>
View
4 app/views/authorization_rules/graph.html.erb
@@ -43,5 +43,5 @@
<div style="margin: 1em;border:1px solid #ccc;max-width:95%">
<object id="graph" data="<%= url_for :format => 'svg' %>" type="image/svg+xml" style="max-width:100%"/>
</div>
-<%= button_to_function "Zoom in", '$("graph").style.maxWidth = "";$(this).toggle();$(this).next().toggle()' %>
-<%= button_to_function "Zoom out", '$("graph").style.maxWidth = "100%";$(this).toggle();$(this).previous().toggle()', :style => 'display:none' %>
+<%= button_to "Zoom in", '#', onclick: '$("graph").style.maxWidth = "";$(this).toggle();$(this).next().toggle()' %>
+<%= button_to "Zoom out", '#', onclick: '$("graph").style.maxWidth = "100%";$(this).toggle();$(this).previous().toggle()', :style => 'display:none' %>
View
2  declarative_authorization.gemspec
@@ -2,7 +2,7 @@
Gem::Specification.new do |s|
s.name = "declarative_authorization"
- s.version = "0.5.7"
+ s.version = "1.0.0.pre"
s.required_ruby_version = ">= 1.8.6"
s.authors = ["Steffen Bartsch"]
View
8 gemfiles/4.0.gemfile
@@ -0,0 +1,8 @@
+source 'https://rubygems.org'
+
+gem 'rails', '~> 4.0.0'
+gem 'sqlite3'
+gem 'ruby_parser'
+gem 'rdoc'
+gemspec :path => '..'
+
View
7 gemfiles/4.1.gemfile
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gem 'rails', '~> 4.1.0'
+gem 'sqlite3'
+gem 'ruby_parser'
+gem 'rdoc'
+gemspec :path => '..'
View
13 lib/declarative_authorization/adapters/active_record.rb
@@ -0,0 +1,13 @@
+case ActiveRecord::VERSION::MAJOR
+when 3, 4
+# ActiveRecord::Relation.send :include, Squeel::Nodes::Aliasing
+# require 'squeel/adapters/active_record/join_dependency_extensions'
+# require 'squeel/adapters/active_record/base_extensions'
+
+ adapter_directory = "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
+ Dir[File.expand_path("../active_record/#{adapter_directory}/*.rb", __FILE__)].each do |f|
+ require f
+ end
+else
+ raise NotImplementedError, "DeclarativeAuthorization does not support Active Record version #{ActiveRecord::VERSION::STRING}"
+end
View
0  lib/declarative_authorization/adapters/active_record/base_extensions.rb
No changes.
View
0  lib/declarative_authorization/adapters/active_record/obligation_scope_builder.rb
No changes.
View
11 lib/declarative_authorization/authorization.rb
@@ -164,7 +164,7 @@ def permit! (privilege, options = {})
# Example: permit!( :edit, :object => user.posts )
#
if Authorization.is_a_association_proxy?(options[:object]) && options[:object].respond_to?(:new)
- options[:object] = (Rails.version < "3.0" ? options[:object] : options[:object].scoped).new
+ options[:object] = (Rails.version < "3.0" ? options[:object] : options[:object].where(nil)).new
end
options[:context] ||= options[:object] && (
@@ -512,6 +512,15 @@ def validate? (attr_validator, object = nil, hash = nil)
object ||= attr_validator.object
return false unless object
+ if ( Authorization.is_a_association_proxy?(object) &&
+ object.respond_to?(:empty?) )
+ return false if object.empty?
+ object.each do |member|
+ return true if validate?(attr_validator, member, hash)
+ end
+ return false
+ end
+
(hash || @conditions_hash).all? do |attr, value|
attr_value = object_attribute_value(object, attr)
if value.is_a?(Hash)
View
19 lib/declarative_authorization/development_support/analyzer.rb
@@ -208,9 +208,10 @@ def process_call (exp)
s(:call, klass, name)
when :has_permission_on
arglist_line = exp[0].line
- arglist = process(exp.shift).shift
- context = arglist.shift
- args_hash = arglist.shift
+ # what is the purpose of arglist? Used to be process(exp.shift).shift, which broke args_hash
+ arglist = process(exp.shift)
+ context = arglist
+ args_hash = exp[0].nil? ? nil : process(exp.shift).shift
@has_permission << {
:context => context,
:rules => [],
@@ -223,15 +224,23 @@ def process_call (exp)
@has_permission.last[:privilege] = process(exp.shift).shift if @has_permission
s(:call, klass, name)
when :if_attribute
- rules = process(exp.shift).shift
+ rules = process(exp.shift)
rules.unshift :if_attribute
@has_permission.last[:rules] << rules if @has_permission
s(:call, klass, name)
when :if_permitted_to
- rules = process(exp.shift).shift
+ rules = process(exp.shift).push(process(exp.shift).shift)
rules.unshift :if_permitted_to
@has_permission.last[:rules] << rules if @has_permission
s(:call, klass, name)
+ when :privilege
+ privilege = process(exp.shift)
+ includes = process(exp.shift).shift
+ privelege_hash = {
+ :privilege => privilege,
+ :options => includes
+ }
+ s(:call, klass, name, privelege_hash)
else
s(:call, klass, name, process(exp.shift))
end
View
91 lib/declarative_authorization/in_controller.rb
@@ -137,9 +137,9 @@ def filter_access_filter # :nodoc:
end
end
- def load_controller_object (context_without_namespace = nil) # :nodoc:
+ def load_controller_object (context_without_namespace = nil, model = nil) # :nodoc:
instance_var = :"@#{context_without_namespace.to_s.singularize}"
- model = context_without_namespace.to_s.classify.constantize
+ model = model ? model.classify.constantize : context_without_namespace.to_s.classify.constantize
instance_variable_set(instance_var, model.find(params[:id]))
end
@@ -149,16 +149,29 @@ def load_parent_controller_object (parent_context_without_namespace) # :nodoc:
instance_variable_set(instance_var, model.find(params[:"#{parent_context_without_namespace.to_s.singularize}_id"]))
end
- def new_controller_object_from_params (context_without_namespace, parent_context_without_namespace) # :nodoc:
+ def new_controller_object_from_params (context_without_namespace, parent_context_without_namespace, strong_params) # :nodoc:
model_or_proxy = parent_context_without_namespace ?
instance_variable_get(:"@#{parent_context_without_namespace.to_s.singularize}").send(context_without_namespace.to_sym) :
context_without_namespace.to_s.classify.constantize
instance_var = :"@#{context_without_namespace.to_s.singularize}"
instance_variable_set(instance_var,
- model_or_proxy.new(params[context_without_namespace.to_s.singularize]))
+ model_or_proxy.new(params[context_without_namespace.to_s.singularize]))
end
- def new_controller_object_for_collection (context_without_namespace, parent_context_without_namespace) # :nodoc:
+ def new_blank_controller_object (context_without_namespace, parent_context_without_namespace, strong_params, model) # :nodoc:
+ if model
+ model_or_proxy = model.to_s.classify.constantize
+ else
+ model_or_proxy = parent_context_without_namespace ?
+ instance_variable_get(:"@#{parent_context_without_namespace.to_s.singularize}").send(context_without_namespace.to_sym) :
+ context_without_namespace.to_s.classify.constantize
+ end
+ instance_var = :"@#{context_without_namespace.to_s.singularize}"
+ instance_variable_set(instance_var,
+ model_or_proxy.new())
+ end
+
+ def new_controller_object_for_collection (context_without_namespace, parent_context_without_namespace, strong_params) # :nodoc:
model_or_proxy = parent_context_without_namespace ?
instance_variable_get(:"@#{parent_context_without_namespace.to_s.singularize}").send(context_without_namespace.to_sym) :
context_without_namespace.to_s.classify.constantize
@@ -290,7 +303,8 @@ def filter_access_to (*args, &filter_block)
:context => nil,
:attribute_check => false,
:model => nil,
- :load_method => nil
+ :load_method => nil,
+ :strong_parameters => nil
}.merge!(options)
privilege = options[:require]
context = options[:context]
@@ -305,6 +319,7 @@ def filter_access_to (*args, &filter_block)
end
filter_access_permissions <<
ControllerPermission.new(actions, privilege, context,
+ options[:strong_parameters],
options[:attribute_check],
options[:model],
options[:load_method],
@@ -460,6 +475,10 @@ def all_filter_access_permissions # :nodoc:
# See filter_access_to on details. By default, with no +nested_in+,
# +no_attribute_check+ is set to all collections. If +nested_in+ is given
# +no_attribute_check+ is empty by default.
+ # [:+strong_parameters+]
+ # If set to true, relies on controller to provide instance variable and
+ # create new object in :create action. Set true if you use strong_params
+ # and false if you use protected_attributes.
#
def filter_resource_access(options = {})
options = {
@@ -474,8 +493,12 @@ def filter_resource_access(options = {})
#:load_method => nil, # only symbol method name
:no_attribute_check => nil,
:context => nil,
+ :model => nil,
:nested_in => nil,
+ :strong_parameters => nil
}.merge(options)
+ options.merge!({ :strong_parameters => true }) if Rails.version >= '4' && options[:strong_parameters] == nil
+ options.merge!({ :strong_parameters => false }) if Rails.version < '4' && options[:strong_parameters] == nil
new_actions = actions_from_option( options[:new] ).merge(
actions_from_option(options[:additional_new]) )
@@ -484,7 +507,9 @@ def filter_resource_access(options = {})
collections = actions_from_option(options[:collection]).merge(
actions_from_option(options[:additional_collection]))
- options[:no_attribute_check] ||= collections.keys unless options[:nested_in]
+ no_attribute_check_actions = options[:strong_parameters] ? actions_from_option(options[:collection]).merge(actions_from_option([:create])) : collections
+
+ options[:no_attribute_check] ||= no_attribute_check_actions.keys unless options[:nested_in]
unless options[:nested_in].blank?
load_parent_method = :"load_#{options[:nested_in].to_s.singularize}"
@@ -504,37 +529,53 @@ def filter_resource_access(options = {})
controller.send(new_for_collection_method)
else
controller.send(:new_controller_object_for_collection,
- options[:context] || controller_name, options[:nested_in])
+ options[:context] || controller_name, options[:nested_in], options[:strong_parameters])
end
end
end
- new_from_params_method = :"new_#{controller_name.singularize}_from_params"
- before_filter :only => new_actions.keys do |controller|
- # new_from_params
- if controller.respond_to?(new_from_params_method, true)
- controller.send(new_from_params_method)
- else
- controller.send(:new_controller_object_from_params,
- options[:context] || controller_name, options[:nested_in])
+ unless options[:strong_parameters]
+ new_from_params_method = :"new_#{controller_name.singularize}_from_params"
+ before_filter :only => new_actions.keys do |controller|
+ # new_from_params
+ if controller.respond_to?(new_from_params_method, true)
+ controller.send(new_from_params_method)
+ else
+ controller.send(:new_controller_object_from_params,
+ options[:context] || controller_name, options[:nested_in], options[:strong_parameters])
+ end
end
+ else
+ new_object_method = :"new_#{controller_name.singularize}"
+ before_filter :only => :new do |controller|
+ # new_from_params
+ if controller.respond_to?(new_object_method, true)
+ controller.send(new_object_method)
+ else
+ controller.send(:new_blank_controller_object,
+ options[:context] || controller_name, options[:nested_in], options[:strong_parameters], options[:model])
+ end
+ end
end
+
load_method = :"load_#{controller_name.singularize}"
before_filter :only => members.keys do |controller|
# load controller object
if controller.respond_to?(load_method, true)
controller.send(load_method)
else
- controller.send(:load_controller_object, options[:context] || controller_name)
+ controller.send(:load_controller_object, options[:context] || controller_name, options[:model])
end
end
- filter_access_to :all, :attribute_check => true, :context => options[:context]
+ filter_access_to :all, :attribute_check => true, :context => options[:context], :model => options[:model]
members.merge(new_actions).merge(collections).each do |action, privilege|
if action != privilege or (options[:no_attribute_check] and options[:no_attribute_check].include?(action))
filter_options = {
+ :strong_parameters => options[:strong_parameters],
:context => options[:context],
- :attribute_check => !options[:no_attribute_check] || !options[:no_attribute_check].include?(action)
+ :attribute_check => !options[:no_attribute_check] || !options[:no_attribute_check].include?(action),
+ :model => options[:model]
}
filter_options[:require] = privilege if action != privilege
filter_access_to(action, filter_options)
@@ -593,8 +634,8 @@ def actions_from_option (option) # :nodoc:
end
class ControllerPermission # :nodoc:
- attr_reader :actions, :privilege, :context, :attribute_check
- def initialize (actions, privilege, context, attribute_check = false,
+ attr_reader :actions, :privilege, :context, :attribute_check, :strong_params
+ def initialize (actions, privilege, context, strong_params, attribute_check = false,
load_object_model = nil, load_object_method = nil,
filter_block = nil)
@actions = actions.to_set
@@ -604,6 +645,7 @@ def initialize (actions, privilege, context, attribute_check = false,
@load_object_method = load_object_method
@filter_block = filter_block
@attribute_check = attribute_check
+ @strong_params = strong_params
end
def matches? (action_name)
@@ -630,6 +672,7 @@ def remove_actions (actions)
end
private
+
def load_object(contr)
if @load_object_method and @load_object_method.is_a?(Symbol)
contr.send(@load_object_method)
@@ -638,11 +681,12 @@ def load_object(contr)
else
load_object_model = @load_object_model ||
(@context ? @context.to_s.classify.constantize : contr.class.controller_name.classify.constantize)
- instance_var = :"@#{load_object_model.name.underscore}"
+ load_object_model = load_object_model.classify.constantize if load_object_model.is_a?(String)
+ instance_var = "@#{load_object_model.name.demodulize.underscore}"
object = contr.instance_variable_get(instance_var)
unless object
begin
- object = load_object_model.find(contr.params[:id])
+ object = @strong_params ? load_object_model.find_or_initialize_by(:id => contr.params[:id]) : load_object_model.find(contr.params[:id])
rescue => e
contr.logger.debug("filter_access_to tried to find " +
"#{load_object_model} from params[:id] " +
@@ -657,3 +701,4 @@ def load_object(contr)
end
end
end
+
View
3  lib/declarative_authorization/in_model.rb
@@ -104,8 +104,7 @@ def self.with_permissions_to (*args)
options = args.last.is_a?(Hash) ? args.pop : {}
privilege = (args[0] || :read).to_sym
privileges = [privilege]
-
- parent_scope = scoped
+ parent_scope = where(nil)
context =
if options[:context]
options[:context]
View
9 lib/declarative_authorization/obligation_scope.rb
@@ -48,16 +48,19 @@ def initialize (model, options)
if Rails.version < "3"
super(model, options)
else
- super(model, model.table_name)
+ super(model, model.table_name)
end
end
def scope
if Rails.version < "3"
self
- else
- # for Rails < 3: scope, after setting proxy_options
+ elsif Rails.version < "4"
+ # for Rails < 4: use scoped method
self.klass.scoped(@finder_options)
+ else
+ # TODO Refactor this. There is certainly a better way.
+ self.klass.joins(@finder_options[:joins]).includes(@finder_options[:include]).where(@finder_options[:conditions])
end
end
View
77 lib/generators/authorization/install/install_generator.rb
@@ -0,0 +1,77 @@
+require 'rails/generators'
+module Authorization
+ class InstallGenerator < Rails::Generators::Base
+
+ include Rails::Generators::Migration
+ source_root File.expand_path('../templates', __FILE__)
+
+ argument :name, type: :string, default: "User"
+ argument :attributes, type: :array, default: ['name:string'], banner: "field[:type] field[:type]"
+ class_option :create_user, type: :boolean, default: false, desc: "Creates the defined User model with attributes given."
+ class_option :commit, type: :boolean, default: false, desc: "Performs rake tasks such as migrate and seed."
+ class_option :user_belongs_to_role, type: :boolean, default: false, desc: "Users have only one role, which can inherit others roles."
+
+ def self.next_migration_number dirname
+ if ActiveRecord::Base.timestamped_migrations
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
+ else
+ "%.3d" % (current_migration_number(dirname) + 1)
+ end
+ end
+
+ def install_decl_auth
+ habtm_table_name = "#{name.pluralize}" <= "Roles" ? "#{name.pluralize}Roles" : "Roles#{name.pluralize}" unless options[:user_belongs_to_role]
+ habtm_file_glob = "#{name.pluralize}" <= "Roles" ? 'db/migrate/*create_*_roles*' : 'db/migrate/*create_roles_*' unless options[:user_belongs_to_role]
+
+ generate 'model', "#{name} #{attributes.join(' ')}" if options[:create_user]
+ generate 'model', 'Role title:string'
+
+ if options[:user_belongs_to_role]
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", " belongs_to :role\n", after: "ActiveRecord::Base\n"
+ generate 'migration', "AddRoleIdTo#{name.camelcase} role_id:integer"
+ else
+ generate 'migration', "Create#{habtm_table_name} #{name.downcase}:integer role:integer"
+ gsub_file Dir.glob(habtm_file_glob).last, 'integer', 'references'
+ inject_into_file Dir.glob(habtm_file_glob).last, ", id: false", before: ' do |t|'
+ inject_into_file "app/models/role.rb", " has_and_belongs_to_many :#{name.downcase.pluralize}\n", after: "ActiveRecord::Base\n"
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", " has_and_belongs_to_many :roles\n", after: "ActiveRecord::Base\n"
+ end
+
+ rake 'db:migrate' if options[:commit]
+
+ if options[:user_belongs_to_role]
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", before: "\nend" do <<-'RUBY'
+
+
+ def role_symbols
+ [role.title.to_sym]
+ end
+ RUBY
+ end
+ else
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", before: "\nend" do <<-'RUBY'
+
+
+ def role_symbols
+ (roles || []).map {|r| r.title.to_sym}
+ end
+ RUBY
+ end
+ end
+
+ inject_into_file 'db/seeds.rb', after: ".first)\n" do <<-'RUBY'
+
+roles = Role.create([
+ {title: 'admin'},
+ {title: 'user'}
+]) if Role.count == 0
+RUBY
+ end
+
+ rake 'db:seed' if options[:commit]
+
+ generate 'authorization:rules'
+ puts "Please run `rake db:migrate` and `rake db:seed` to finish installing." unless options[:commit]
+ end
+ end
+end
View
14 lib/generators/authorization/rules/rules_generator.rb
@@ -0,0 +1,14 @@
+require 'rails/generators'
+module Authorization
+ class RulesGenerator < Rails::Generators::Base
+
+ source_root File.expand_path('../templates', __FILE__)
+
+ def copy_auth_rules
+
+ puts "WARNING - Copying authorization_rules template. Make sure to back up any existing rules before overwriting."
+
+ copy_file "authorization_rules.rb", "config/authorization_rules.rb"
+ end
+ end
+end
View
27 lib/generators/authorization/rules/templates/authorization_rules.rb
@@ -0,0 +1,27 @@
+authorization do
+ role :guest do
+ # add permissions for guests here, e.g.
+ # has_permission_on :conferences, :to => :read
+ end
+
+ # permissions on other roles, such as
+ # role :admin do
+ # has_permission_on :conferences, :to => :manage
+ # end
+ # role :user do
+ # has_permission_on :conferences, :to => [:read, :create]
+ # has_permission_on :conferences, :to => [:update, :delete] do
+ # if_attribute :user_id => is {user.id}
+ # end
+ # end
+ # See the readme or GitHub for more examples
+end
+
+privileges do
+ # default privilege hierarchies to facilitate RESTful Rails apps
+ privilege :manage, :includes => [:create, :read, :update, :delete]
+ privilege :read, :includes => [:index, :show]
+ privilege :create, :includes => :new
+ privilege :update, :includes => :edit
+ privilege :delete, :includes => :destroy
+end
View
76 test/controller_filter_resource_access_test.rb
@@ -6,7 +6,7 @@ def self.name
end
end
class BasicResourcesController < MocksController
- filter_resource_access
+ filter_resource_access :strong_parameters => false
define_resource_actions
end
class BasicResourcesControllerTest < ActionController::TestCase
@@ -117,7 +117,7 @@ def self.name
end
class NestedResourcesController < MocksController
- filter_resource_access :nested_in => :parent_mocks
+ filter_resource_access :nested_in => :parent_mocks, :strong_parameters => false
define_resource_actions
end
class NestedResourcesControllerTest < ActionController::TestCase
@@ -190,7 +190,8 @@ def test_nested_filter_new_with_params
class ShallowNestedResourcesController < MocksController
filter_resource_access :nested_in => :parent_mocks,
:shallow => true,
- :additional_member => :additional_member_action
+ :additional_member => :additional_member_action,
+ :strong_parameters => false
define_resource_actions
define_action_methods :additional_member_action
end
@@ -294,7 +295,7 @@ def self.controller_name
"basic_resources"
end
filter_resource_access :member => [[:other_show, :read]],
- :collection => {:search => :read}, :new => [:other_new]
+ :collection => {:search => :read}, :new => [:other_new], :strong_parameters => false
define_action_methods :other_new, :search, :other_show
end
class CustomMembersCollectionsResourceControllerTest < ActionController::TestCase
@@ -362,7 +363,7 @@ def self.controller_name
"basic_resources"
end
filter_resource_access :additional_member => :other_show,
- :additional_collection => [:search], :additional_new => {:other_new => :new}
+ :additional_collection => [:search], :additional_new => {:other_new => :new}, :strong_parameters => false
define_resource_actions
define_action_methods :other_new, :search, :other_show
end
@@ -447,7 +448,7 @@ class CustomMethodsResourceController < MocksController
class ExplicitContextResourceController < MocksController
- filter_resource_access :context => :basic_resources
+ filter_resource_access :context => :basic_resources, :strong_parameters => false
define_resource_actions
end
class ExplicitContextResourceControllerTest < ActionController::TestCase
@@ -509,3 +510,66 @@ def test_explicit_context_filter_new_with_params
assert @controller.authorized?
end
end
+
+if Rails.version >= '4'
+
+ class StrongResource < MockDataObject
+ def self.name
+ "StrongResource"
+ end
+ end
+
+ class StrongResourcesController < MocksController
+ def self.controller_name
+ "strong_resources"
+ end
+ filter_resource_access :strong_parameters => true
+ define_resource_actions
+
+ private
+ def strong_resource_params
+ params.require(:strong_resource).permit(:test_param1, :test_param2)
+ end
+ end
+ class StrongResourcesControllerTest < ActionController::TestCase
+ def test_still_authorized_with_strong_params
+ reader = Authorization::Reader::DSLReader.new
+ reader.parse %{
+ authorization do
+ role :allowed_role do
+ has_permission_on :strong_resources, :to => :show do
+ if_attribute :id => "1"
+ end
+ end
+ end
+ }
+
+ allowed_user = MockUser.new(:allowed_role)
+ request!(allowed_user, :show, reader, :id => "2")
+ assert !@controller.authorized?
+ request!(allowed_user, :show, reader, :id => "1", :clear => [:@strong_resource])
+ assert @controller.authorized?
+ end
+
+ def test_new_strong_resource
+ reader = Authorization::Reader::DSLReader.new
+ reader.parse %{
+ authorization do
+ role :allowed_role do
+ has_permission_on :strong_resources, :to => :new
+ end
+ end
+ }
+
+ allowed_user = MockUser.new(:allowed_role)
+ request!(allowed_user, :new, reader, :strong_resource => {:id => "1"},
+ :clear => [:@strong_resource])
+ assert @controller.authorized?
+
+ # allowed_user = MockUser.new(:allowed_role)
+ # request!(allowed_user, :new, reader, :strong_resource => {:id => "1"}, :clear => [:@strong_resource])
+ # assert @controller.authorized?
+ # assert assigns :strong_resource
+ end
+ end
+end
View
3  test/development_support/analyzer_test.rb
@@ -42,7 +42,8 @@ def test_analyzing_complex_rules
if_attribute :talk => { :conference => { :attendees => contains {user} }}
end
has_permission_on :talk_attendees, :to => :delete do
- if_attribute :user => is {user}
+ if_attribute :user => is {user},
+ :talk => { :conference => { :attendees => contains {user} }}
end
end
View
148 test/model_test.rb
@@ -17,16 +17,31 @@ class TestModel < ActiveRecord::Base
has_many :test_attrs
has_many :test_another_attrs, :class_name => "TestAttr", :foreign_key => :test_another_model_id
has_many :test_attr_throughs, :through => :test_attrs
- has_many :test_attrs_with_attr, :class_name => "TestAttr", :conditions => {:attr => 1}
- has_many :test_attr_throughs_with_attr, :through => :test_attrs,
- :class_name => "TestAttrThrough", :source => :test_attr_throughs,
- :conditions => "test_attrs.attr = 1"
has_one :test_attr_has_one, :class_name => "TestAttr"
- has_one :test_attr_throughs_with_attr_and_has_one, :through => :test_attrs,
- :class_name => "TestAttrThrough", :source => :test_attr_throughs,
- :conditions => "test_attrs.attr = 1"
+ has_many :branches
+
+ # :conditions is deprecated in Rails 4.1
+ if Rails.version >= '4'
+ has_many :test_attrs_with_attr, lambda { where(:attr => 1) }, :class_name => "TestAttr"
+ has_many :test_attr_throughs_with_attr, lambda { where("test_attrs.attr = 1") }, :through => :test_attrs,
+ :class_name => "TestAttrThrough", :source => :test_attr_throughs
- attr_accessible :content, :test_attr_through_id, :country_id
+ has_one :test_attr_throughs_with_attr_and_has_one, lambda { where("test_attrs.attr = 1") }, :through => :test_attrs,
+ :class_name => "TestAttrThrough", :source => :test_attr_throughs
+ else
+ has_many :test_attrs_with_attr, :class_name => "TestAttr", :conditions => {:attr => 1}
+ has_many :test_attr_throughs_with_attr, :through => :test_attrs,
+ :class_name => "TestAttrThrough", :source => :test_attr_throughs,
+ :conditions => "test_attrs.attr = 1"
+
+ has_one :test_attr_throughs_with_attr_and_has_one, :through => :test_attrs,
+ :class_name => "TestAttrThrough", :source => :test_attr_throughs,
+ :conditions => "test_attrs.attr = 1"
+ end
+
+ if Rails.version < '4'
+ attr_accessible :content, :test_attr_through_id, :country_id
+ end
# TODO currently not working in Rails 3
if Rails.version < "3"
@@ -36,8 +51,10 @@ class TestModel < ActiveRecord::Base
if Rails.version < "3"
named_scope :with_content, :conditions => "test_models.content IS NOT NULL"
- else
+ elsif Rails.version < "4"
scope :with_content, :conditions => "test_models.content IS NOT NULL"
+ else
+ scope :with_content, lambda { where("test_models.content IS NOT NULL") }
end
# Primary key test
@@ -75,9 +92,13 @@ class TestAttr < ActiveRecord::Base
has_many :test_attr_throughs
has_many :test_model_security_model_with_finds
attr_reader :role_symbols
- attr_accessible :test_model, :test_another_model, :attr, :branch, :company, :test_attr,
- :test_a_third_model, :n_way_join_item, :n_way_join_item_id, :test_attr_through_id,
- :test_model_id, :test_another_model_id
+
+ if Rails.version < '4'
+ attr_accessible :test_model, :test_another_model, :attr, :branch, :company, :test_attr,
+ :test_a_third_model, :n_way_join_item, :n_way_join_item_id, :test_attr_through_id,
+ :test_model_id, :test_another_model_id
+ end
+
def initialize (*args)
@role_symbols = []
super(*args)
@@ -91,7 +112,10 @@ class TestAttrThrough < ActiveRecord::Base
class TestModelSecurityModel < ActiveRecord::Base
has_many :test_attrs
using_access_control
- attr_accessible :attr, :attr_2, :test_attrs
+
+ if Rails.version < '4'
+ attr_accessible :attr, :attr_2, :test_attrs
+ end
end
class TestModelSecurityModelWithFind < ActiveRecord::Base
if Rails.version < "3.2"
@@ -103,19 +127,29 @@ class TestModelSecurityModelWithFind < ActiveRecord::Base
belongs_to :test_attr
using_access_control :include_read => true,
:context => :test_model_security_models
- attr_accessible :test_attr, :attr
+
+ if Rails.version < '4'
+ attr_accessible :test_attr, :attr
+ end
end
class Branch < ActiveRecord::Base
has_many :test_attrs
belongs_to :company
- attr_accessible :name, :company
+ belongs_to :test_model
+
+ if Rails.version < '4'
+ attr_accessible :name, :company, :test_model
+ end
end
class Company < ActiveRecord::Base
has_many :test_attrs
has_many :branches
belongs_to :country
- attr_accessible :name, :country, :country_id
+
+ if Rails.version < '4'
+ attr_accessible :name, :country, :country_id
+ end
end
class SmallCompany < Company
def self.decl_auth_context
@@ -125,7 +159,10 @@ def self.decl_auth_context
class Country < ActiveRecord::Base
has_many :test_models
has_many :companies
- attr_accessible :name
+
+ if Rails.version < '4'
+ attr_accessible :name
+ end
end
class NamedScopeModelTest < Test::Unit::TestCase
@@ -149,7 +186,12 @@ def test_multiple_deep_ored_belongs_to
:test_another_model_id => test_model_2.id
user = MockUser.new(:test_role, :id => test_attr_1)
- assert_equal 1, TestAttr.with_permissions_to(:read, :user => user).length
+ if Rails.version >= '4'
+ assert_equal 1, TestAttr.with_permissions_to(:read, :user => user).references(:test_attrs, :test_attrs_test_models, :test_attrs_test_models_2).length
+ else
+ assert_equal 1, TestAttr.with_permissions_to(:read, :user => user).length
+ end
+
TestAttr.delete_all
TestModel.delete_all
end
@@ -328,7 +370,7 @@ def test_named_scope_on_named_scope
assert_equal 1, TestModel.query_count if Rails.version < "3"
TestModel.query_count = 0
- assert_equal 1, TestModel.with_permissions_to(:read, :user => user).with_content.length
+ assert_equal 1, TestModel.with_permissions_to(:read, :user => user).with_content.length if Rails.version < "4"
assert_equal 1, TestModel.query_count if Rails.version < "3"
TestModel.query_count = 0
@@ -781,7 +823,11 @@ def test_with_contains
user = MockUser.new(:test_role,
:id => test_model_1.test_attrs.first.id)
assert_equal 1, TestModel.with_permissions_to(:read, :user => user).length
- assert_equal 1, TestModel.with_permissions_to(:read, :user => user).find(:all, :conditions => {:id => test_model_1.id}).length
+ if Rails.version < '3'
+ assert_equal 1, TestModel.with_permissions_to(:read, :user => user).find(:all, :conditions => {:id => test_model_1.id} ).length
+ else
+ assert_equal 1, TestModel.with_permissions_to(:read, :user => user).where(:id => test_model_1.id).length
+ end
TestModel.delete_all
TestAttr.delete_all
@@ -1164,7 +1210,11 @@ def test_with_anded_if_permitted_to
assert Authorization::Engine.instance.permit?(:read, :object => test_model_1.test_attrs.first, :user => user_with_both_roles)
assert Authorization::Engine.instance.permit?(:read, :object => test_model_for_second_role.test_attrs.first, :user => user_with_both_roles)
#p Authorization::Engine.instance.obligations(:read, :user => user_with_both_roles, :context => :test_attrs)
- assert_equal 2, TestAttr.with_permissions_to(:read, :user => user_with_both_roles).length
+ if Rails.version >= '4'
+ assert_equal 2, TestAttr.with_permissions_to(:read, :user => user_with_both_roles).references(:test_attrs, :test_models).length
+ else
+ assert_equal 1, TestAttr.with_permissions_to(:read, :user => user).length
+ end
TestModel.delete_all
TestAttr.delete_all
@@ -1425,7 +1475,11 @@ def test_with_ored_rules_and_reoccuring_tables
test_attr_2.test_model.test_attrs.create!
user = MockUser.new(:test_role, :test_attr => test_attr_2.test_model.test_attrs.last)
- assert_equal 2, TestAttr.with_permissions_to(:read, :user => user).length
+ if Rails.version >= '4'
+ assert_equal 2, TestAttr.with_permissions_to(:read, :user => user).references(:test_attrs, :test_models, :test_models_test_attrs, :test_attrs_test_models).length
+ else
+ assert_equal 2, TestAttr.with_permissions_to(:read, :user => user).length
+ end
TestModel.delete_all
TestAttr.delete_all
end
@@ -1462,7 +1516,11 @@ def test_with_many_ored_rules_and_reoccuring_tables
user = MockUser.new(:test_role, :test_model => country.test_models.first)
- assert_equal 2, TestAttr.with_permissions_to(:read, :user => user).length
+ if Rails.version >= '4'
+ assert_equal 2, TestAttr.with_permissions_to(:read, :user => user).references(:test_attrs, :test_models, :test_models_countries).length
+ else
+ assert_equal 2, TestAttr.with_permissions_to(:read, :user => user).length
+ end
TestModel.delete_all
TestAttr.delete_all
end
@@ -1801,12 +1859,48 @@ def test_authorization_permit_association_proxy
test_model = TestModel.create(:content => "content")
assert engine.permit?(:read, :object => test_model.test_attrs,
:user => MockUser.new(:test_role))
- assert test_model.test_attrs.empty?
assert !engine.permit?(:read, :object => TestAttr.new,
:user => MockUser.new(:test_role))
TestModel.delete_all
end
+ def test_authorization_permit_nested_association_proxy
+ reader = Authorization::Reader::DSLReader.new
+ reader.parse %{
+ authorization do
+ role :test_role do
+ has_permission_on :branches, :to => :read do
+ if_attribute :test_model => { :test_attrs => {:attr => 1 } }
+ end
+ end
+ end
+ }
+ engine = Authorization::Engine.instance(reader)
+
+ test_model = TestModel.create!
+ test_model.test_attrs.create!(:attr => 0)
+ test_attr = test_model.test_attrs.create!(:attr => 1)
+ test_model.test_attrs.create!(:attr => 3)
+ test_branch = Branch.create!(:test_model => test_model)
+
+ test_model_2 = TestModel.create!
+ test_attr_2 = test_model_2.test_attrs.create!(:attr => 2)
+ test_branch_2 = Branch.create!(:test_model => test_model_2)
+
+ test_model_3 = TestModel.create!
+ test_branch_3 = Branch.create!(:test_model => test_model_3)
+
+ assert engine.permit?(:read, :object => test_branch,
+ :user => MockUser.new(:test_role))
+ assert !engine.permit?(:read, :object => test_branch_2,
+ :user => MockUser.new(:test_role))
+ assert !engine.permit?(:read, :object => test_branch_3,
+ :user => MockUser.new(:test_role))
+ TestModel.delete_all
+ Branch.delete_all
+ TestAttr.delete_all
+ end
+
def test_multiple_roles_with_has_many_through
reader = Authorization::Reader::DSLReader.new
reader.parse %{
@@ -1839,7 +1933,11 @@ def test_multiple_roles_with_has_many_through
user = MockUser.new(:test_role_1, :test_role_2,
:test_attr_through_id => test_model_1.test_attr_throughs.first.id,
:test_attr_through_2_id => test_model_2.test_attr_throughs.first.id)
- assert_equal 2, TestModel.with_permissions_to(:read, :user => user).length
+ if Rails.version >= '4'
+ assert_equal 2, TestModel.with_permissions_to(:read, :user => user).references(:test_models, :test_attr_throughs).length
+ else
+ assert_equal 2, TestModel.with_permissions_to(:read, :user => user).length
+ end
TestModel.delete_all
TestAttr.delete_all
TestAttrThrough.delete_all
View
1  test/schema.sql
@@ -39,6 +39,7 @@ CREATE TABLE 'n_way_join_items' (
CREATE TABLE 'branches' (
'id' INTEGER PRIMARY KEY NOT NULL,
'company_id' integer,
+ 'test_model_id' integer,
'name' text
);
View
131 test/test_helper.rb
@@ -1,4 +1,3 @@
-require 'test/unit'
require 'pathname'
ENV['RAILS_ENV'] = 'test'
@@ -13,9 +12,23 @@
end
Bundler.require
+if Rails.version >= '4.1'
+ require 'minitest/autorun'
+ require 'test_support/minitest_compatibility'
+else
+ require 'test/unit'
+end
+
# rails 2.3 and ruby 1.9.3 fix
MissingSourceFile::REGEXPS.push([/^cannot load such file -- (.+)$/i, 1])
+# Silence Rails 4 deprecation warnings in test suite
+# TODO: Model.scoped is deprecated
+# TODO: Eager loading Post.includes(:comments).where("comments.title = 'foo'") becomes Post.includes(:comments).where("comments.title = 'foo'").references(:comments)
+# if Rails.version >= '4'
+# ActiveSupport::Deprecation.silenced = true
+# end
+
puts "Testing against rails #{Rails::VERSION::STRING}"
RAILS_ROOT = File.dirname(__FILE__)
@@ -58,6 +71,11 @@ def self.find(*args)
raise StandardError, "Couldn't find #{self.name} with id #{args[0].inspect}" unless args[0]
new :id => args[0]
end
+
+ def self.find_or_initialize_by(args)
+ raise StandardError, "Syntax error: find_or_initialize by expects a hash: User.find_or_initialize_by(:id => @user.id)" unless args.is_a?(Hash)
+ new :id => args[:id]
+ end
end
class MockUser < MockDataObject
@@ -114,6 +132,7 @@ def warn?; end
else
class TestApp
class Application < ::Rails::Application
+ config.secret_key_base = "testingpurposesonly"
config.active_support.deprecation = :stderr
database_path = File.expand_path('../database.yml', __FILE__)
if Rails.version.start_with? '3.0.'
@@ -127,10 +146,23 @@ class Application < ::Rails::Application
class ApplicationController < ActionController::Base
end
#Rails::Application.routes.draw do
- Rails.application.routes.draw do
- match '/name/spaced_things(/:action)' => 'name/spaced_things'
- match '/deep/name_spaced/things(/:action)' => 'deep/name_spaced/things'
- match '/:controller(/:action(/:id))'
+ if Rails.version.start_with? '4'
+ Rails.application.routes.draw do
+ match '/name/spaced_things(/:action)' => 'name/spaced_things', :via => [:get, :post, :put, :patch, :delete]
+ match '/deep/name_spaced/things(/:action)' => 'deep/name_spaced/things', :via => [:get, :post, :put, :patch, :delete]
+ match '/:controller(/:action(/:id))', :via => [:get, :post, :put, :patch, :delete]
+ end
+ class TestApp
+ class Application < ::Rails::Application
+ config.secret_key_base = 'thisstringdoesnothing'
+ end
+ end
+ else
+ Rails.application.routes.draw do
+ match '/name/spaced_things(/:action)' => 'name/spaced_things'
+ match '/deep/name_spaced/things(/:action)' => 'deep/name_spaced/things'
+ match '/:controller(/:action(/:id))'
+ end
end
end
@@ -139,24 +171,85 @@ class ApplicationController < ActionController::Base
require "action_controller/test_process"
end
-class Test::Unit::TestCase
- include Authorization::TestHelper
-
- def request! (user, action, reader, params = {})
- action = action.to_sym if action.is_a?(String)
- @controller.current_user = user
- @controller.authorization_engine = Authorization::Engine.new(reader)
+
+if Rails.version < "4"
+ class Test::Unit::TestCase
+ include Authorization::TestHelper
+
+ def request! (user, action, reader, params = {})
+ action = action.to_sym if action.is_a?(String)
+ @controller.current_user = user
+ @controller.authorization_engine = Authorization::Engine.new(reader)
+
+ ((params.delete(:clear) || []) + [:@authorized]).each do |var|
+ @controller.instance_variable_set(var, nil)
+ end
+ get action, params
+ end
+
+ unless Rails.version < "3"
+ def setup
+ #@routes = Rails::Application.routes
+ @routes = Rails.application.routes
+ end
+ end
+ end
+
+elsif Rails.version < '4.1'
+ class Test::Unit::TestCase
+ include Authorization::TestHelper
+ end
+
+ class ActiveSupport::TestCase
+ include Authorization::TestHelper
- ((params.delete(:clear) || []) + [:@authorized]).each do |var|
- @controller.instance_variable_set(var, nil)
+ def request! (user, action, reader, params = {})
+ action = action.to_sym if action.is_a?(String)
+ @controller.current_user = user
+ @controller.authorization_engine = Authorization::Engine.new(reader)
+
+ ((params.delete(:clear) || []) + [:@authorized]).each do |var|
+ @controller.instance_variable_set(var, nil)
+ end
+ get action, params
+ end
+
+ unless Rails.version < "3"
+ def setup
+ #@routes = Rails::Application.routes
+ @routes = Rails.application.routes
+ end
+ end
+ end
+else
+ module Test
+ module Unit
end
- get action, params
end
- unless Rails.version < "3"
- def setup
- #@routes = Rails::Application.routes
- @routes = Rails.application.routes
+ class Test::Unit::TestCase < Minitest::Test
+ include Authorization::TestHelper
+ end
+
+ class ActiveSupport::TestCase
+ include Authorization::TestHelper
+
+ def request! (user, action, reader, params = {})
+ action = action.to_sym if action.is_a?(String)
+ @controller.current_user = user
+ @controller.authorization_engine = Authorization::Engine.new(reader)
+
+ ((params.delete(:clear) || []) + [:@authorized]).each do |var|
+ @controller.instance_variable_set(var, nil)
+ end
+ get action, params
+ end
+
+ unless Rails.version < "3"
+ def setup
+ #@routes = Rails::Application.routes
+ @routes = Rails.application.routes
+ end
end
end
end
View
27 test/test_support/minitest_compatibility.rb
@@ -0,0 +1,27 @@
+require 'minitest/assertions'
+
+module Minitest
+ module Assertions
+
+ # test/unit backwards compatibility methods
+ alias :assert_raise :assert_raises
+ alias :assert_not_empty :refute_empty
+ alias :assert_not_equal :refute_equal
+ alias :assert_not_in_delta :refute_in_delta
+ alias :assert_not_in_epsilon :refute_in_epsilon
+ alias :assert_not_includes :refute_includes
+ alias :assert_not_instance_of :refute_instance_of
+ alias :assert_not_kind_of :refute_kind_of
+ alias :assert_no_match :refute_match
+ alias :assert_not_nil :refute_nil
+ alias :assert_not_operator :refute_operator
+ alias :assert_not_predicate :refute_predicate
+ alias :assert_not_respond_to :refute_respond_to
+ alias :assert_not_same :refute_same
+
+ def assert_nothing_raised(*)
+ yield
+ end
+
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.