cancancan 1.12.0 → 1.13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55bf93046d99f249ab63118d79f1188ef2383278
4
- data.tar.gz: 052a7a962e2585ca122723f23a733d882872a660
3
+ metadata.gz: 60da1f3c13774c65e5c622667c2a1472fffa0dbf
4
+ data.tar.gz: 1e3f6fd8446e2560579d313980a7633efe8e8af1
5
5
  SHA512:
6
- metadata.gz: 7b4259d5de95a69c48301338605341a0f86d200ec01e56981a50d08e5367b7513042620fbeaae77d6790299dcae616feb606fa3c1718b20250bf29cd35356519
7
- data.tar.gz: 1c58fbfde297986492dda47b7f1c03f86da96fb412fe2917bb75bbe8ea5e4e49607189d71c8f19336392d8dd7a7cc30a6b19e8c6e475cc69e38e9ecd533ac135
6
+ metadata.gz: f717a5d3e6c98cb11aad2e1fd38ccfa4d7848d1181f031d0c2e988200f77bda96df6997b9d5c18b8b62d50c0b0ebf0d0c8177b8b6b596443875b52c895820e65
7
+ data.tar.gz: 504adef485e28df04ba9decd2902f38963886e9fe7e047125c15d8505b02fc0bb3f978d99f2306e154be3b8cb64dd1ad4ffdd7e8f0172950817841a67160f31b
data/.travis.yml CHANGED
@@ -1,55 +1,28 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
1
4
  rvm:
2
- - 1.8.7
3
- - 1.9.2
4
- - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1.0
7
7
  - 2.2.0
8
- - ree
9
8
  - jruby
10
9
  - rbx
11
10
  gemfile:
12
- - gemfiles/activerecord_3.0.gemfile
13
- - gemfiles/activerecord_3.1.gemfile
14
11
  - gemfiles/activerecord_3.2.gemfile
15
12
  - gemfiles/activerecord_4.0.gemfile
16
13
  - gemfiles/activerecord_4.1.gemfile
17
14
  - gemfiles/activerecord_4.2.gemfile
18
- - gemfiles/datamapper_1.x.gemfile
19
15
  - gemfiles/mongoid_2.x.gemfile
20
16
  - gemfiles/sequel_3.x.gemfile
21
17
  services:
22
18
  - mongodb
23
19
  matrix:
20
+ fast_finish: true
24
21
  allow_failures:
25
22
  - rvm: rbx
26
- - rvm: jruby
27
- gemfile: gemfiles/datamapper_1.x.gemfile
28
23
  exclude:
29
- - rvm: 1.8.7
30
- gemfile: gemfiles/activerecord_4.0.gemfile
31
- - rvm: 1.8.7
32
- gemfile: gemfiles/activerecord_4.1.gemfile
33
- - rvm: 1.8.7
34
- gemfile: gemfiles/activerecord_4.2.gemfile
35
- - rvm: 1.9.2
36
- gemfile: gemfiles/activerecord_4.0.gemfile
37
- - rvm: 1.9.2
38
- gemfile: gemfiles/activerecord_4.1.gemfile
39
- - rvm: 1.9.2
40
- gemfile: gemfiles/activerecord_4.2.gemfile
41
- - rvm: 2.2.0
42
- gemfile: gemfiles/activerecord_3.0.gemfile
43
- - rvm: 2.2.0
44
- gemfile: gemfiles/activerecord_3.1.gemfile
45
24
  - rvm: 2.2.0
46
25
  gemfile: gemfiles/activerecord_3.2.gemfile
47
- - rvm: ree
48
- gemfile: gemfiles/activerecord_4.0.gemfile
49
- - rvm: ree
50
- gemfile: gemfiles/activerecord_4.1.gemfile
51
- - rvm: ree
52
- gemfile: gemfiles/activerecord_4.2.gemfile
53
26
  notifications:
54
27
  recipients:
55
28
  - bryan@bryanrite.com
data/Appraisals CHANGED
@@ -1,42 +1,6 @@
1
- appraise "activerecord_3.0" do
2
- gem "activerecord", "~> 3.0.20", :require => "active_record"
3
- gem "activesupport", "~> 3.0.20", :require => "active_support/all"
4
- gem "meta_where"
5
-
6
- gemfile.platforms :jruby do
7
- gem "activerecord-jdbcsqlite3-adapter"
8
- gem "jdbc-sqlite3"
9
- end
10
-
11
- gemfile.platforms :ruby, :mswin, :mingw do
12
- gem "sqlite3"
13
- end
14
- end
15
-
16
- appraise "activerecord_3.1" do
17
- gem "activerecord", "~> 3.1.0", :require => "active_record"
18
-
19
- gemfile.platforms :ruby_18, :ruby_19 do
20
- gem "i18n", "< 0.7"
21
- end
22
-
23
- gemfile.platforms :jruby do
24
- gem "activerecord-jdbcsqlite3-adapter"
25
- gem "jdbc-sqlite3"
26
- end
27
-
28
- gemfile.platforms :ruby, :mswin, :mingw do
29
- gem "sqlite3"
30
- end
31
- end
32
-
33
1
  appraise "activerecord_3.2" do
34
2
  gem "activerecord", "~> 3.2.0", :require => "active_record"
35
3
 
36
- gemfile.platforms :ruby_18, :ruby_19 do
37
- gem "i18n", "< 0.7"
38
- end
39
-
40
4
  gemfile.platforms :jruby do
41
5
  gem "activerecord-jdbcsqlite3-adapter"
42
6
  gem "jdbc-sqlite3"
@@ -90,25 +54,10 @@ appraise "activerecord_4.2" do
90
54
  end
91
55
  end
92
56
 
93
- appraise "datamapper_1.x" do
94
- gem "activesupport", "~> 3.0", :require => "active_support/all"
95
- gem "dm-core", "~> 1.0"
96
- gem "dm-sqlite-adapter", "~> 1.0"
97
- gem "dm-migrations", "~> 1.0"
98
-
99
- gemfile.platforms :ruby_18, :ruby_19 do
100
- gem "i18n", "< 0.7"
101
- end
102
- end
103
-
104
57
  appraise "mongoid_2.x" do
105
58
  gem "activesupport", "~> 3.0", :require => "active_support/all"
106
59
  gem "mongoid", "~> 2.0.0"
107
60
 
108
- gemfile.platforms :ruby_18, :ruby_19 do
109
- gem "i18n", "< 0.7"
110
- end
111
-
112
61
  gemfile.platforms :ruby, :mswin, :mingw do
113
62
  gem "bson_ext", "~> 1.1"
114
63
  end
@@ -122,10 +71,6 @@ appraise "sequel_3.x" do
122
71
  gem "sequel", "~> 3.47.0"
123
72
  gem "activesupport", "~> 3.0", :require => "active_support/all"
124
73
 
125
- gemfile.platforms :ruby_18, :ruby_19 do
126
- gem "i18n", "< 0.7"
127
- end
128
-
129
74
  gemfile.platforms :jruby do
130
75
  gem "jdbc-sqlite3"
131
76
  end
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,12 @@
1
1
  Develop
2
2
 
3
+ Unreleased
4
+
5
+ 1.13.0 (Oct 7th, 2015)
6
+
7
+ * Significantly improve rule lookup time (amarshall)
8
+ * Removed deprecation warnings for RSpec 3.2 (NekoNova)
9
+
3
10
  1.12.0 (June 28th, 2015)
4
11
 
5
12
  * Add a permissions method to Ability (devaroop)
data/CONTRIBUTING.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  ### Reporting an Issue
4
4
 
5
- 1. If you have any questions about CanCanCan, search the [Wiki](https://github.com/bryanrite/cancancan/wiki), use [Stack Overflow](http://stackoverflow.com/questions/tagged/cancancan), or [our mailing list](https://groups.google.com/forum/#!forum/cancancan). Do not post questions here.
5
+ 1. If you have any questions about CanCanCan, search the [Wiki](https://github.com/cancancommunity/cancancan/wiki), use [Stack Overflow](http://stackoverflow.com/questions/tagged/cancancan), or [our mailing list](https://groups.google.com/forum/#!forum/cancancan). Do not post questions here.
6
6
 
7
- 1. If you find a security bug, **DO NOT** submit an issue here. Please send an e-mail to [bryan@bryanrite.com](mailto:bryan@bryanrite.com) instead.
7
+ 1. If you find a security bug, **DO NOT** submit an issue here. Please send an e-mail to the current maintainer instead.
8
8
 
9
9
  1. Do a small search on the issues tracker before submitting your issue to see if it was already reported / fixed.
10
10
 
data/README.md CHANGED
@@ -9,6 +9,9 @@
9
9
 
10
10
  CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access. All permissions are defined in a single location (the `Ability` class) and not duplicated across controllers, views, and database queries.
11
11
 
12
+ ## This is the master branch!
13
+ This branch represents work towards version 2.0. Please checkout the 1.x branch for the stable release. Use master at your own risk.
14
+
12
15
  ## Mission
13
16
 
14
17
  This repo is a continuation of the dead [CanCan](https://github.com/ryanb/cancan) project. Our mission is to keep CanCan alive and moving forward, with maintenance fixes and new features. Pull Requests are welcome!
@@ -28,6 +31,12 @@ In **Rails 3 and 4**, add this to your Gemfile and run the `bundle install` comm
28
31
 
29
32
  CanCanCan expects a `current_user` method to exist in the controller. First, set up some authentication (such as [Authlogic](https://github.com/binarylogic/authlogic) or [Devise](https://github.com/plataformatec/devise)). See [Changing Defaults](https://github.com/CanCanCommunity/cancancan/wiki/changing-defaults) if you need different behavior.
30
33
 
34
+ When using [rails-api](https://github.com/rails-api/rails-api), you have to manually include the controller methods for CanCan:
35
+ ```ruby
36
+ class ApplicationController < ActionController::API
37
+ include CanCan::ControllerAdditions
38
+ end
39
+ ```
31
40
 
32
41
  ### 1. Define Abilities
33
42
 
@@ -89,9 +98,26 @@ See [Authorizing Controller Actions](https://github.com/CanCanCommunity/cancanca
89
98
 
90
99
  When using `strong_parameters` or Rails 4+, you have to sanitize inputs before saving the record, in actions such as `:create` and `:update`.
91
100
 
92
- By default, CanCan will try to sanitize the input on `:create` and `:update` routes by seeing if your controller will respond to the following methods (in order):
101
+ For the `:update` action, CanCan will load and authorize the resource but *not* change it automatically, so the typical usage would be something like:
102
+
103
+ ```ruby
104
+ def update
105
+ if @article.update_attributes(update_params)
106
+ # hurray
107
+ else
108
+ render :edit
109
+ end
110
+ end
111
+ ...
112
+
113
+ def update_params
114
+ params.require(:article).permit(:body)
115
+ end
116
+ ```
117
+
118
+ For the `:create` action, CanCan will try to initialize a new instance with sanitized input by seeing if your controller will respond to the following methods (in order):
93
119
 
94
- 1. `create_params` or `update_params` (depending on the action you are performing)
120
+ 1. `create_params`
95
121
  2. `<model_name>_params` such as `article_params` (this is the default convention in rails for naming your param method)
96
122
  3. `resource_params` (a generically named method you could specify in each controller)
97
123
 
data/cancancan.gemspec CHANGED
@@ -6,8 +6,8 @@ require 'cancan/version'
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cancancan"
8
8
  s.version = CanCan::VERSION
9
- s.authors = ["Bryan Rite", "Ryan Bates"]
10
- s.email = "bryan@bryanrite.com"
9
+ s.authors = ["Bryan Rite", "Ryan Bates", "Richard Wilson"]
10
+ s.email = "r.crawfordwilson@gmail.com"
11
11
  s.homepage = "https://github.com/CanCanCommunity/cancancan"
12
12
  s.summary = "Simple authorization solution for Rails."
13
13
  s.description = "Continuation of the simple authorization solution for Rails which is decoupled from user roles. All permissions are stored in a single location."
@@ -19,13 +19,10 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split($/).map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
23
- s.required_rubygems_version = ">= 1.3.4"
22
+ s.required_ruby_version = ">= 2.0.0"
24
23
 
25
24
  s.add_development_dependency 'bundler', '~> 1.3'
26
25
  s.add_development_dependency 'rake', '~> 10.1.1'
27
- s.add_development_dependency 'rspec', '~> 3.0.0'
28
- s.add_development_dependency 'appraisal', '>= 1.0.0'
29
-
30
- s.rubyforge_project = s.name
26
+ s.add_development_dependency 'rspec', '~> 3.2.0'
27
+ s.add_development_dependency 'appraisal', '>= 2.0.0'
31
28
  end
@@ -4,10 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 3.2.0", :require => "active_record"
6
6
 
7
- platforms :ruby_18, :ruby_19 do
8
- gem "i18n", "< 0.7"
9
- end
10
-
11
7
  platforms :jruby do
12
8
  gem "activerecord-jdbcsqlite3-adapter"
13
9
  gem "jdbc-sqlite3"
@@ -5,10 +5,6 @@ source "https://rubygems.org"
5
5
  gem "activesupport", "~> 3.0", :require => "active_support/all"
6
6
  gem "mongoid", "~> 2.0.0"
7
7
 
8
- platforms :ruby_18, :ruby_19 do
9
- gem "i18n", "< 0.7"
10
- end
11
-
12
8
  platforms :ruby, :mswin, :mingw do
13
9
  gem "bson_ext", "~> 1.1"
14
10
  end
@@ -5,10 +5,6 @@ source "https://rubygems.org"
5
5
  gem "sequel", "~> 3.47.0"
6
6
  gem "activesupport", "~> 3.0", :require => "active_support/all"
7
7
 
8
- platforms :ruby_18, :ruby_19 do
9
- gem "i18n", "< 0.7"
10
- end
11
-
12
8
  platforms :jruby do
13
9
  gem "jdbc-sqlite3"
14
10
  end
@@ -119,7 +119,7 @@ module CanCan
119
119
  # can :read, :stats
120
120
  # can? :read, :stats # => true
121
121
  #
122
- # IMPORTANT: Neither a hash of conditions or a block will be used when checking permission on a class.
122
+ # IMPORTANT: Neither a hash of conditions nor a block will be used when checking permission on a class.
123
123
  #
124
124
  # can :update, Project, :priority => 3
125
125
  # can? :update, Project # => true
@@ -133,7 +133,7 @@ module CanCan
133
133
  # end
134
134
  #
135
135
  def can(action = nil, subject = nil, conditions = nil, &block)
136
- rules << Rule.new(true, action, subject, conditions, block)
136
+ add_rule(Rule.new(true, action, subject, conditions, block))
137
137
  end
138
138
 
139
139
  # Defines an ability which cannot be done. Accepts the same arguments as "can".
@@ -149,7 +149,7 @@ module CanCan
149
149
  # end
150
150
  #
151
151
  def cannot(action = nil, subject = nil, conditions = nil, &block)
152
- rules << Rule.new(false, action, subject, conditions, block)
152
+ add_rule(Rule.new(false, action, subject, conditions, block))
153
153
  end
154
154
 
155
155
  # Alias one or more actions into another one.
@@ -246,8 +246,8 @@ module CanCan
246
246
  end
247
247
 
248
248
  def merge(ability)
249
- ability.send(:rules).each do |rule|
250
- rules << rule.dup
249
+ ability.rules.each do |rule|
250
+ add_rule(rule.dup)
251
251
  end
252
252
  self
253
253
  end
@@ -281,6 +281,12 @@ module CanCan
281
281
  permissions_list
282
282
  end
283
283
 
284
+ protected
285
+
286
+ # Must be protected as an ability can merge with other abilities.
287
+ # This means that an ability must expose their rules with another ability.
288
+ attr_reader :rules
289
+
284
290
  private
285
291
 
286
292
  def unauthorized_message_keys(action, subject)
@@ -331,21 +337,50 @@ module CanCan
331
337
  results
332
338
  end
333
339
 
334
- def rules
340
+ def add_rule(rule)
335
341
  @rules ||= []
342
+ @rules << rule
343
+ add_rule_to_index(rule, @rules.size - 1)
344
+ end
345
+
346
+ def add_rule_to_index(rule, position)
347
+ @rules_index ||= Hash.new { |h, k| h[k] = [] }
348
+
349
+ subjects = rule.subjects.compact
350
+ subjects << :all if subjects.empty?
351
+
352
+ subjects.each do |subject|
353
+ @rules_index[subject] << position
354
+ end
355
+ end
356
+
357
+ def alternative_subjects(subject)
358
+ subject = subject.class unless subject.is_a?(Module)
359
+ [:all, *subject.ancestors, subject.class.to_s]
336
360
  end
337
361
 
338
362
  # Returns an array of Rule instances which match the action and subject
339
363
  # This does not take into consideration any hash conditions or block statements
340
364
  def relevant_rules(action, subject)
341
- relevant = rules.select do |rule|
365
+ return [] unless @rules
366
+ relevant = possible_relevant_rules(subject).select do |rule|
342
367
  rule.expanded_actions = expand_actions(rule.actions)
343
368
  rule.relevant? action, subject
344
369
  end
345
- relevant.reverse!
370
+ relevant.reverse!.uniq!
346
371
  relevant
347
372
  end
348
373
 
374
+ def possible_relevant_rules(subject)
375
+ if subject.is_a?(Hash)
376
+ rules
377
+ else
378
+ positions = @rules_index.values_at(subject, *alternative_subjects(subject))
379
+ positions.flatten!.sort!
380
+ positions.map { |i| @rules[i] }
381
+ end
382
+ end
383
+
349
384
  def relevant_rules_for_match(action, subject)
350
385
  relevant_rules(action, subject).each do |rule|
351
386
  if rule.only_raw_sql?
@@ -15,6 +15,9 @@ Kernel.const_get(rspec_module)::Matchers.define :be_able_to do |*args|
15
15
  # Check that RSpec is < 2.99
16
16
  if !respond_to?(:failure_message) && respond_to?(:failure_message_for_should)
17
17
  alias :failure_message :failure_message_for_should
18
+ end
19
+
20
+ if !respond_to?(:failure_message_when_negated) && respond_to?(:failure_message_for_should_not)
18
21
  alias :failure_message_when_negated :failure_message_for_should_not
19
22
  end
20
23
 
@@ -6,37 +6,6 @@ module CanCan
6
6
  model_class <= ActiveRecord::Base
7
7
  end
8
8
 
9
- def self.override_condition_matching?(subject, name, value)
10
- name.kind_of?(MetaWhere::Column) if defined? MetaWhere
11
- end
12
-
13
- def self.matches_condition?(subject, name, value)
14
- subject_value = subject.send(name.column)
15
- if name.method.to_s.ends_with? "_any"
16
- value.any? { |v| meta_where_match? subject_value, name.method.to_s.sub("_any", ""), v }
17
- elsif name.method.to_s.ends_with? "_all"
18
- value.all? { |v| meta_where_match? subject_value, name.method.to_s.sub("_all", ""), v }
19
- else
20
- meta_where_match? subject_value, name.method, value
21
- end
22
- end
23
-
24
- def self.meta_where_match?(subject_value, method, value)
25
- case method.to_sym
26
- when :eq then subject_value == value
27
- when :not_eq then subject_value != value
28
- when :in then value.include?(subject_value)
29
- when :not_in then !value.include?(subject_value)
30
- when :lt then subject_value < value
31
- when :lteq then subject_value <= value
32
- when :gt then subject_value > value
33
- when :gteq then subject_value >= value
34
- when :matches then subject_value =~ Regexp.new("^" + Regexp.escape(value).gsub("%", ".*") + "$", true)
35
- when :does_not_match then !meta_where_match?(subject_value, :matches, value)
36
- else raise NotImplemented, "The #{method} MetaWhere condition is not supported."
37
- end
38
- end
39
-
40
9
  private
41
10
 
42
11
  def build_relation(*where_conditions)
data/lib/cancan/rule.rb CHANGED
@@ -91,7 +91,11 @@ module CanCan
91
91
  end
92
92
 
93
93
  def matches_subject_class?(subject)
94
- @subjects.any? { |sub| sub.kind_of?(Module) && (subject.kind_of?(sub) || subject.class.to_s == sub.to_s || subject.kind_of?(Module) && subject.ancestors.include?(sub)) }
94
+ @subjects.any? do |sub|
95
+ sub.kind_of?(Module) && (subject.kind_of?(sub) ||
96
+ subject.class.to_s == sub.to_s ||
97
+ (subject.kind_of?(Module) && subject.ancestors.include?(sub)))
98
+ end
95
99
  end
96
100
 
97
101
  # Checks if the given subject matches the given conditions hash.
@@ -1,3 +1,3 @@
1
1
  module CanCan
2
- VERSION = "1.12.0"
2
+ VERSION = "1.13.0"
3
3
  end
data/lib/cancan.rb CHANGED
@@ -20,6 +20,5 @@ if defined? ActiveRecord
20
20
  end
21
21
  end
22
22
 
23
- require 'cancan/model_adapters/data_mapper_adapter' if defined? DataMapper
24
23
  require 'cancan/model_adapters/mongoid_adapter' if defined?(Mongoid) && defined?(Mongoid::Document)
25
24
  require 'cancan/model_adapters/sequel_adapter' if defined? Sequel
@@ -45,6 +45,13 @@ describe CanCan::Ability do
45
45
  expect(@ability.can?(:read, 6)).to be(false)
46
46
  end
47
47
 
48
+ it "overrides earlier rules with later ones (even if a different exact subject)" do
49
+ @ability.cannot :read, Numeric
50
+ @ability.can :read, Integer
51
+
52
+ expect(@ability.can?(:read, 6)).to be(true)
53
+ end
54
+
48
55
  it "does not pass class with object if :all objects are accepted" do
49
56
  @ability.can :preview, :all do |object|
50
57
  expect(object).to eq(123)
@@ -380,67 +380,5 @@ if defined? CanCan::ModelAdapters::ActiveRecordAdapter
380
380
  expect(Namespace::TableX.accessible_by(ability)).to eq([table_x])
381
381
  end
382
382
  end
383
-
384
- context "when MetaWhere is defined" do
385
- before :each do
386
- pending "[Deprecated] MetaWhere support is being removed" unless defined? MetaWhere
387
- end
388
-
389
- it "restricts articles given a MetaWhere condition" do
390
- # pending "[Deprecated] MetaWhere support is being removed" unless defined? MetaWhere
391
- @ability.can :read, Article, :priority.lt => 2
392
- article1 = Article.create!(:priority => 1)
393
- article2 = Article.create!(:priority => 3)
394
- expect(Article.accessible_by(@ability)).to eq([article1])
395
- expect(@ability).to be_able_to(:read, article1)
396
- expect(@ability).to_not be_able_to(:read, article2)
397
- end
398
-
399
- it "merges MetaWhere and non-MetaWhere conditions" do
400
- # pending "[Deprecated] MetaWhere support is being removed" unless defined? MetaWhere
401
- @ability.can :read, Article, :priority.lt => 2
402
- @ability.can :read, Article, :priority => 1
403
- article1 = Article.create!(:priority => 1)
404
- article2 = Article.create!(:priority => 3)
405
- expect(Article.accessible_by(@ability)).to eq([article1])
406
- expect(@ability).to be_able_to(:read, article1)
407
- expect(@ability).to_not be_able_to(:read, article2)
408
- end
409
-
410
- it "matches any MetaWhere condition" do
411
- adapter = CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article)
412
- article1 = Article.new(:priority => 1, :name => "Hello World")
413
- expect(adapter.matches_condition?(article1, :priority.eq, 1)).to be(true)
414
- expect(adapter.matches_condition?(article1, :priority.eq, 2)).to be(false)
415
- expect(adapter.matches_condition?(article1, :priority.eq_any, [1, 2])).to be(true)
416
- expect(adapter.matches_condition?(article1, :priority.eq_any, [2, 3])).to be(false)
417
- expect(adapter.matches_condition?(article1, :priority.eq_all, [1, 1])).to be(true)
418
- expect(adapter.matches_condition?(article1, :priority.eq_all, [1, 2])).to be(false)
419
- expect(adapter.matches_condition?(article1, :priority.ne, 2)).to be(true)
420
- expect(adapter.matches_condition?(article1, :priority.ne, 1)).to be(false)
421
- expect(adapter.matches_condition?(article1, :priority.in, [1, 2])).to be(true)
422
- expect(adapter.matches_condition?(article1, :priority.in, [2, 3])).to be(false)
423
- expect(adapter.matches_condition?(article1, :priority.nin, [2, 3])).to be(true)
424
- expect(adapter.matches_condition?(article1, :priority.nin, [1, 2])).to be(false)
425
- expect(adapter.matches_condition?(article1, :priority.lt, 2)).to be(true)
426
- expect(adapter.matches_condition?(article1, :priority.lt, 1)).to be(false)
427
- expect(adapter.matches_condition?(article1, :priority.lteq, 1)).to be(true)
428
- expect(adapter.matches_condition?(article1, :priority.lteq, 0)).to be(false)
429
- expect(adapter.matches_condition?(article1, :priority.gt, 0)).to be(true)
430
- expect(adapter.matches_condition?(article1, :priority.gt, 1)).to be(false)
431
- expect(adapter.matches_condition?(article1, :priority.gteq, 1)).to be(true)
432
- expect(adapter.matches_condition?(article1, :priority.gteq, 2)).to be(false)
433
- expect(adapter.matches_condition?(article1, :name.like, "%ello worl%")).to be_truthy
434
- expect(adapter.matches_condition?(article1, :name.like, "hello world")).to be_truthy
435
- expect(adapter.matches_condition?(article1, :name.like, "hello%")).to be_truthy
436
- expect(adapter.matches_condition?(article1, :name.like, "h%d")).to be_truthy
437
- expect(adapter.matches_condition?(article1, :name.like, "%helo%")).to be_falsey
438
- expect(adapter.matches_condition?(article1, :name.like, "hello")).to be_falsey
439
- expect(adapter.matches_condition?(article1, :name.like, "hello.world")).to be_falsey
440
- # For some reason this is reporting "The not_matches MetaWhere condition is not supported."
441
- # expect(adapter.matches_condition?(article1, :name.nlike, "%helo%")).to be(true)
442
- # expect(adapter.matches_condition?(article1, :name.nlike, "%ello worl%")).to be(false)
443
- end
444
- end
445
383
  end
446
384
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cancancan
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.0
4
+ version: 1.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Rite
8
8
  - Ryan Bates
9
+ - Richard Wilson
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-06-29 00:00:00.000000000 Z
13
+ date: 2015-10-08 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: bundler
@@ -45,31 +46,31 @@ dependencies:
45
46
  requirements:
46
47
  - - "~>"
47
48
  - !ruby/object:Gem::Version
48
- version: 3.0.0
49
+ version: 3.2.0
49
50
  type: :development
50
51
  prerelease: false
51
52
  version_requirements: !ruby/object:Gem::Requirement
52
53
  requirements:
53
54
  - - "~>"
54
55
  - !ruby/object:Gem::Version
55
- version: 3.0.0
56
+ version: 3.2.0
56
57
  - !ruby/object:Gem::Dependency
57
58
  name: appraisal
58
59
  requirement: !ruby/object:Gem::Requirement
59
60
  requirements:
60
61
  - - ">="
61
62
  - !ruby/object:Gem::Version
62
- version: 1.0.0
63
+ version: 2.0.0
63
64
  type: :development
64
65
  prerelease: false
65
66
  version_requirements: !ruby/object:Gem::Requirement
66
67
  requirements:
67
68
  - - ">="
68
69
  - !ruby/object:Gem::Version
69
- version: 1.0.0
70
+ version: 2.0.0
70
71
  description: Continuation of the simple authorization solution for Rails which is
71
72
  decoupled from user roles. All permissions are stored in a single location.
72
- email: bryan@bryanrite.com
73
+ email: r.crawfordwilson@gmail.com
73
74
  executables: []
74
75
  extensions: []
75
76
  extra_rdoc_files: []
@@ -85,13 +86,10 @@ files:
85
86
  - README.md
86
87
  - Rakefile
87
88
  - cancancan.gemspec
88
- - gemfiles/activerecord_3.0.gemfile
89
- - gemfiles/activerecord_3.1.gemfile
90
89
  - gemfiles/activerecord_3.2.gemfile
91
90
  - gemfiles/activerecord_4.0.gemfile
92
91
  - gemfiles/activerecord_4.1.gemfile
93
92
  - gemfiles/activerecord_4.2.gemfile
94
- - gemfiles/datamapper_1.x.gemfile
95
93
  - gemfiles/mongoid_2.x.gemfile
96
94
  - gemfiles/sequel_3.x.gemfile
97
95
  - init.rb
@@ -106,7 +104,6 @@ files:
106
104
  - lib/cancan/model_adapters/active_record_3_adapter.rb
107
105
  - lib/cancan/model_adapters/active_record_4_adapter.rb
108
106
  - lib/cancan/model_adapters/active_record_adapter.rb
109
- - lib/cancan/model_adapters/data_mapper_adapter.rb
110
107
  - lib/cancan/model_adapters/default_adapter.rb
111
108
  - lib/cancan/model_adapters/mongoid_adapter.rb
112
109
  - lib/cancan/model_adapters/sequel_adapter.rb
@@ -126,7 +123,6 @@ files:
126
123
  - spec/cancan/matchers_spec.rb
127
124
  - spec/cancan/model_adapters/active_record_4_adapter_spec.rb
128
125
  - spec/cancan/model_adapters/active_record_adapter_spec.rb
129
- - spec/cancan/model_adapters/data_mapper_adapter_spec.rb
130
126
  - spec/cancan/model_adapters/default_adapter_spec.rb
131
127
  - spec/cancan/model_adapters/mongoid_adapter_spec.rb
132
128
  - spec/cancan/model_adapters/sequel_adapter_spec.rb
@@ -147,14 +143,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
143
  requirements:
148
144
  - - ">="
149
145
  - !ruby/object:Gem::Version
150
- version: 1.8.7
146
+ version: 2.0.0
151
147
  required_rubygems_version: !ruby/object:Gem::Requirement
152
148
  requirements:
153
149
  - - ">="
154
150
  - !ruby/object:Gem::Version
155
- version: 1.3.4
151
+ version: '0'
156
152
  requirements: []
157
- rubyforge_project: cancancan
153
+ rubyforge_project:
158
154
  rubygems_version: 2.2.3
159
155
  signing_key:
160
156
  specification_version: 4
@@ -1,18 +0,0 @@
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 => "../"
@@ -1,20 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 3.1.0", :require => "active_record"
6
-
7
- platforms :ruby_18, :ruby_19 do
8
- gem "i18n", "< 0.7"
9
- end
10
-
11
- platforms :jruby do
12
- gem "activerecord-jdbcsqlite3-adapter"
13
- gem "jdbc-sqlite3"
14
- end
15
-
16
- platforms :ruby, :mswin, :mingw do
17
- gem "sqlite3"
18
- end
19
-
20
- gemspec :path => "../"
@@ -1,14 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 3.0", :require => "active_support/all"
6
- gem "dm-core", "~> 1.0"
7
- gem "dm-sqlite-adapter", "~> 1.0"
8
- gem "dm-migrations", "~> 1.0"
9
-
10
- platforms :ruby_18, :ruby_19 do
11
- gem "i18n", "< 0.7"
12
- end
13
-
14
- gemspec :path => "../"
@@ -1,34 +0,0 @@
1
- module CanCan
2
- module ModelAdapters
3
- class DataMapperAdapter < AbstractAdapter
4
- def self.for_class?(model_class)
5
- model_class <= DataMapper::Resource
6
- end
7
-
8
- def self.find(model_class, id)
9
- model_class.get(id)
10
- end
11
-
12
- def self.override_conditions_hash_matching?(subject, conditions)
13
- conditions.any? { |k,v| !k.kind_of?(Symbol) }
14
- end
15
-
16
- def self.matches_conditions_hash?(subject, conditions)
17
- collection = DataMapper::Collection.new(subject.query, [ subject ])
18
- !!collection.first(conditions)
19
- end
20
-
21
- def database_records
22
- scope = @model_class.all(:conditions => ["0 = 1"])
23
- cans, cannots = @rules.partition { |r| r.base_behavior }
24
- return scope if cans.empty?
25
- # apply unions first, then differences. this mean cannot overrides can
26
- cans.each { |r| scope += @model_class.all(:conditions => r.conditions) }
27
- cannots.each { |r| scope -= @model_class.all(:conditions => r.conditions) }
28
- scope
29
- end
30
- end # class DataMapper
31
- end # module ModelAdapters
32
- end # module CanCan
33
-
34
- DataMapper::Model.append_extensions(CanCan::ModelAdditions::ClassMethods)
@@ -1,119 +0,0 @@
1
- require "spec_helper"
2
-
3
- if defined? CanCan::ModelAdapters::DataMapperAdapter
4
-
5
- DataMapper.setup(:default, 'sqlite::memory:')
6
-
7
- class Article
8
- include DataMapper::Resource
9
- property :id, Serial
10
- property :published, Boolean, :default => false
11
- property :secret, Boolean, :default => false
12
- property :priority, Integer
13
- has n, :comments
14
- end
15
-
16
- class Comment
17
- include DataMapper::Resource
18
- property :id, Serial
19
- property :spam, Boolean, :default => false
20
- belongs_to :article
21
- end
22
-
23
- DataMapper.finalize
24
- DataMapper.auto_migrate!
25
-
26
- describe CanCan::ModelAdapters::DataMapperAdapter do
27
- before(:each) do
28
- Article.destroy
29
- Comment.destroy
30
- (@ability = double).extend(CanCan::Ability)
31
- end
32
-
33
- it "is for only data mapper classes" do
34
- expect(CanCan::ModelAdapters::DataMapperAdapter).not_to be_for_class(Object)
35
- expect(CanCan::ModelAdapters::DataMapperAdapter).to be_for_class(Article)
36
- expect(CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article)).to eq(CanCan::ModelAdapters::DataMapperAdapter)
37
- end
38
-
39
- it "finds record" do
40
- article = Article.create
41
- expect(CanCan::ModelAdapters::DataMapperAdapter.find(Article, article.id)).to eq(article)
42
- end
43
-
44
- it "does not fetch any records when no abilities are defined" do
45
- Article.create
46
- expect(Article.accessible_by(@ability)).to be_empty
47
- end
48
-
49
- it "fetches all articles when one can read all" do
50
- @ability.can :read, Article
51
- article = Article.create
52
- expect(Article.accessible_by(@ability)).to eq([article])
53
- end
54
-
55
- it "fetches only the articles that are published" do
56
- @ability.can :read, Article, :published => true
57
- article1 = Article.create(:published => true)
58
- article2 = Article.create(:published => false)
59
- expect(Article.accessible_by(@ability)).to eq([article1])
60
- end
61
-
62
- it "fetches any articles which are published or secret" do
63
- @ability.can :read, Article, :published => true
64
- @ability.can :read, Article, :secret => true
65
- article1 = Article.create(:published => true, :secret => false)
66
- article2 = Article.create(:published => true, :secret => true)
67
- article3 = Article.create(:published => false, :secret => true)
68
- article4 = Article.create(:published => false, :secret => false)
69
- expect(Article.accessible_by(@ability)).to eq([article1, article2, article3])
70
- end
71
-
72
- it "fetches only the articles that are published and not secret" do
73
- @ability.can :read, Article, :published => true
74
- @ability.cannot :read, Article, :secret => true
75
- article1 = Article.create(:published => true, :secret => false)
76
- article2 = Article.create(:published => true, :secret => true)
77
- article3 = Article.create(:published => false, :secret => true)
78
- article4 = Article.create(:published => false, :secret => false)
79
- expect(Article.accessible_by(@ability)).to eq([article1])
80
- end
81
-
82
- it "only reads comments for articles which are published" do
83
- @ability.can :read, Comment, :article => { :published => true }
84
- comment1 = Comment.create(:article => Article.create!(:published => true))
85
- comment2 = Comment.create(:article => Article.create!(:published => false))
86
- expect(Comment.accessible_by(@ability)).to eq([comment1])
87
- end
88
-
89
- it "allows conditions in SQL and merge with hash conditions" do
90
- @ability.can :read, Article, :published => true
91
- @ability.can :read, Article, ["secret=?", true]
92
- article1 = Article.create(:published => true, :secret => false)
93
- article4 = Article.create(:published => false, :secret => false)
94
- expect(Article.accessible_by(@ability)).to eq([article1])
95
- end
96
-
97
- it "matches gt comparison" do
98
- @ability.can :read, Article, :priority.gt => 3
99
- article1 = Article.create(:priority => 4)
100
- article2 = Article.create(:priority => 3)
101
- expect(Article.accessible_by(@ability)).to eq([article1])
102
- expect(@ability).to be_able_to(:read, article1)
103
- expect(@ability).not_to be_able_to(:read, article2)
104
- end
105
-
106
- it "matches gte comparison" do
107
- @ability.can :read, Article, :priority.gte => 3
108
- article1 = Article.create(:priority => 4)
109
- article2 = Article.create(:priority => 3)
110
- article3 = Article.create(:priority => 2)
111
- expect(Article.accessible_by(@ability)).to eq([article1, article2])
112
- expect(@ability).to be_able_to(:read, article1)
113
- expect(@ability).to be_able_to(:read, article2)
114
- expect(@ability).not_to be_able_to(:read, article3)
115
- end
116
-
117
- # TODO: add more comparison specs
118
- end
119
- end