cancat 0.0.1.beta1

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.
Files changed (39) hide show
  1. data/CHANGELOG.rdoc +291 -0
  2. data/Gemfile +20 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +111 -0
  5. data/Rakefile +18 -0
  6. data/init.rb +1 -0
  7. data/lib/cancan.rb +13 -0
  8. data/lib/cancan/ability.rb +302 -0
  9. data/lib/cancan/controller_additions.rb +389 -0
  10. data/lib/cancan/controller_resource.rb +222 -0
  11. data/lib/cancan/exceptions.rb +50 -0
  12. data/lib/cancan/inherited_resource.rb +19 -0
  13. data/lib/cancan/matchers.rb +14 -0
  14. data/lib/cancan/model_adapters/abstract_adapter.rb +56 -0
  15. data/lib/cancan/model_adapters/active_record_adapter.rb +165 -0
  16. data/lib/cancan/model_adapters/data_mapper_adapter.rb +36 -0
  17. data/lib/cancan/model_adapters/default_adapter.rb +7 -0
  18. data/lib/cancan/model_adapters/mongoid_adapter.rb +53 -0
  19. data/lib/cancan/model_additions.rb +31 -0
  20. data/lib/cancan/rule.rb +142 -0
  21. data/lib/generators/cancan/ability/USAGE +4 -0
  22. data/lib/generators/cancan/ability/ability_generator.rb +11 -0
  23. data/lib/generators/cancan/ability/templates/ability.rb +28 -0
  24. data/spec/README.rdoc +28 -0
  25. data/spec/cancan/ability_spec.rb +419 -0
  26. data/spec/cancan/controller_additions_spec.rb +137 -0
  27. data/spec/cancan/controller_resource_spec.rb +412 -0
  28. data/spec/cancan/exceptions_spec.rb +35 -0
  29. data/spec/cancan/inherited_resource_spec.rb +42 -0
  30. data/spec/cancan/matchers_spec.rb +33 -0
  31. data/spec/cancan/model_adapters/active_record_adapter_spec.rb +278 -0
  32. data/spec/cancan/model_adapters/data_mapper_adapter_spec.rb +119 -0
  33. data/spec/cancan/model_adapters/default_adapter_spec.rb +7 -0
  34. data/spec/cancan/model_adapters/mongoid_adapter_spec.rb +216 -0
  35. data/spec/cancan/rule_spec.rb +39 -0
  36. data/spec/matchers.rb +13 -0
  37. data/spec/spec.opts +2 -0
  38. data/spec/spec_helper.rb +41 -0
  39. metadata +171 -0
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe CanCan::ModelAdapters::DefaultAdapter do
4
+ it "should be default for generic classes" do
5
+ CanCan::ModelAdapters::AbstractAdapter.adapter_class(Object).should == CanCan::ModelAdapters::DefaultAdapter
6
+ end
7
+ end
@@ -0,0 +1,216 @@
1
+ if ENV["MODEL_ADAPTER"] == "mongoid"
2
+ require "spec_helper"
3
+
4
+ class MongoidCategory
5
+ include Mongoid::Document
6
+
7
+ references_many :mongoid_projects
8
+ end
9
+
10
+ class MongoidProject
11
+ include Mongoid::Document
12
+
13
+ referenced_in :mongoid_category
14
+ end
15
+
16
+ Mongoid.configure do |config|
17
+ config.master = Mongo::Connection.new('127.0.0.1', 27017).db("cancan_mongoid_spec")
18
+ end
19
+
20
+ describe CanCan::ModelAdapters::MongoidAdapter do
21
+ context "Mongoid defined" do
22
+ before(:each) do
23
+ @ability = Object.new
24
+ @ability.extend(CanCan::Ability)
25
+ end
26
+
27
+ after(:each) do
28
+ Mongoid.master.collections.select do |collection|
29
+ collection.name !~ /system/
30
+ end.each(&:drop)
31
+ end
32
+
33
+ it "should be for only Mongoid classes" do
34
+ CanCan::ModelAdapters::MongoidAdapter.should_not be_for_class(Object)
35
+ CanCan::ModelAdapters::MongoidAdapter.should be_for_class(MongoidProject)
36
+ CanCan::ModelAdapters::AbstractAdapter.adapter_class(MongoidProject).should == CanCan::ModelAdapters::MongoidAdapter
37
+ end
38
+
39
+ it "should find record" do
40
+ project = MongoidProject.create
41
+ CanCan::ModelAdapters::MongoidAdapter.find(MongoidProject, project.id).should == project
42
+ end
43
+
44
+ it "should compare properties on mongoid documents with the conditions hash" do
45
+ model = MongoidProject.new
46
+ @ability.can :read, MongoidProject, :id => model.id
47
+ @ability.should be_able_to(:read, model)
48
+ end
49
+
50
+ it "should be able to read hashes when field is array" do
51
+ one_to_three = MongoidProject.create(:numbers => ['one', 'two', 'three'])
52
+ two_to_five = MongoidProject.create(:numbers => ['two', 'three', 'four', 'five'])
53
+
54
+ @ability.can :foo, MongoidProject, :numbers => 'one'
55
+ @ability.should be_able_to(:foo, one_to_three)
56
+ @ability.should_not be_able_to(:foo, two_to_five)
57
+ end
58
+
59
+ it "should return [] when no ability is defined so no records are found" do
60
+ MongoidProject.create(:title => 'Sir')
61
+ MongoidProject.create(:title => 'Lord')
62
+ MongoidProject.create(:title => 'Dude')
63
+
64
+ MongoidProject.accessible_by(@ability, :read).entries.should == []
65
+ end
66
+
67
+ it "should return the correct records based on the defined ability" do
68
+ @ability.can :read, MongoidProject, :title => "Sir"
69
+ sir = MongoidProject.create(:title => 'Sir')
70
+ lord = MongoidProject.create(:title => 'Lord')
71
+ dude = MongoidProject.create(:title => 'Dude')
72
+
73
+ MongoidProject.accessible_by(@ability, :read).entries.should == [sir]
74
+ end
75
+
76
+ it "should be able to mix empty conditions and hashes" do
77
+ @ability.can :read, MongoidProject
78
+ @ability.can :read, MongoidProject, :title => 'Sir'
79
+ sir = MongoidProject.create(:title => 'Sir')
80
+ lord = MongoidProject.create(:title => 'Lord')
81
+
82
+ MongoidProject.accessible_by(@ability, :read).count.should == 2
83
+ end
84
+
85
+ it "should return everything when the defined ability is manage all" do
86
+ @ability.can :manage, :all
87
+ sir = MongoidProject.create(:title => 'Sir')
88
+ lord = MongoidProject.create(:title => 'Lord')
89
+ dude = MongoidProject.create(:title => 'Dude')
90
+
91
+ MongoidProject.accessible_by(@ability, :read).entries.should == [sir, lord, dude]
92
+ end
93
+
94
+ it "should allow a scope for conditions" do
95
+ @ability.can :read, MongoidProject, MongoidProject.where(:title => 'Sir')
96
+ sir = MongoidProject.create(:title => 'Sir')
97
+ lord = MongoidProject.create(:title => 'Lord')
98
+ dude = MongoidProject.create(:title => 'Dude')
99
+
100
+ MongoidProject.accessible_by(@ability, :read).entries.should == [sir]
101
+ end
102
+
103
+ describe "Mongoid::Criteria where clause Symbol extensions using MongoDB expressions" do
104
+ it "should handle :field.in" do
105
+ obj = MongoidProject.create(:title => 'Sir')
106
+ @ability.can :read, MongoidProject, :title.in => ["Sir", "Madam"]
107
+ @ability.can?(:read, obj).should == true
108
+ MongoidProject.accessible_by(@ability, :read).should == [obj]
109
+
110
+ obj2 = MongoidProject.create(:title => 'Lord')
111
+ @ability.can?(:read, obj2).should == false
112
+ end
113
+
114
+ describe "activates only when there are Criteria in the hash" do
115
+ it "Calls where on the model class when there are criteria" do
116
+ obj = MongoidProject.create(:title => 'Bird')
117
+ @conditions = {:title.nin => ["Fork", "Spoon"]}
118
+
119
+ @ability.can :read, MongoidProject, @conditions
120
+ @ability.should be_able_to(:read, obj)
121
+ end
122
+ it "Calls the base version if there are no mongoid criteria" do
123
+ obj = MongoidProject.new(:title => 'Bird')
124
+ @conditions = {:id => obj.id}
125
+ @ability.can :read, MongoidProject, @conditions
126
+ @ability.should be_able_to(:read, obj)
127
+ end
128
+ end
129
+
130
+ it "should handle :field.nin" do
131
+ obj = MongoidProject.create(:title => 'Sir')
132
+ @ability.can :read, MongoidProject, :title.nin => ["Lord", "Madam"]
133
+ @ability.can?(:read, obj).should == true
134
+ MongoidProject.accessible_by(@ability, :read).should == [obj]
135
+
136
+ obj2 = MongoidProject.create(:title => 'Lord')
137
+ @ability.can?(:read, obj2).should == false
138
+ end
139
+
140
+ it "should handle :field.size" do
141
+ obj = MongoidProject.create(:titles => ['Palatin', 'Margrave'])
142
+ @ability.can :read, MongoidProject, :titles.size => 2
143
+ @ability.can?(:read, obj).should == true
144
+ MongoidProject.accessible_by(@ability, :read).should == [obj]
145
+
146
+ obj2 = MongoidProject.create(:titles => ['Palatin', 'Margrave', 'Marquis'])
147
+ @ability.can?(:read, obj2).should == false
148
+ end
149
+
150
+ it "should handle :field.exists" do
151
+ obj = MongoidProject.create(:titles => ['Palatin', 'Margrave'])
152
+ @ability.can :read, MongoidProject, :titles.exists => true
153
+ @ability.can?(:read, obj).should == true
154
+ MongoidProject.accessible_by(@ability, :read).should == [obj]
155
+
156
+ obj2 = MongoidProject.create
157
+ @ability.can?(:read, obj2).should == false
158
+ end
159
+
160
+ it "should handle :field.gt" do
161
+ obj = MongoidProject.create(:age => 50)
162
+ @ability.can :read, MongoidProject, :age.gt => 45
163
+ @ability.can?(:read, obj).should == true
164
+ MongoidProject.accessible_by(@ability, :read).should == [obj]
165
+
166
+ obj2 = MongoidProject.create(:age => 40)
167
+ @ability.can?(:read, obj2).should == false
168
+ end
169
+
170
+ it "should handle instance not saved to database" do
171
+ obj = MongoidProject.new(:title => 'Sir')
172
+ @ability.can :read, MongoidProject, :title.in => ["Sir", "Madam"]
173
+ @ability.can?(:read, obj).should == true
174
+
175
+ # accessible_by only returns saved records
176
+ MongoidProject.accessible_by(@ability, :read).entries.should == []
177
+
178
+ obj2 = MongoidProject.new(:title => 'Lord')
179
+ @ability.can?(:read, obj2).should == false
180
+ end
181
+ end
182
+
183
+ it "should call where with matching ability conditions" do
184
+ obj = MongoidProject.create(:foo => {:bar => 1})
185
+ @ability.can :read, MongoidProject, :foo => {:bar => 1}
186
+ MongoidProject.accessible_by(@ability, :read).entries.first.should == obj
187
+ end
188
+
189
+ it "should exclude from the result if set to cannot" do
190
+ obj = MongoidProject.create(:bar => 1)
191
+ obj2 = MongoidProject.create(:bar => 2)
192
+ @ability.can :read, MongoidProject
193
+ @ability.cannot :read, MongoidProject, :bar => 2
194
+ MongoidProject.accessible_by(@ability, :read).entries.should == [obj]
195
+ end
196
+
197
+ it "should combine the rules" do
198
+ obj = MongoidProject.create(:bar => 1)
199
+ obj2 = MongoidProject.create(:bar => 2)
200
+ obj3 = MongoidProject.create(:bar => 3)
201
+ @ability.can :read, MongoidProject, :bar => 1
202
+ @ability.can :read, MongoidProject, :bar => 2
203
+ MongoidProject.accessible_by(@ability, :read).entries.should =~ [obj, obj2]
204
+ end
205
+
206
+ it "should not allow to fetch records when ability with just block present" do
207
+ @ability.can :read, MongoidProject do
208
+ false
209
+ end
210
+ lambda {
211
+ MongoidProject.accessible_by(@ability)
212
+ }.should raise_error(CanCan::Error)
213
+ end
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ # Most of Rule functionality is tested in Ability specs
4
+ describe CanCan::Rule do
5
+ before(:each) do
6
+ @conditions = {}
7
+ @rule = CanCan::Rule.new(true, :read, Integer, @conditions, nil)
8
+ end
9
+
10
+ it "should return no association joins if none exist" do
11
+ @rule.associations_hash.should == {}
12
+ end
13
+
14
+ it "should return no association for joins if just attributes" do
15
+ @conditions[:foo] = :bar
16
+ @rule.associations_hash.should == {}
17
+ end
18
+
19
+ it "should return single association for joins" do
20
+ @conditions[:foo] = {:bar => 1}
21
+ @rule.associations_hash.should == {:foo => {}}
22
+ end
23
+
24
+ it "should return multiple associations for joins" do
25
+ @conditions[:foo] = {:bar => 1}
26
+ @conditions[:test] = {1 => 2}
27
+ @rule.associations_hash.should == {:foo => {}, :test => {}}
28
+ end
29
+
30
+ it "should return nested associations for joins" do
31
+ @conditions[:foo] = {:bar => {1 => 2}}
32
+ @rule.associations_hash.should == {:foo => {:bar => {}}}
33
+ end
34
+
35
+ it "should return no association joins if conditions is nil" do
36
+ rule = CanCan::Rule.new(true, :read, Integer, nil, nil)
37
+ rule.associations_hash.should == {}
38
+ end
39
+ end
data/spec/matchers.rb ADDED
@@ -0,0 +1,13 @@
1
+ RSpec::Matchers.define :orderlessly_match do |original_string|
2
+ match do |given_string|
3
+ original_string.split('').sort == given_string.split('').sort
4
+ end
5
+
6
+ failure_message_for_should do |given_string|
7
+ "expected \"#{given_string}\" to have the same characters as \"#{original_string}\""
8
+ end
9
+
10
+ failure_message_for_should_not do |given_string|
11
+ "expected \"#{given_string}\" not to have the same characters as \"#{original_string}\""
12
+ end
13
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --backtrace
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require(:default)
5
+
6
+ require 'supermodel' # shouldn't Bundler do this already?
7
+ require 'active_support/all'
8
+ require 'matchers'
9
+ require 'cancan/matchers'
10
+
11
+ RSpec.configure do |config|
12
+ config.mock_with :rr
13
+ config.before(:each) do
14
+ Project.delete_all
15
+ Category.delete_all
16
+ end
17
+ end
18
+
19
+ class Ability
20
+ include CanCan::Ability
21
+
22
+ def initialize(user)
23
+ end
24
+ end
25
+
26
+ class Category < SuperModel::Base
27
+ has_many :projects
28
+ end
29
+
30
+ class Project < SuperModel::Base
31
+ belongs_to :category
32
+ attr_accessor :category # why doesn't SuperModel do this automatically?
33
+
34
+ def self.respond_to?(method, include_private = false)
35
+ if method.to_s == "find_by_name!" # hack to simulate ActiveRecord
36
+ true
37
+ else
38
+ super
39
+ end
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cancat
3
+ version: !ruby/object:Gem::Version
4
+ hash: 62196393
5
+ prerelease: 6
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ - beta
11
+ - 1
12
+ version: 0.0.1.beta1
13
+ platform: ruby
14
+ authors:
15
+ - Ryan Bates, Matthew Burket
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2011-05-30 00:00:00 -05:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: rspec
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ hash: 11
32
+ segments:
33
+ - 2
34
+ - 1
35
+ - 0
36
+ version: 2.1.0
37
+ type: :development
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: rails
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ hash: 9
48
+ segments:
49
+ - 3
50
+ - 0
51
+ - 7
52
+ version: 3.0.7
53
+ type: :development
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: rr
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ hash: 33
64
+ segments:
65
+ - 0
66
+ - 10
67
+ - 11
68
+ version: 0.10.11
69
+ type: :development
70
+ version_requirements: *id003
71
+ - !ruby/object:Gem::Dependency
72
+ name: supermodel
73
+ prerelease: false
74
+ requirement: &id004 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ hash: 19
80
+ segments:
81
+ - 0
82
+ - 1
83
+ - 4
84
+ version: 0.1.4
85
+ type: :development
86
+ version_requirements: *id004
87
+ description: Simple authorization solution for Rails which is decoupled from user roles. All permissions are stored in a single location.
88
+ email: support@AssignItApp.com
89
+ executables: []
90
+
91
+ extensions: []
92
+
93
+ extra_rdoc_files: []
94
+
95
+ files:
96
+ - lib/cancan/rule.rb
97
+ - lib/cancan/model_additions.rb
98
+ - lib/cancan/exceptions.rb
99
+ - lib/cancan/model_adapters/default_adapter.rb
100
+ - lib/cancan/model_adapters/active_record_adapter.rb
101
+ - lib/cancan/model_adapters/abstract_adapter.rb
102
+ - lib/cancan/model_adapters/data_mapper_adapter.rb
103
+ - lib/cancan/model_adapters/mongoid_adapter.rb
104
+ - lib/cancan/ability.rb
105
+ - lib/cancan/inherited_resource.rb
106
+ - lib/cancan/controller_additions.rb
107
+ - lib/cancan/matchers.rb
108
+ - lib/cancan/controller_resource.rb
109
+ - lib/cancan.rb
110
+ - lib/generators/cancan/ability/USAGE
111
+ - lib/generators/cancan/ability/templates/ability.rb
112
+ - lib/generators/cancan/ability/ability_generator.rb
113
+ - spec/spec.opts
114
+ - spec/cancan/ability_spec.rb
115
+ - spec/cancan/exceptions_spec.rb
116
+ - spec/cancan/rule_spec.rb
117
+ - spec/cancan/controller_additions_spec.rb
118
+ - spec/cancan/model_adapters/data_mapper_adapter_spec.rb
119
+ - spec/cancan/model_adapters/active_record_adapter_spec.rb
120
+ - spec/cancan/model_adapters/mongoid_adapter_spec.rb
121
+ - spec/cancan/model_adapters/default_adapter_spec.rb
122
+ - spec/cancan/matchers_spec.rb
123
+ - spec/cancan/inherited_resource_spec.rb
124
+ - spec/cancan/controller_resource_spec.rb
125
+ - spec/spec_helper.rb
126
+ - spec/README.rdoc
127
+ - spec/matchers.rb
128
+ - Gemfile
129
+ - Rakefile
130
+ - CHANGELOG.rdoc
131
+ - LICENSE
132
+ - README.rdoc
133
+ - init.rb
134
+ has_rdoc: true
135
+ homepage: http://github.com/Mab879/cancant
136
+ licenses: []
137
+
138
+ post_install_message:
139
+ rdoc_options: []
140
+
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ hash: 3
149
+ segments:
150
+ - 0
151
+ version: "0"
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ hash: 19
158
+ segments:
159
+ - 1
160
+ - 3
161
+ - 4
162
+ version: 1.3.4
163
+ requirements: []
164
+
165
+ rubyforge_project: cancat
166
+ rubygems_version: 1.6.1
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: Simple authorization solution for Rails.
170
+ test_files: []
171
+