canard 0.3.6 → 0.3.7
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.
- data/TODO +4 -2
- data/lib/ability.rb +2 -1
- data/lib/canard/adapters/active_record.rb +4 -0
- data/lib/canard/user_model.rb +10 -1
- data/lib/canard/version.rb +1 -1
- data/test/canard/ability_test.rb +42 -3
- data/test/canard/adapters/active_record_test.rb +37 -0
- data/test/canard/user_model_test.rb +34 -0
- data/test/dummy/app/models/plain_ruby_user.rb +7 -3
- metadata +105 -68
data/TODO
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
0.4.0
|
2
|
-
* Make
|
3
|
-
*
|
2
|
+
* Make framework agnostic.
|
3
|
+
* Split the test suite so Rails is only required for Rails integration. http://blog.railsware.com/2012/01/07/testing-gem-integration-with-multiple-ruby-frameworks/
|
4
4
|
* Test the railtie (currently implicity tested in dummy app).
|
5
5
|
* Add upgrade generator to move the now deprecated definitions to the new syntax.
|
6
6
|
* Remove old definition syntax and therefore deprecations.
|
7
7
|
* Remove ActiveSupport runtime dependency (which is just used for deprecation warnings).
|
8
8
|
0.5.0
|
9
9
|
* Expand the generated tests to produce all the standard abilities: index,show,read,new,create,edit,update,destroy.
|
10
|
+
* Test the generators.
|
10
11
|
* Add test unit generator.
|
11
12
|
* Add install generator to allow overriding of the default tests.
|
13
|
+
* Make the Ability user referece configureable in Ability.
|
data/lib/ability.rb
CHANGED
@@ -37,7 +37,8 @@ class Ability
|
|
37
37
|
|
38
38
|
if @user
|
39
39
|
# Add the base user abilities.
|
40
|
-
|
40
|
+
user_class_name = @user.class.name.to_s
|
41
|
+
append_abilities user_class_name.underscore.to_sym unless user_class_name.length == 0
|
41
42
|
else
|
42
43
|
# If user not set then lets create a guest
|
43
44
|
@user = Object.new
|
@@ -17,6 +17,10 @@ module Canard
|
|
17
17
|
define_scope_method(:with_all_roles) do |*roles|
|
18
18
|
where("#{role_mask_column} & :role_mask = :role_mask", { :role_mask => mask_for(*roles) })
|
19
19
|
end
|
20
|
+
|
21
|
+
define_scope_method(:with_only_roles) do |*roles|
|
22
|
+
where("#{role_mask_column} = :role_mask", { :role_mask => mask_for(*roles) })
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
data/lib/canard/user_model.rb
CHANGED
@@ -58,12 +58,13 @@ module Canard
|
|
58
58
|
# returns all the users who don't have the manager role.
|
59
59
|
def acts_as_user(*args)
|
60
60
|
include RoleModel
|
61
|
+
include InstanceMethods
|
61
62
|
extend Adapters::ActiveRecord if defined?(ActiveRecord) && self < ActiveRecord::Base
|
62
63
|
|
63
64
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
64
65
|
|
65
66
|
roles_attribute options[:roles_mask] if options.has_key?(:roles_mask)
|
66
|
-
|
67
|
+
|
67
68
|
roles options[:roles] if options.has_key?(:roles) && has_roles_mask_accessors?
|
68
69
|
|
69
70
|
add_role_scopes if respond_to?(:add_role_scopes, true)
|
@@ -79,5 +80,13 @@ module Canard
|
|
79
80
|
instance_method_names.include?(accessor)
|
80
81
|
end
|
81
82
|
end
|
83
|
+
|
84
|
+
module InstanceMethods
|
85
|
+
|
86
|
+
def ability
|
87
|
+
@ability ||= Ability.new(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
82
91
|
end
|
83
92
|
end
|
data/lib/canard/version.rb
CHANGED
data/test/canard/ability_test.rb
CHANGED
@@ -34,7 +34,7 @@ describe Ability do
|
|
34
34
|
|
35
35
|
end
|
36
36
|
|
37
|
-
describe "
|
37
|
+
describe "with a user that has author role" do
|
38
38
|
|
39
39
|
let(:user) { User.create(:roles => [:author]) }
|
40
40
|
let(:member) { Member.create(:user => user) }
|
@@ -64,7 +64,7 @@ describe Ability do
|
|
64
64
|
|
65
65
|
end
|
66
66
|
|
67
|
-
describe "
|
67
|
+
describe "with a user that has admin and author roles" do
|
68
68
|
|
69
69
|
let(:user) { User.create(:roles => [:author, :admin]) }
|
70
70
|
let(:member) { Member.create(:user => user) }
|
@@ -93,7 +93,7 @@ describe Ability do
|
|
93
93
|
|
94
94
|
end
|
95
95
|
|
96
|
-
describe "
|
96
|
+
describe "with no user" do
|
97
97
|
|
98
98
|
subject { Ability.new }
|
99
99
|
|
@@ -109,6 +109,45 @@ describe Ability do
|
|
109
109
|
subject.cannot?(:show, Member)
|
110
110
|
end
|
111
111
|
end
|
112
|
+
|
113
|
+
describe "with an instance of an anonymous class that has author role" do
|
114
|
+
|
115
|
+
let(:klass) do
|
116
|
+
Class.new do
|
117
|
+
extend Canard::UserModel
|
118
|
+
attr_accessor :roles_mask
|
119
|
+
acts_as_user :roles => [:author, :admin]
|
120
|
+
def initialize(*roles); self.roles = roles; end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
let(:instance) { klass.new(:author) }
|
124
|
+
|
125
|
+
describe "for base class abilities" do
|
126
|
+
|
127
|
+
it "does nothing" do
|
128
|
+
proc { Ability.new(instance) }.must_be_silent
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "for assigned roles" do
|
133
|
+
|
134
|
+
subject { Ability.new(instance) }
|
135
|
+
|
136
|
+
it "has all the abilities of an author" do
|
137
|
+
subject.can?(:new, Post).must_equal true
|
138
|
+
subject.can?(:create, Post).must_equal true
|
139
|
+
subject.can?(:edit, Post).must_equal true
|
140
|
+
subject.can?(:update, Post).must_equal true
|
141
|
+
subject.can?(:show, Post).must_equal true
|
142
|
+
subject.can?(:index, Post).must_equal true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "has no admin abilities" do
|
146
|
+
subject.cannot?(:destroy, Post).must_equal true
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
112
151
|
end
|
113
152
|
|
114
153
|
end
|
@@ -436,6 +436,43 @@ describe Canard::Adapters::ActiveRecord do
|
|
436
436
|
|
437
437
|
end
|
438
438
|
|
439
|
+
describe "with_only_roles" do
|
440
|
+
|
441
|
+
describe "specifying one role" do
|
442
|
+
|
443
|
+
subject { User.with_only_roles(:admin).sort_by(&:id) }
|
444
|
+
|
445
|
+
it "returns users with just that role" do
|
446
|
+
subject.must_equal [@admin_only].sort_by(&:id)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "doesn't return any other users" do
|
450
|
+
subject.wont_include @no_role
|
451
|
+
subject.wont_include @admin_author_viewer
|
452
|
+
subject.wont_include @author_viewer
|
453
|
+
subject.wont_include @author_only
|
454
|
+
subject.wont_include @viewer
|
455
|
+
end
|
456
|
+
|
457
|
+
end
|
458
|
+
|
459
|
+
describe "specifying multiple roles" do
|
460
|
+
|
461
|
+
subject { User.with_only_roles(:author, :viewer).sort_by(&:id) }
|
462
|
+
|
463
|
+
it "returns only users with no more or less roles" do
|
464
|
+
subject.must_equal [@author_viewer].sort_by(&:id)
|
465
|
+
end
|
466
|
+
|
467
|
+
it "doesn't return any other users" do
|
468
|
+
subject.wont_include @no_role
|
469
|
+
subject.wont_include @admin_author_viewer
|
470
|
+
subject.wont_include @admin_only
|
471
|
+
subject.wont_include @author_only
|
472
|
+
subject.wont_include @viewer
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
439
476
|
end
|
440
477
|
end
|
441
478
|
|
@@ -87,5 +87,39 @@ describe Canard::UserModel do
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe Canard::UserModel::InstanceMethods do
|
93
|
+
|
94
|
+
before do
|
95
|
+
Canard::Abilities.default_path = File.expand_path('../../dummy/app/abilities', __FILE__)
|
96
|
+
# reload abilities because the reloader will have removed them after the railtie ran
|
97
|
+
Canard.find_abilities
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "ability" do
|
101
|
+
|
102
|
+
before do
|
103
|
+
PlainRubyUser.acts_as_user :roles => [:admin, :author]
|
104
|
+
end
|
90
105
|
|
106
|
+
subject { PlainRubyUser.new(:author).ability }
|
107
|
+
|
108
|
+
it "returns an ability for this instance" do
|
109
|
+
subject.must_be_instance_of Ability
|
110
|
+
end
|
111
|
+
|
112
|
+
it "has the users abilities" do
|
113
|
+
subject.can?(:new, Post).must_equal true
|
114
|
+
subject.can?(:create, Post).must_equal true
|
115
|
+
subject.can?(:edit, Post).must_equal true
|
116
|
+
subject.can?(:update, Post).must_equal true
|
117
|
+
subject.can?(:show, Post).must_equal true
|
118
|
+
subject.can?(:index, Post).must_equal true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "has no other abilities" do
|
122
|
+
subject.cannot?(:destroy, Post).must_equal true
|
123
|
+
end
|
124
|
+
end
|
91
125
|
end
|
metadata
CHANGED
@@ -1,90 +1,118 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: canard
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 7
|
10
|
+
version: 0.3.7
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- James McCarthy
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2012-06-23 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: minitest
|
16
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
24
|
none: false
|
18
|
-
requirements:
|
25
|
+
requirements:
|
19
26
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 7
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
version: "2"
|
22
32
|
type: :development
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
26
35
|
name: sqlite3
|
27
|
-
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
38
|
none: false
|
29
|
-
requirements:
|
30
|
-
- -
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
33
46
|
type: :development
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
37
49
|
name: rails
|
38
|
-
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
52
|
none: false
|
40
|
-
requirements:
|
53
|
+
requirements:
|
41
54
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 9
|
57
|
+
segments:
|
58
|
+
- 3
|
59
|
+
- 2
|
60
|
+
- 3
|
43
61
|
version: 3.2.3
|
44
62
|
type: :development
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
48
65
|
name: activesupport
|
49
|
-
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
68
|
none: false
|
51
|
-
requirements:
|
52
|
-
- -
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
55
76
|
type: :runtime
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
59
79
|
name: cancan
|
60
|
-
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
82
|
none: false
|
62
|
-
requirements:
|
63
|
-
- -
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
66
90
|
type: :runtime
|
67
|
-
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
91
|
+
version_requirements: *id005
|
92
|
+
- !ruby/object:Gem::Dependency
|
70
93
|
name: role_model
|
71
|
-
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
72
96
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
77
104
|
type: :runtime
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
easy in Rails 3.x.
|
82
|
-
email:
|
105
|
+
version_requirements: *id006
|
106
|
+
description: Wraps CanCan and RoleModel up to make role based authorisation really easy in Rails 3.x.
|
107
|
+
email:
|
83
108
|
- james2mccarthy@gmail.com
|
84
109
|
executables: []
|
110
|
+
|
85
111
|
extensions: []
|
112
|
+
|
86
113
|
extra_rdoc_files: []
|
87
|
-
|
114
|
+
|
115
|
+
files:
|
88
116
|
- .gitignore
|
89
117
|
- Gemfile
|
90
118
|
- MIT-LICENSE
|
@@ -147,29 +175,38 @@ files:
|
|
147
175
|
- test/test_helper.rb
|
148
176
|
homepage: https://github.com/james2m/canard
|
149
177
|
licenses: []
|
178
|
+
|
150
179
|
post_install_message:
|
151
180
|
rdoc_options: []
|
152
|
-
|
181
|
+
|
182
|
+
require_paths:
|
153
183
|
- lib
|
154
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
184
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
185
|
none: false
|
156
|
-
requirements:
|
157
|
-
- -
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
|
160
|
-
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
hash: 3
|
190
|
+
segments:
|
191
|
+
- 0
|
192
|
+
version: "0"
|
193
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
194
|
none: false
|
162
|
-
requirements:
|
163
|
-
- -
|
164
|
-
- !ruby/object:Gem::Version
|
165
|
-
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
hash: 3
|
199
|
+
segments:
|
200
|
+
- 0
|
201
|
+
version: "0"
|
166
202
|
requirements: []
|
203
|
+
|
167
204
|
rubyforge_project: canard
|
168
|
-
rubygems_version: 1.8.
|
205
|
+
rubygems_version: 1.8.24
|
169
206
|
signing_key:
|
170
207
|
specification_version: 3
|
171
208
|
summary: Adds role based authorisation to Rails by combining RoleModel and CanCan.
|
172
|
-
test_files:
|
209
|
+
test_files:
|
173
210
|
- test/abilities/admins.rb
|
174
211
|
- test/canard/abilities_test.rb
|
175
212
|
- test/canard/ability_test.rb
|