cancancan 1.7.1 → 1.8.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -3
- data/Appraisals +50 -4
- data/CHANGELOG.rdoc +12 -1
- data/README.rdoc +12 -2
- data/Rakefile +0 -2
- data/cancancan.gemspec +3 -2
- data/gemfiles/activerecord_3.0.gemfile +18 -0
- data/gemfiles/{rails_3.0.gemfile → activerecord_3.1.gemfile} +2 -4
- data/gemfiles/activerecord_3.2.gemfile +16 -0
- data/gemfiles/{rails_3.0_datamapper.gemfile → datamapper_1.x.gemfile} +2 -1
- data/gemfiles/{rails_3.0_mongoid.gemfile → mongoid_2.x.gemfile} +6 -1
- data/gemfiles/sequel_3.x.gemfile +17 -0
- data/lib/cancan.rb +1 -0
- data/lib/cancan/ability.rb +24 -4
- data/lib/cancan/controller_resource.rb +6 -2
- data/lib/cancan/model_adapters/sequel_adapter.rb +87 -0
- data/lib/cancan/rule.rb +29 -24
- data/lib/cancan/version.rb +1 -1
- data/lib/cancancan.rb +3 -0
- data/spec/cancan/ability_spec.rb +26 -0
- data/spec/cancan/controller_resource_spec.rb +520 -447
- data/spec/cancan/inherited_resource_spec.rb +49 -38
- data/spec/cancan/model_adapters/active_record_adapter_spec.rb +106 -92
- data/spec/cancan/model_adapters/sequel_adapter_spec.rb +148 -0
- data/spec/spec_helper.rb +6 -61
- data/spec/support/ability.rb +7 -0
- metadata +41 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7079b16052c2f98ebe67d6ce08e390188bca856d
|
4
|
+
data.tar.gz: faa43141ca3124dbe3d40ceb30a76ca78bc56117
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8168024035574501d8bef61033f458facb1b7173ed98d901b9b51aedc0c659470f6210beb308273de9cd437e4d75027eb39321f104a9e8dc8f933593f1a67aa1
|
7
|
+
data.tar.gz: e71e7aa4f2a66f0f660aa9ce224dff3c0de2efc3b0fb85d461113175e5349700bf4475f5f9ca7abf16c56457488a33b3b5d954e753b021f162428c5827e28cd5
|
data/.travis.yml
CHANGED
@@ -8,9 +8,12 @@ rvm:
|
|
8
8
|
- jruby
|
9
9
|
- rbx
|
10
10
|
gemfile:
|
11
|
-
- gemfiles/
|
12
|
-
- gemfiles/
|
13
|
-
- gemfiles/
|
11
|
+
- gemfiles/activerecord_3.0.gemfile
|
12
|
+
- gemfiles/activerecord_3.1.gemfile
|
13
|
+
- gemfiles/activerecord_3.2.gemfile
|
14
|
+
- gemfiles/datamapper_1.x.gemfile
|
15
|
+
- gemfiles/mongoid_2.x.gemfile
|
16
|
+
- gemfiles/sequel_3.x.gemfile
|
14
17
|
services:
|
15
18
|
- mongodb
|
16
19
|
matrix:
|
data/Appraisals
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
appraise "
|
1
|
+
appraise "activerecord_3.0" do
|
2
2
|
gem "activerecord", "~> 3.0.20", :require => "active_record"
|
3
|
-
gem
|
3
|
+
gem 'activesupport', '~> 3.0.20', :require => 'active_support/all'
|
4
4
|
gem "meta_where"
|
5
5
|
|
6
6
|
gemfile.platforms :jruby do
|
@@ -13,16 +13,62 @@ appraise "rails_3.0" do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
appraise "
|
16
|
+
appraise "activerecord_3.1" do
|
17
|
+
gem "activerecord", "~> 3.1.0", :require => "active_record"
|
18
|
+
|
19
|
+
gemfile.platforms :jruby do
|
20
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
21
|
+
gem "jdbc-sqlite3"
|
22
|
+
end
|
23
|
+
|
24
|
+
gemfile.platforms :ruby, :mswin, :mingw do
|
25
|
+
gem "sqlite3"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
appraise "activerecord_3.2" do
|
30
|
+
gem "activerecord", "~> 3.2.0", :require => "active_record"
|
31
|
+
|
32
|
+
gemfile.platforms :jruby do
|
33
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
34
|
+
gem "jdbc-sqlite3"
|
35
|
+
end
|
36
|
+
|
37
|
+
gemfile.platforms :ruby, :mswin, :mingw do
|
38
|
+
gem "sqlite3"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
appraise "datamapper_1.x" do
|
43
|
+
gem 'activesupport', '~> 3.0', :require => 'active_support/all'
|
17
44
|
gem "dm-core", "~> 1.0.2"
|
18
45
|
gem "dm-sqlite-adapter", "~> 1.0.2"
|
19
46
|
gem "dm-migrations", "~> 1.0.2"
|
20
47
|
end
|
21
48
|
|
22
|
-
appraise "
|
49
|
+
appraise "mongoid_2.x" do
|
50
|
+
gem 'activesupport', '~> 3.0', :require => 'active_support/all'
|
23
51
|
gem "mongoid", "~> 2.0.0"
|
24
52
|
|
25
53
|
gemfile.platforms :ruby, :mswin, :mingw do
|
26
54
|
gem "bson_ext", "~> 1.1"
|
27
55
|
end
|
56
|
+
|
57
|
+
gemfile.platforms :jruby do
|
58
|
+
gem "mongo", "~> 1.9.2"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
appraise "sequel_3.x" do
|
63
|
+
gem "sequel", "~> 3.47.0"
|
64
|
+
gem 'activesupport', '~> 3.0', :require => 'active_support/all'
|
65
|
+
|
66
|
+
gemfile.platforms :jruby do
|
67
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
68
|
+
gem "jdbc-sqlite3"
|
69
|
+
end
|
70
|
+
|
71
|
+
gemfile.platforms :ruby, :mswin, :mingw do
|
72
|
+
gem "sqlite3"
|
73
|
+
end
|
28
74
|
end
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
|
1
|
+
Develop
|
2
|
+
|
3
|
+
|
4
|
+
1.8.0 (May 8th, 2014)
|
5
|
+
|
6
|
+
* Feature cancan#884 - Add a Sequel model adapter (szetobo)
|
7
|
+
|
8
|
+
* Feature cancancan#3 - Permit "can?" check multiple subjects (cefigueiredo)
|
9
|
+
|
10
|
+
* Feature cancancan#29 - Add ability to use a String that will get instance_eval'd or a Proc that will get called as the parameter method option for strong_parameter santization (svoop)
|
11
|
+
|
12
|
+
* Feature cancancan#48 - Define a CanCanCan module. Even though it is not used, it is standard practice to define the module, and helpful for determining between CanCanCan and CanCan for external libraries.
|
2
13
|
|
3
14
|
|
4
15
|
1.7.1 (March 19th, 2014)
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= CanCanCan
|
2
2
|
{<img src="https://badge.fury.io/rb/cancancan.png" alt="Gem Version" />}[http://badge.fury.io/rb/cancancan]
|
3
3
|
{<img src="https://travis-ci.org/CanCanCommunity/cancancan.png?branch=master" alt="Build Status" />}[https://travis-ci.org/CanCanCommunity/cancancan]
|
4
|
-
{<img src="https://codeclimate.com/github/
|
4
|
+
{<img src="https://codeclimate.com/github/CanCanCommunity/cancancan.png" />}[https://codeclimate.com/github/CanCanCommunity/cancancan]
|
5
5
|
{<img src="http://inch-pages.github.io/github/CanCanCommunity/cancancan.png" alt="Inline docs" />}[http://inch-pages.github.io/github/CanCanCommunity/cancancan]
|
6
6
|
|
7
7
|
Wiki[https://github.com/bryanrite/cancancan/wiki] | RDocs[http://rdoc.info/projects/ryanb/cancan] | Screencast[http://railscasts.com/episodes/192-authorization-with-cancan]
|
@@ -22,7 +22,7 @@ Any help is greatly appreciated, feel free to submit pull-requests or open issue
|
|
22
22
|
|
23
23
|
In <b>Rails 3 and 4</b>, add this to your Gemfile and run the +bundle+ command.
|
24
24
|
|
25
|
-
gem 'cancancan', '~> 1.
|
25
|
+
gem 'cancancan', '~> 1.8'
|
26
26
|
|
27
27
|
In <b>Rails 2</b>, add this to your environment.rb file.
|
28
28
|
|
@@ -98,6 +98,8 @@ By default, CanCan will try to sanitize the input on <tt>:create</tt> and <tt>:u
|
|
98
98
|
|
99
99
|
Additionally, <tt>load_and_authorize_resource</tt> can now take a <tt>param_method</tt> option to specify a custom method in the controller to run to sanitize input.
|
100
100
|
|
101
|
+
You can associate the <tt>param_method</tt> option with a symbol corresponding to the name of a method that will get called:
|
102
|
+
|
101
103
|
class ArticlesController < ApplicationController
|
102
104
|
load_and_authorize_resource param_method: :my_sanitizer
|
103
105
|
|
@@ -116,6 +118,14 @@ Additionally, <tt>load_and_authorize_resource</tt> can now take a <tt>param_meth
|
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
121
|
+
You can also use a string that will be evaluated in the context of the controller using <tt>instance_eval</tt> and needs to contain valid Ruby code. This does come in handy when using a PermittedParams class as suggested in Railscast 371:
|
122
|
+
|
123
|
+
load_and_authorize_resource param_method: 'permitted_params.article'
|
124
|
+
|
125
|
+
Finally, it's possible to associate <tt>param_method</tt> with a Proc object which will be called with the controller as the only argument:
|
126
|
+
|
127
|
+
load_and_authorize_resource param_method: Proc.new { |c| c.params.require(:article).permit(:name) }
|
128
|
+
|
119
129
|
See {Strong Parameters}[https://github.com/bryanrite/cancancan/wiki/Strong-Parameters] for more information.
|
120
130
|
|
121
131
|
=== 3. Handle Unauthorized Access
|
data/Rakefile
CHANGED
data/cancancan.gemspec
CHANGED
@@ -22,9 +22,10 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
|
23
23
|
s.required_rubygems_version = ">= 1.3.4"
|
24
24
|
|
25
|
+
s.add_development_dependency 'bundler', '~> 1.3'
|
26
|
+
s.add_development_dependency 'rake', '~> 10.1.1'
|
25
27
|
s.add_development_dependency 'rspec', '~> 2.14'
|
26
|
-
s.add_development_dependency '
|
27
|
-
s.add_development_dependency 'appraisal', '>= 1.0.0.beta3'
|
28
|
+
s.add_development_dependency 'appraisal', '>= 1.0.0'
|
28
29
|
|
29
30
|
s.rubyforge_project = s.name
|
30
31
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "activerecord", "~> 3.0.20", :require => "active_record"
|
6
|
+
gem "activesupport", "~> 3.0.20", :require => "active_support/all"
|
7
|
+
gem "meta_where"
|
8
|
+
|
9
|
+
platforms :jruby do
|
10
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
11
|
+
gem "jdbc-sqlite3"
|
12
|
+
end
|
13
|
+
|
14
|
+
platforms :ruby, :mswin, :mingw do
|
15
|
+
gem "sqlite3"
|
16
|
+
end
|
17
|
+
|
18
|
+
gemspec :path => "../"
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "activerecord", "~> 3.0
|
6
|
-
gem "with_model", "~> 0.2.5"
|
7
|
-
gem "meta_where"
|
5
|
+
gem "activerecord", "~> 3.1.0", :require => "active_record"
|
8
6
|
|
9
7
|
platforms :jruby do
|
10
8
|
gem "activerecord-jdbcsqlite3-adapter"
|
@@ -15,4 +13,4 @@ platforms :ruby, :mswin, :mingw do
|
|
15
13
|
gem "sqlite3"
|
16
14
|
end
|
17
15
|
|
18
|
-
gemspec :path=>"
|
16
|
+
gemspec :path => "../"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "activerecord", "~> 3.2.0", :require => "active_record"
|
6
|
+
|
7
|
+
platforms :jruby do
|
8
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
9
|
+
gem "jdbc-sqlite3"
|
10
|
+
end
|
11
|
+
|
12
|
+
platforms :ruby, :mswin, :mingw do
|
13
|
+
gem "sqlite3"
|
14
|
+
end
|
15
|
+
|
16
|
+
gemspec :path => "../"
|
@@ -2,10 +2,15 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "activesupport", "~> 3.0", :require => "active_support/all"
|
5
6
|
gem "mongoid", "~> 2.0.0"
|
6
7
|
|
7
8
|
platforms :ruby, :mswin, :mingw do
|
8
9
|
gem "bson_ext", "~> 1.1"
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
+
platforms :jruby do
|
13
|
+
gem "mongo", "~> 1.9.2"
|
14
|
+
end
|
15
|
+
|
16
|
+
gemspec :path => "../"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "sequel", "~> 3.47.0"
|
6
|
+
gem "activesupport", "~> 3.0", :require => "active_support/all"
|
7
|
+
|
8
|
+
platforms :jruby do
|
9
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
10
|
+
gem "jdbc-sqlite3"
|
11
|
+
end
|
12
|
+
|
13
|
+
platforms :ruby, :mswin, :mingw do
|
14
|
+
gem "sqlite3"
|
15
|
+
end
|
16
|
+
|
17
|
+
gemspec :path => "../"
|
data/lib/cancan.rb
CHANGED
@@ -12,3 +12,4 @@ require 'cancan/model_adapters/default_adapter'
|
|
12
12
|
require 'cancan/model_adapters/active_record_adapter' if defined? ActiveRecord
|
13
13
|
require 'cancan/model_adapters/data_mapper_adapter' if defined? DataMapper
|
14
14
|
require 'cancan/model_adapters/mongoid_adapter' if defined?(Mongoid) && defined?(Mongoid::Document)
|
15
|
+
require 'cancan/model_adapters/sequel_adapter' if defined? Sequel
|
data/lib/cancan/ability.rb
CHANGED
@@ -29,6 +29,13 @@ module CanCan
|
|
29
29
|
#
|
30
30
|
# can? :create, @category => Project
|
31
31
|
#
|
32
|
+
# You can also pass multiple objects to check. You only need to pass a hash
|
33
|
+
# following the pattern { :any => [many subjects] }. The behaviour is check if
|
34
|
+
# there is a permission on any of the given objects.
|
35
|
+
#
|
36
|
+
# can? :create, {:any => [Project, Rule]}
|
37
|
+
#
|
38
|
+
#
|
32
39
|
# Any additional arguments will be passed into the "can" block definition. This
|
33
40
|
# can be used to pass more information about the user's request for example.
|
34
41
|
#
|
@@ -54,12 +61,16 @@ module CanCan
|
|
54
61
|
#
|
55
62
|
# Also see the RSpec Matchers to aid in testing.
|
56
63
|
def can?(action, subject, *extra_args)
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
subject = extract_subjects(subject)
|
65
|
+
|
66
|
+
match = subject.map do |subject|
|
67
|
+
relevant_rules_for_match(action, subject).detect do |rule|
|
68
|
+
rule.matches_conditions?(action, subject, extra_args)
|
69
|
+
end
|
70
|
+
end.compact.first
|
71
|
+
|
60
72
|
match ? match.base_behavior : false
|
61
73
|
end
|
62
|
-
|
63
74
|
# Convenience method which works the same as "can?" but returns the opposite value.
|
64
75
|
#
|
65
76
|
# cannot? :destroy, @project
|
@@ -272,6 +283,15 @@ module CanCan
|
|
272
283
|
@expanded_actions ||= {}
|
273
284
|
end
|
274
285
|
|
286
|
+
# It translates to an array the subject or the hash with multiple subjects given to can?.
|
287
|
+
def extract_subjects(subject)
|
288
|
+
subject = if subject.respond_to?(:keys) && subject.key?(:any)
|
289
|
+
subject[:any]
|
290
|
+
else
|
291
|
+
[subject]
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
275
295
|
# Given an action, it will try to find all of the actions which are aliased to it.
|
276
296
|
# This does the opposite kind of lookup as expand_actions.
|
277
297
|
def aliases_for_action(action)
|
@@ -221,7 +221,11 @@ module CanCan
|
|
221
221
|
|
222
222
|
def resource_params
|
223
223
|
if param_actions.include?(@params[:action].to_sym) && params_method.present?
|
224
|
-
return
|
224
|
+
return case params_method
|
225
|
+
when Symbol then @controller.send(params_method)
|
226
|
+
when String then @controller.instance_eval(params_method)
|
227
|
+
when Proc then params_method.call(@controller)
|
228
|
+
end
|
225
229
|
elsif @options[:class]
|
226
230
|
params_key = extract_key(@options[:class])
|
227
231
|
return @params[params_key] if @params[params_key]
|
@@ -236,7 +240,7 @@ module CanCan
|
|
236
240
|
|
237
241
|
def params_method
|
238
242
|
params_methods.each do |method|
|
239
|
-
return method if @controller.respond_to?(method, true)
|
243
|
+
return method if (method.is_a?(Symbol) && @controller.respond_to?(method, true)) || method.is_a?(String) || method.is_a?(Proc)
|
240
244
|
end
|
241
245
|
nil
|
242
246
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module CanCan
|
2
|
+
module ModelAdapters
|
3
|
+
class SequelAdapter < AbstractAdapter
|
4
|
+
def self.for_class?(model_class)
|
5
|
+
model_class <= Sequel::Model
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.find(model_class, id)
|
9
|
+
model_class[id]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.override_condition_matching?(subject, name, value)
|
13
|
+
value.kind_of?(Hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.matches_condition?(subject, name, value)
|
17
|
+
obj = subject.send(name)
|
18
|
+
if obj.nil?
|
19
|
+
false
|
20
|
+
else
|
21
|
+
value.each do |k, v|
|
22
|
+
if v.kind_of?(Hash)
|
23
|
+
return false unless self.matches_condition?(obj, k, v)
|
24
|
+
elsif obj.send(k) != v
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def database_records
|
32
|
+
if @rules.size == 0
|
33
|
+
@model_class.where('1=0')
|
34
|
+
else
|
35
|
+
# only need to process can rules if there are no can rule with empty conditions
|
36
|
+
rules = @rules.reject { |rule| rule.base_behavior && rule.conditions.empty? }
|
37
|
+
rules.reject! { |rule| rule.base_behavior } if rules.count < @rules.count
|
38
|
+
|
39
|
+
can_condition_added = false
|
40
|
+
rules.reverse.inject(@model_class.dataset) do |records, rule|
|
41
|
+
normalized_conditions = normalize_conditions(rule.conditions)
|
42
|
+
if rule.base_behavior
|
43
|
+
if can_condition_added
|
44
|
+
records.or normalized_conditions
|
45
|
+
else
|
46
|
+
can_condition_added = true
|
47
|
+
records.where normalized_conditions
|
48
|
+
end
|
49
|
+
else
|
50
|
+
records.exclude normalized_conditions
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def normalize_conditions(conditions, model_class = @model_class)
|
59
|
+
return conditions unless conditions.kind_of? Hash
|
60
|
+
conditions.inject({}) do |result_hash, (name, value)|
|
61
|
+
if value.kind_of? Hash
|
62
|
+
value = value.dup
|
63
|
+
association_class = model_class.association_reflection(name).associated_class
|
64
|
+
nested = value.inject({}) do |nested, (k, v)|
|
65
|
+
if v.kind_of?(Hash)
|
66
|
+
value.delete(k)
|
67
|
+
nested_class = association_class.association_reflection(k).associated_class
|
68
|
+
nested[k] = nested_class.where(normalize_conditions(v, association_class))
|
69
|
+
else
|
70
|
+
nested[k] = v
|
71
|
+
end
|
72
|
+
nested
|
73
|
+
end
|
74
|
+
result_hash[name] = association_class.where(nested)
|
75
|
+
else
|
76
|
+
result_hash[name] = value
|
77
|
+
end
|
78
|
+
result_hash
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
Sequel::Model.class_eval do
|
86
|
+
include CanCan::ModelAdditions
|
87
|
+
end
|