rolify 4.0.0 → 4.1.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/.gitignore +1 -0
- data/CHANGELOG.rdoc +6 -0
- data/README.md +27 -10
- data/lib/generators/active_record/rolify_generator.rb +9 -0
- data/lib/rolify.rb +11 -2
- data/lib/rolify/adapters/active_record/resource_adapter.rb +5 -0
- data/lib/rolify/adapters/active_record/role_adapter.rb +15 -0
- data/lib/rolify/adapters/base.rb +1 -0
- data/lib/rolify/adapters/mongoid/resource_adapter.rb +4 -0
- data/lib/rolify/adapters/mongoid/role_adapter.rb +14 -0
- data/lib/rolify/configure.rb +2 -2
- data/lib/rolify/dynamic.rb +14 -3
- data/lib/rolify/finders.rb +4 -0
- data/lib/rolify/resource.rb +19 -4
- data/lib/rolify/role.rb +12 -1
- data/lib/rolify/version.rb +1 -1
- data/spec/rolify/config_spec.rb +4 -4
- data/spec/rolify/coverage/.last_run.json +5 -0
- data/spec/rolify/coverage/.resultset.json +7 -0
- data/spec/rolify/coverage/.resultset.json.lock +0 -0
- data/spec/rolify/resource_spec.rb +176 -19
- data/spec/rolify/shared_examples/shared_examples_for_finders.rb +50 -0
- data/spec/rolify/shared_examples/shared_examples_for_has_role.rb +6 -1
- data/spec/rolify/shared_examples/shared_examples_for_roles.rb +1 -0
- data/spec/support/adapters/active_record.rb +7 -0
- data/spec/support/adapters/mongoid.rb +10 -1
- data/spec/support/data.rb +3 -3
- data/spec/support/schema.rb +6 -1
- metadata +9 -4
- data/circle.yml +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edae47a21706d1859520df05876acf68d95c0d48
|
4
|
+
data.tar.gz: 09dbd84321d04321d1ef889db0911fa86f1ccbe4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 910c97443cd78a0386a36f2d6645708c7f6eadf5b84815ca51f8b1cbd39f4a6e1236a16688c37ef99a48234deb44a25c684e7852ce146f7d0e75cc22817a841c
|
7
|
+
data.tar.gz: 4525bec755d35bb470d364088bdfe2c7f2a39b61cf140944363518ed5626de9f4c438c088d432002a7b41edc750dccc7a032b94f76d075d068f0770b762223cb
|
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= 4.1.0 (Aug 04, 2015)
|
2
|
+
* added `without_role` method for resources and classes
|
3
|
+
* fix `has_role?` with :any and an unsaved user
|
4
|
+
* rename the `with_role` method on a resource to `find_as`
|
5
|
+
* add a strict parameter to check only roles that were set without supers.
|
6
|
+
|
1
7
|
= 4.0.0 (Feb 12, 2015)
|
2
8
|
* Increasing version number to 4.0.0 for semantic versioning since `has_role` was removed in 3.5.0
|
3
9
|
* Fix spec to pass.
|
data/README.md
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
# rolify [](http://badge.fury.io/rb/rolify) [](http://travis-ci.org/RolifyCommunity/rolify) [](https://gemnasium.com/RolifyCommunity/rolify) [](https://codeclimate.com/github/RolifyCommunity/rolify) [](https://coveralls.io/r/RolifyCommunity/rolify?branch=master)
|
2
2
|
|
3
|
-
|
4
3
|
Very simple Roles library without any authorization enforcement supporting scope on resource object.
|
5
4
|
|
6
|
-
Let's see an example:
|
5
|
+
Let's see an example:
|
7
6
|
|
8
7
|
```ruby
|
9
|
-
user.has_role?(:moderator, Forum.first)
|
8
|
+
user.has_role?(:moderator, Forum.first)
|
10
9
|
=> false # if user is moderator of another Forum
|
11
10
|
```
|
12
11
|
|
@@ -23,7 +22,7 @@ This library can be easily integrated with any authentication gem ([devise](http
|
|
23
22
|
|
24
23
|
## Installation
|
25
24
|
|
26
|
-
|
25
|
+
Add this to your Gemfile and run the +bundle+ command.
|
27
26
|
|
28
27
|
```ruby
|
29
28
|
gem "rolify"
|
@@ -119,7 +118,7 @@ That's it !
|
|
119
118
|
|
120
119
|
### 5. Role queries
|
121
120
|
|
122
|
-
To check if a user has a global role:
|
121
|
+
To check if a user has a global role:
|
123
122
|
|
124
123
|
```ruby
|
125
124
|
user = User.find(1)
|
@@ -152,7 +151,7 @@ user.has_role? :moderator, Forum.last
|
|
152
151
|
=> true
|
153
152
|
```
|
154
153
|
|
155
|
-
A global role overrides resource role request:
|
154
|
+
A global role overrides resource role request:
|
156
155
|
|
157
156
|
```ruby
|
158
157
|
user = User.find(4)
|
@@ -163,7 +162,7 @@ user.has_role? :moderator, Forum.last
|
|
163
162
|
=> true
|
164
163
|
```
|
165
164
|
|
166
|
-
### 6. Resource roles querying
|
165
|
+
### 6. Resource roles querying
|
167
166
|
|
168
167
|
Starting from rolify 3.0, you can search roles on instance level or class level resources.
|
169
168
|
|
@@ -181,10 +180,10 @@ forum.applied_roles
|
|
181
180
|
|
182
181
|
```ruby
|
183
182
|
Forum.with_role(:admin)
|
184
|
-
# => [ list of Forum instances that has role "admin" binded to it ]
|
183
|
+
# => [ list of Forum instances that has role "admin" binded to it ]
|
185
184
|
Forum.with_role(:admin, current_user)
|
186
185
|
# => [ list of Forum instances that has role "admin" binded to it and belongs to current_user roles ]
|
187
|
-
Forum.
|
186
|
+
Forum.with_all_roles([:admin, :user], current_user)
|
188
187
|
# => [ list of Forum instances that has role "admin" or "user" binded to it and belongs to current_user roles ]
|
189
188
|
|
190
189
|
User.with_any_role(:user, :admin)
|
@@ -202,12 +201,30 @@ Forum.find_roles(:admin, current_user)
|
|
202
201
|
# => [ list of roles that binded to any Forum instance or to the Forum class with "admin" as a role name and belongs to current_user roles ]
|
203
202
|
```
|
204
203
|
|
204
|
+
### Strict Mode
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
class User < ActiveRecord::Base
|
208
|
+
rolify strict: true
|
209
|
+
end
|
210
|
+
|
211
|
+
@user = User.first
|
212
|
+
|
213
|
+
@user.add_role(:forum, Forum)
|
214
|
+
@user.add_role(:forum, Forum.first)
|
215
|
+
|
216
|
+
@user.has_role?(:forum, Forum) #=> true
|
217
|
+
@user.has_role?(:forum, Forum.first) #=> true
|
218
|
+
@user.has_role?(:forum, Forum.last) #=> false
|
219
|
+
```
|
220
|
+
I.e. you get true only on a role that you manually add.
|
221
|
+
|
205
222
|
## Resources
|
206
223
|
|
207
224
|
* [Wiki](https://github.com/RolifyCommunity/rolify/wiki)
|
208
225
|
* [Usage](https://github.com/RolifyCommunity/rolify/wiki/Usage): all the available commands
|
209
226
|
* [Tutorials](https://github.com/RolifyCommunity/rolify/wiki#wiki-tutorials):
|
210
|
-
* [How-To use rolify with Devise and
|
227
|
+
* [How-To use rolify with Devise and CanCanCan](https://github.com/RolifyCommunity/rolify/wiki/Devise---CanCanCan---rolify-Tutorial)
|
211
228
|
* [Using rolify with Devise and Authority](https://github.com/RolifyCommunity/rolify/wiki/Using-rolify-with-Devise-and-Authority)
|
212
229
|
* [Step-by-step tutorial](http://railsapps.github.com/tutorial-rails-bootstrap-devise-cancan.html) provided by [RailsApps](http://railsapps.github.com/)
|
213
230
|
|
@@ -13,6 +13,15 @@ module ActiveRecord
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def inject_role_class
|
16
|
+
if args[1]=="engine"
|
17
|
+
if args[2]=="devise"
|
18
|
+
require 'devise'
|
19
|
+
require "#{ENGINE_ROOT}/config/initializers/devise.rb"
|
20
|
+
require "#{ENGINE_ROOT}/app/models/#{user_cname.downcase}.rb"
|
21
|
+
else
|
22
|
+
require "#{ENGINE_ROOT}/app/models/#{user_cname.downcase}.rb"
|
23
|
+
end
|
24
|
+
end
|
16
25
|
inject_into_class(model_path, class_name, model_content)
|
17
26
|
end
|
18
27
|
|
data/lib/rolify.rb
CHANGED
@@ -8,7 +8,7 @@ require 'rolify/role'
|
|
8
8
|
module Rolify
|
9
9
|
extend Configure
|
10
10
|
|
11
|
-
attr_accessor :role_cname, :adapter, :role_join_table_name, :role_table_name
|
11
|
+
attr_accessor :role_cname, :adapter, :resource_adapter, :role_join_table_name, :role_table_name, :strict_rolify
|
12
12
|
@@resource_types = []
|
13
13
|
|
14
14
|
def rolify(options = {})
|
@@ -31,6 +31,9 @@ module Rolify
|
|
31
31
|
|
32
32
|
self.adapter = Rolify::Adapter::Base.create("role_adapter", self.role_cname, self.name)
|
33
33
|
load_dynamic_methods if Rolify.dynamic_shortcuts
|
34
|
+
|
35
|
+
#use strict roles
|
36
|
+
self.strict_rolify = true if options[:strict]
|
34
37
|
end
|
35
38
|
|
36
39
|
def adapter
|
@@ -48,10 +51,15 @@ module Rolify
|
|
48
51
|
|
49
52
|
has_many association_name, resourcify_options
|
50
53
|
|
51
|
-
self.
|
54
|
+
self.resource_adapter = Rolify::Adapter::Base.create("resource_adapter", self.role_cname, self.name)
|
52
55
|
@@resource_types << self.name
|
53
56
|
end
|
54
57
|
|
58
|
+
def resource_adapter
|
59
|
+
return self.superclass.resource_adapter unless self.instance_variable_defined? '@resource_adapter'
|
60
|
+
@resource_adapter
|
61
|
+
end
|
62
|
+
|
55
63
|
def scopify
|
56
64
|
require "rolify/adapters/#{Rolify.orm}/scopes.rb"
|
57
65
|
extend Rolify::Adapter::Scopes
|
@@ -65,4 +73,5 @@ module Rolify
|
|
65
73
|
def self.resource_types
|
66
74
|
@@resource_types
|
67
75
|
end
|
76
|
+
|
68
77
|
end
|
@@ -8,6 +8,16 @@ module Rolify
|
|
8
8
|
relation.where(conditions, *values)
|
9
9
|
end
|
10
10
|
|
11
|
+
def where_strict(relation, args)
|
12
|
+
resource = if args[:resource].is_a?(Class)
|
13
|
+
{class: args[:resource].to_s, id: nil}
|
14
|
+
else
|
15
|
+
{class: args[:resource].class.name, id: args[:resource].id}
|
16
|
+
end
|
17
|
+
|
18
|
+
relation.where(:name => args[:name], :resource_type => resource[:class], :resource_id => resource[:id])
|
19
|
+
end
|
20
|
+
|
11
21
|
def find_or_create_by(role_name, resource_type = nil, resource_id = nil)
|
12
22
|
role_class.where(:name => role_name, :resource_type => resource_type, :resource_id => resource_id).first_or_create
|
13
23
|
end
|
@@ -45,6 +55,11 @@ module Rolify
|
|
45
55
|
query
|
46
56
|
end
|
47
57
|
|
58
|
+
def all_except(user, excluded_obj)
|
59
|
+
prime_key = user.primary_key.to_sym
|
60
|
+
user.where(prime_key => (user.all - excluded_obj).map(&prime_key))
|
61
|
+
end
|
62
|
+
|
48
63
|
private
|
49
64
|
|
50
65
|
def build_conditions(relation, args)
|
data/lib/rolify/adapters/base.rb
CHANGED
@@ -8,6 +8,16 @@ module Rolify
|
|
8
8
|
relation.any_of(*conditions)
|
9
9
|
end
|
10
10
|
|
11
|
+
def where_strict(relation, args)
|
12
|
+
resource = if args[:resource].is_a?(Class)
|
13
|
+
{class: args[:resource].to_s, id: nil}
|
14
|
+
else
|
15
|
+
{class: args[:resource].class.name, id: args[:resource].id}
|
16
|
+
end
|
17
|
+
|
18
|
+
relation.where(:name => args[:name], :resource_type => resource[:class], :resource_id => resource[:id])
|
19
|
+
end
|
20
|
+
|
11
21
|
def find_or_create_by(role_name, resource_type = nil, resource_id = nil)
|
12
22
|
self.role_class.find_or_create_by(:name => role_name,
|
13
23
|
:resource_type => resource_type,
|
@@ -58,6 +68,10 @@ module Rolify
|
|
58
68
|
query
|
59
69
|
end
|
60
70
|
|
71
|
+
def all_except(user, excluded_obj)
|
72
|
+
user.not_in(_id: excluded_obj.to_a)
|
73
|
+
end
|
74
|
+
|
61
75
|
private
|
62
76
|
|
63
77
|
def build_conditions(relation, args)
|
data/lib/rolify/configure.rb
CHANGED
@@ -52,13 +52,13 @@ module Rolify
|
|
52
52
|
private
|
53
53
|
|
54
54
|
def sanity_check(role_cnames)
|
55
|
-
return true if
|
55
|
+
return true if (ARGV[0] =~ /assets:/) == 0
|
56
56
|
|
57
57
|
role_cnames = [ "Role" ] if role_cnames.empty?
|
58
58
|
role_cnames.each do |role_cname|
|
59
59
|
role_class = role_cname.constantize
|
60
60
|
if role_class.superclass.to_s == "ActiveRecord::Base" && role_table_missing?(role_class)
|
61
|
-
warn "[WARN] table '#{role_cname}' doesn't exist. Did you run the migration
|
61
|
+
warn "[WARN] table '#{role_cname}' doesn't exist. Did you run the migration? Ignoring rolify config."
|
62
62
|
return false
|
63
63
|
end
|
64
64
|
end
|
data/lib/rolify/dynamic.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
+
require "rolify/configure"
|
2
|
+
|
1
3
|
module Rolify
|
2
4
|
module Dynamic
|
3
5
|
def load_dynamic_methods
|
4
|
-
|
5
|
-
|
6
|
+
if ENV['ADAPTER'] == 'mongoid'
|
7
|
+
# for compatibility with MongoidDB - does not support polymorphic includes
|
8
|
+
self.role_class.all.each do |r|
|
9
|
+
define_dynamic_method(r.name, r.resource)
|
10
|
+
end
|
11
|
+
else
|
12
|
+
# otherwise should be able to support polymorphic includes.
|
13
|
+
# supported Rails version >= 3.2 with AR should use find_each, since use of .all.each is deprecated
|
14
|
+
self.role_class.includes(:resource).find_each do |r|
|
15
|
+
define_dynamic_method(r.name, r.resource)
|
16
|
+
end
|
6
17
|
end
|
7
18
|
end
|
8
19
|
|
@@ -18,4 +29,4 @@ module Rolify
|
|
18
29
|
end
|
19
30
|
end
|
20
31
|
end
|
21
|
-
end
|
32
|
+
end
|
data/lib/rolify/finders.rb
CHANGED
@@ -4,6 +4,10 @@ module Rolify
|
|
4
4
|
self.adapter.scope(self, :name => role_name, :resource => resource)
|
5
5
|
end
|
6
6
|
|
7
|
+
def without_role(role_name, resource = nil)
|
8
|
+
self.adapter.all_except(self, self.with_role(role_name, resource))
|
9
|
+
end
|
10
|
+
|
7
11
|
def with_all_roles(*args)
|
8
12
|
users = []
|
9
13
|
parse_args(args, users) do |users_to_add|
|
data/lib/rolify/resource.rb
CHANGED
@@ -6,7 +6,7 @@ module Rolify
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
def find_roles(role_name = nil, user = nil)
|
9
|
-
self.
|
9
|
+
self.resource_adapter.find_roles(role_name, self, user)
|
10
10
|
end
|
11
11
|
|
12
12
|
def with_role(role_name, user = nil)
|
@@ -16,14 +16,29 @@ module Rolify
|
|
16
16
|
role_name = role_name.to_s
|
17
17
|
end
|
18
18
|
|
19
|
-
resources = self.
|
20
|
-
user ? self.
|
19
|
+
resources = self.resource_adapter.resources_find(self.role_table_name, self, role_name) #.map(&:id)
|
20
|
+
user ? self.resource_adapter.in(resources, user, role_name) : resources
|
21
21
|
end
|
22
22
|
alias :with_roles :with_role
|
23
|
+
alias :find_as :with_role
|
24
|
+
alias :find_multiple_as :with_role
|
25
|
+
|
26
|
+
|
27
|
+
def without_role(role_name, user = nil)
|
28
|
+
self.resource_adapter.all_except(self, self.find_as(role_name, user))
|
29
|
+
end
|
30
|
+
alias :without_roles :without_role
|
31
|
+
alias :except_as :without_role
|
32
|
+
alias :except_multiple_as :without_role
|
33
|
+
|
34
|
+
|
23
35
|
|
24
36
|
def applied_roles(children = true)
|
25
|
-
self.
|
37
|
+
self.resource_adapter.applied_roles(self, children)
|
26
38
|
end
|
39
|
+
|
40
|
+
|
41
|
+
|
27
42
|
end
|
28
43
|
|
29
44
|
def applied_roles
|
data/lib/rolify/role.rb
CHANGED
@@ -23,8 +23,15 @@ module Rolify
|
|
23
23
|
alias_method :grant, :add_role
|
24
24
|
|
25
25
|
def has_role?(role_name, resource = nil)
|
26
|
+
return has_strict_role?(role_name, resource) if self.class.strict_rolify and resource and resource != :any
|
27
|
+
|
26
28
|
if new_record?
|
27
|
-
role_array = self.roles.detect { |r|
|
29
|
+
role_array = self.roles.detect { |r|
|
30
|
+
r.name.to_s == role_name.to_s &&
|
31
|
+
(r.resource == resource ||
|
32
|
+
resource.nil? ||
|
33
|
+
(resource == :any && r.resource.present?))
|
34
|
+
}
|
28
35
|
else
|
29
36
|
role_array = self.class.adapter.where(self.roles, name: role_name, resource: resource)
|
30
37
|
end
|
@@ -33,6 +40,10 @@ module Rolify
|
|
33
40
|
role_array != []
|
34
41
|
end
|
35
42
|
|
43
|
+
def has_strict_role?(role_name, resource)
|
44
|
+
self.class.adapter.where_strict(self.roles, name: role_name, resource: resource).any?
|
45
|
+
end
|
46
|
+
|
36
47
|
def has_all_roles?(*args)
|
37
48
|
args.each do |arg|
|
38
49
|
if arg.is_a? Hash
|
data/lib/rolify/version.rb
CHANGED
data/spec/rolify/config_spec.rb
CHANGED
@@ -57,7 +57,7 @@ describe Rolify do
|
|
57
57
|
|
58
58
|
subject { Forum }
|
59
59
|
|
60
|
-
its("
|
60
|
+
its("resource_adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -88,7 +88,7 @@ describe Rolify do
|
|
88
88
|
|
89
89
|
subject { Forum }
|
90
90
|
|
91
|
-
its("
|
91
|
+
its("resource_adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -118,7 +118,7 @@ describe Rolify do
|
|
118
118
|
|
119
119
|
subject { Forum }
|
120
120
|
|
121
|
-
its("
|
121
|
+
its("resource_adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
@@ -184,7 +184,7 @@ describe Rolify do
|
|
184
184
|
|
185
185
|
subject { Forum }
|
186
186
|
it { should satisfy { |u| u.include? Rolify::Resource }}
|
187
|
-
its("
|
187
|
+
its("resource_adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
|
188
188
|
end
|
189
189
|
end
|
190
190
|
end
|
File without changes
|
@@ -27,7 +27,7 @@ describe Rolify::Resource do
|
|
27
27
|
let!(:player_role) { captain.add_role(:player, Team.last) }
|
28
28
|
let!(:company_role) { admin.add_role(:owner, Company.first) }
|
29
29
|
|
30
|
-
describe ".
|
30
|
+
describe ".find_multiple_as" do
|
31
31
|
subject { Group }
|
32
32
|
|
33
33
|
it { should respond_to(:find_roles).with(1).arguments }
|
@@ -38,15 +38,15 @@ describe Rolify::Resource do
|
|
38
38
|
subject { Forum }
|
39
39
|
|
40
40
|
it "should include Forum instances with forum role" do
|
41
|
-
subject.
|
41
|
+
subject.find_as(:forum).should =~ [ Forum.first, Forum.last ]
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should include Forum instances with godfather role" do
|
45
|
-
subject.
|
45
|
+
subject.find_as(:godfather).should =~ Forum.all
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should be able to modify the resource", :if => ENV['ADAPTER'] == 'active_record' do
|
49
|
-
forum_resource = subject.
|
49
|
+
forum_resource = subject.find_as(:forum).first
|
50
50
|
forum_resource.name = "modified name"
|
51
51
|
expect { forum_resource.save }.not_to raise_error
|
52
52
|
end
|
@@ -56,7 +56,7 @@ describe Rolify::Resource do
|
|
56
56
|
subject { Group }
|
57
57
|
|
58
58
|
it "should include Group instances with group role" do
|
59
|
-
subject.
|
59
|
+
subject.find_as(:group).should =~ [ Group.last ]
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -64,7 +64,7 @@ describe Rolify::Resource do
|
|
64
64
|
subject { Group.last }
|
65
65
|
|
66
66
|
it "should ignore nil entries" do
|
67
|
-
subject.subgroups.
|
67
|
+
subject.subgroups.find_as(:group).should =~ [ ]
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -74,7 +74,7 @@ describe Rolify::Resource do
|
|
74
74
|
subject { Group }
|
75
75
|
|
76
76
|
it "should include Group instances with both group and grouper roles" do
|
77
|
-
subject.
|
77
|
+
subject.find_multiple_as([:group, :grouper]).should =~ [ Group.first, Group.last ]
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -84,27 +84,27 @@ describe Rolify::Resource do
|
|
84
84
|
subject { Forum }
|
85
85
|
|
86
86
|
it "should get all Forum instances binded to the forum role and the admin user" do
|
87
|
-
subject.
|
87
|
+
subject.find_as(:forum, admin).should =~ [ Forum.first ]
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should get all Forum instances binded to the forum role and the tourist user" do
|
91
|
-
subject.
|
91
|
+
subject.find_as(:forum, tourist).should =~ [ Forum.last ]
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should get all Forum instances binded to the godfather role and the admin user" do
|
95
|
-
subject.
|
95
|
+
subject.find_as(:godfather, admin).should =~ Forum.all.to_a
|
96
96
|
end
|
97
97
|
|
98
98
|
it "should get all Forum instances binded to the godfather role and the tourist user" do
|
99
|
-
subject.
|
99
|
+
subject.find_as(:godfather, tourist).should be_empty
|
100
100
|
end
|
101
101
|
|
102
102
|
it "should get Forum instances binded to the group role and the tourist user" do
|
103
|
-
subject.
|
103
|
+
subject.find_as(:group, tourist).should =~ [ Forum.first ]
|
104
104
|
end
|
105
105
|
|
106
106
|
it "should not get Forum instances not binded to the group role and the tourist user" do
|
107
|
-
subject.
|
107
|
+
subject.find_as(:group, tourist).should_not include(Forum.last)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -112,11 +112,11 @@ describe Rolify::Resource do
|
|
112
112
|
subject { Group }
|
113
113
|
|
114
114
|
it "should get all resources binded to the group role and the admin user" do
|
115
|
-
subject.
|
115
|
+
subject.find_as(:group, admin).should =~ [ Group.last ]
|
116
116
|
end
|
117
117
|
|
118
118
|
it "should not get resources not binded to the group role and the admin user" do
|
119
|
-
subject.
|
119
|
+
subject.find_as(:group, admin).should_not include(Group.first)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -126,7 +126,7 @@ describe Rolify::Resource do
|
|
126
126
|
subject { Forum }
|
127
127
|
|
128
128
|
it "should get Forum instances binded to the forum and group roles and the tourist user" do
|
129
|
-
subject.
|
129
|
+
subject.find_multiple_as([:forum, :group], tourist).should =~ [ Forum.first, Forum.last ]
|
130
130
|
end
|
131
131
|
|
132
132
|
end
|
@@ -135,7 +135,7 @@ describe Rolify::Resource do
|
|
135
135
|
subject { Group }
|
136
136
|
|
137
137
|
it "should get Group instances binded to the group and grouper roles and the admin user" do
|
138
|
-
subject.
|
138
|
+
subject.find_multiple_as([:group, :grouper], admin).should =~ [ Group.first, Group.last ]
|
139
139
|
end
|
140
140
|
|
141
141
|
end
|
@@ -145,14 +145,138 @@ describe Rolify::Resource do
|
|
145
145
|
subject { Team }
|
146
146
|
|
147
147
|
it "should find Team instance using team_code column" do
|
148
|
-
subject.
|
148
|
+
subject.find_multiple_as([:captain, :player], captain).should =~ [ Team.first, Team.last ]
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
152
|
context "with a resource using STI" do
|
153
153
|
subject { Organization }
|
154
154
|
it "should find instances of children classes" do
|
155
|
-
subject.
|
155
|
+
subject.find_multiple_as(:owner, admin).should =~ [ Company.first ]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
describe ".except_multiple_as" do
|
162
|
+
subject { Group }
|
163
|
+
|
164
|
+
it { should respond_to(:find_roles).with(1).arguments }
|
165
|
+
it { should respond_to(:find_roles).with(2).arguments }
|
166
|
+
|
167
|
+
context "with a role name as argument" do
|
168
|
+
context "on the Forum class" do
|
169
|
+
subject { Forum }
|
170
|
+
|
171
|
+
it "should not include Forum instances with forum role" do
|
172
|
+
subject.except_as(:forum).should_not =~ [ Forum.first, Forum.last ]
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should not include Forum instances with godfather role" do
|
176
|
+
subject.except_as(:godfather).should be_empty
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should be able to modify the resource", :if => ENV['ADAPTER'] == 'active_record' do
|
180
|
+
forum_resource = subject.except_as(:forum).first
|
181
|
+
forum_resource.name = "modified name"
|
182
|
+
expect { forum_resource.save }.not_to raise_error
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "on the Group class" do
|
187
|
+
subject { Group }
|
188
|
+
|
189
|
+
it "should not include Group instances with group role" do
|
190
|
+
subject.except_as(:group).should_not =~ [ Group.last ]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
context "with an array of role names as argument" do
|
197
|
+
context "on the Group class" do
|
198
|
+
subject { Group }
|
199
|
+
|
200
|
+
it "should include Group instances without either the group and grouper roles" do
|
201
|
+
subject.except_multiple_as([:group, :grouper]).should_not =~ [ Group.first, Group.last ]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with a role name and a user as arguments" do
|
207
|
+
context "on the Forum class" do
|
208
|
+
subject { Forum }
|
209
|
+
|
210
|
+
it "should get all Forum instances the admin user does not have the forum role" do
|
211
|
+
subject.except_as(:forum, admin).should_not =~ [ Forum.first ]
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should get all Forum instances the tourist user does not have the forum role" do
|
215
|
+
subject.except_as(:forum, tourist).should_not =~ [ Forum.last ]
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should get all Forum instances the admin user does not have the godfather role" do
|
219
|
+
subject.except_as(:godfather, admin).should_not =~ Forum.all
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should get all Forum instances tourist user does not have the godfather role" do
|
223
|
+
subject.except_as(:godfather, tourist).should =~ Forum.all
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should get Forum instances the tourist user does not have the group role" do
|
227
|
+
subject.except_as(:group, tourist).should_not =~ [ Forum.first ]
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should get Forum instances the tourist user does not have the group role" do
|
231
|
+
subject.except_as(:group, tourist).should_not =~ [ Forum.first ]
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context "on the Group class" do
|
236
|
+
subject { Group }
|
237
|
+
|
238
|
+
it "should get all resources not bounded to the group role and the admin user" do
|
239
|
+
subject.except_as(:group, admin).should =~ [ Group.first ]
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should not get resources bound to the group role and the admin user" do
|
243
|
+
subject.except_as(:group, admin).should include(Group.first)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context "with an array of role names and a user as arguments" do
|
249
|
+
context "on the Forum class" do
|
250
|
+
subject { Forum }
|
251
|
+
|
252
|
+
it "should get Forum instances not bound to the forum and group roles and the tourist user" do
|
253
|
+
subject.except_multiple_as([:forum, :group], tourist).should_not =~ [ Forum.first, Forum.last ]
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
context "on the Group class" do
|
259
|
+
subject { Group }
|
260
|
+
|
261
|
+
it "should get Group instances binded to the group and grouper roles and the admin user" do
|
262
|
+
subject.except_multiple_as([:group, :grouper], admin).should =~ [ ]
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "with a model not having ID column" do
|
269
|
+
subject { Team }
|
270
|
+
|
271
|
+
it "should find Team instance not using team_code column" do
|
272
|
+
subject.except_multiple_as(:captain, captain).should =~ [ Team.last ]
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "with a resource using STI" do
|
277
|
+
subject { Organization }
|
278
|
+
it "should exclude instances of children classes with matching" do
|
279
|
+
subject.except_as(:owner, admin).should_not =~ [ Company.first ]
|
156
280
|
end
|
157
281
|
end
|
158
282
|
end
|
@@ -404,6 +528,7 @@ describe Rolify::Resource do
|
|
404
528
|
end
|
405
529
|
end
|
406
530
|
|
531
|
+
|
407
532
|
describe '.resource_types' do
|
408
533
|
|
409
534
|
it 'include all models that call resourcify' do
|
@@ -411,4 +536,36 @@ describe Rolify::Resource do
|
|
411
536
|
"Team", "Organization")
|
412
537
|
end
|
413
538
|
end
|
539
|
+
|
540
|
+
|
541
|
+
describe "#strict" do
|
542
|
+
context "strict user" do
|
543
|
+
before(:all) do
|
544
|
+
@strict_user = StrictUser.first
|
545
|
+
@strict_user.add_role(:forum, Forum.first)
|
546
|
+
@strict_user.add_role(:forum, Forum)
|
547
|
+
end
|
548
|
+
|
549
|
+
it "should return only strict forum" do
|
550
|
+
@strict_user.has_role?(:forum, Forum.first).should be true
|
551
|
+
end
|
552
|
+
|
553
|
+
it "should return false on strict another forum" do
|
554
|
+
@strict_user.has_role?(:forum, Forum.last).should be false
|
555
|
+
end
|
556
|
+
|
557
|
+
it "should return true if user has role on Forum model" do
|
558
|
+
@strict_user.has_role?(:forum, Forum).should be true
|
559
|
+
end
|
560
|
+
|
561
|
+
it "should return true if user has role any forum name" do
|
562
|
+
@strict_user.has_role?(:forum, :any).should be true
|
563
|
+
end
|
564
|
+
|
565
|
+
it "should return false when deleted role on Forum model" do
|
566
|
+
@strict_user.remove_role(:forum, Forum)
|
567
|
+
@strict_user.has_role?(:forum, Forum).should be false
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
414
571
|
end
|
@@ -49,6 +49,56 @@ shared_examples_for :finders do |param_name, param_method|
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
describe ".without_role" do
|
53
|
+
it { should respond_to(:without_role).with(1).argument }
|
54
|
+
it { should respond_to(:without_role).with(2).arguments }
|
55
|
+
|
56
|
+
context "with a global role" do
|
57
|
+
it { subject.without_role("admin".send(param_method)).should_not eq([ root ]) }
|
58
|
+
it { subject.without_role("moderator".send(param_method)).should_not be_empty }
|
59
|
+
it { subject.without_role("visitor".send(param_method)).should_not be_empty }
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with a class scoped role" do
|
63
|
+
context "on Forum class" do
|
64
|
+
it { subject.without_role("admin".send(param_method), Forum).should_not eq([ root ]) }
|
65
|
+
it { subject.without_role("moderator".send(param_method), Forum).should_not eq([ modo ]) }
|
66
|
+
it { subject.without_role("visitor".send(param_method), Forum).should_not be_empty }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "on Group class" do
|
70
|
+
it { subject.without_role("admin".send(param_method), Group).should_not eq([ root ]) }
|
71
|
+
it { subject.without_role("moderator".send(param_method), Group).should_not eq([ root ]) }
|
72
|
+
it { subject.without_role("visitor".send(param_method), Group).should_not be_empty }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with an instance scoped role" do
|
77
|
+
context "on Forum.first instance" do
|
78
|
+
it { subject.without_role("admin".send(param_method), Forum.first).should_not eq([ root ]) }
|
79
|
+
it { subject.without_role("moderator".send(param_method), Forum.first).should_not eq([ modo ]) }
|
80
|
+
it { subject.without_role("visitor".send(param_method), Forum.first).should_not be_empty }
|
81
|
+
end
|
82
|
+
|
83
|
+
context "on Forum.last instance" do
|
84
|
+
it { subject.without_role("admin".send(param_method), Forum.last).should_not eq([ root ]) }
|
85
|
+
it { subject.without_role("moderator".send(param_method), Forum.last).should_not eq([ modo ]) }
|
86
|
+
it { subject.without_role("visitor".send(param_method), Forum.last).should_not include(root, visitor) } # =~ doesn't pass using mongoid, don't know why...
|
87
|
+
end
|
88
|
+
|
89
|
+
context "on Group.first instance" do
|
90
|
+
it { subject.without_role("admin".send(param_method), Group.first).should_not eq([ root ]) }
|
91
|
+
it { subject.without_role("moderator".send(param_method), Group.first).should_not eq([ root ]) }
|
92
|
+
it { subject.without_role("visitor".send(param_method), Group.first).should_not eq([ modo ]) }
|
93
|
+
end
|
94
|
+
|
95
|
+
context "on Company.first_instance" do
|
96
|
+
it { subject.without_role("owner".send(param_method), Company.first).should_not eq([ owner ]) }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
52
102
|
describe ".with_all_roles" do
|
53
103
|
it { should respond_to(:with_all_roles) }
|
54
104
|
|
@@ -79,6 +79,11 @@ shared_examples_for "#has_role?_examples" do |param_name, param_method|
|
|
79
79
|
context "on instance scoped role request" do
|
80
80
|
it { subject.has_role?("moderator".send(param_method), Forum.first).should be_truthy }
|
81
81
|
it { subject.has_role?("moderator".send(param_method), :any).should be_truthy }
|
82
|
+
it {
|
83
|
+
m = subject.class.new
|
84
|
+
m.add_role("moderator", Forum.first)
|
85
|
+
m.has_role?("moderator".send(param_method), :any).should be_truthy
|
86
|
+
}
|
82
87
|
end
|
83
88
|
|
84
89
|
it "should not get an instance scoped role when asking for a global" do
|
@@ -132,4 +137,4 @@ shared_examples_for "#has_role?_examples" do |param_name, param_method|
|
|
132
137
|
end
|
133
138
|
end
|
134
139
|
end
|
135
|
-
end
|
140
|
+
end
|
@@ -7,6 +7,7 @@ require "rolify/shared_examples/shared_examples_for_has_any_role"
|
|
7
7
|
require "rolify/shared_examples/shared_examples_for_remove_role"
|
8
8
|
require "rolify/shared_examples/shared_examples_for_finders"
|
9
9
|
|
10
|
+
|
10
11
|
shared_examples_for Rolify::Role do
|
11
12
|
before(:all) do
|
12
13
|
reset_defaults
|
@@ -13,11 +13,18 @@ end
|
|
13
13
|
|
14
14
|
class Role < ActiveRecord::Base
|
15
15
|
has_and_belongs_to_many :users, :join_table => :users_roles
|
16
|
+
has_and_belongs_to_many :strict_users, :join_table => :strict_users_roles
|
17
|
+
|
16
18
|
belongs_to :resource, :polymorphic => true
|
17
19
|
|
18
20
|
extend Rolify::Adapter::Scopes
|
19
21
|
end
|
20
22
|
|
23
|
+
# Strict user and role classes
|
24
|
+
class StrictUser < ActiveRecord::Base
|
25
|
+
rolify strict: true
|
26
|
+
end
|
27
|
+
|
21
28
|
# Resourcifed and rolifed at the same time
|
22
29
|
class HumanResource < ActiveRecord::Base
|
23
30
|
resourcify :resources
|
@@ -18,9 +18,18 @@ class User
|
|
18
18
|
field :login, :type => String
|
19
19
|
end
|
20
20
|
|
21
|
+
# Standard user and role classes
|
22
|
+
class StrictUser
|
23
|
+
include Mongoid::Document
|
24
|
+
rolify strict: true
|
25
|
+
|
26
|
+
field :login, :type => String
|
27
|
+
end
|
28
|
+
|
21
29
|
class Role
|
22
30
|
include Mongoid::Document
|
23
31
|
has_and_belongs_to_many :users
|
32
|
+
has_and_belongs_to_many :strict_users
|
24
33
|
belongs_to :resource, :polymorphic => true
|
25
34
|
|
26
35
|
field :name, :type => String
|
@@ -148,4 +157,4 @@ end
|
|
148
157
|
|
149
158
|
class Company < Organization
|
150
159
|
|
151
|
-
end
|
160
|
+
end
|
data/spec/support/data.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Users
|
2
|
-
[ User, Customer, Admin::Moderator ].each do |user|
|
2
|
+
[ User, Customer, Admin::Moderator, StrictUser ].each do |user|
|
3
3
|
user.destroy_all
|
4
|
-
|
4
|
+
|
5
5
|
user.create(:login => "admin")
|
6
6
|
user.create(:login => "moderator")
|
7
7
|
user.create(:login => "god")
|
@@ -25,4 +25,4 @@ Team.create(:team_code => "1", :name => "PSG")
|
|
25
25
|
Team.create(:team_code => "2", :name => "MU")
|
26
26
|
|
27
27
|
Organization.create
|
28
|
-
Company.create
|
28
|
+
Company.create
|
data/spec/support/schema.rb
CHANGED
@@ -10,7 +10,7 @@ ActiveRecord::Schema.define do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
[ :users, :human_resources, :customers, :admin_moderators ].each do |table|
|
13
|
+
[ :users, :human_resources, :customers, :admin_moderators, :strict_users ].each do |table|
|
14
14
|
create_table(table) do |t|
|
15
15
|
t.string :login
|
16
16
|
end
|
@@ -21,6 +21,11 @@ ActiveRecord::Schema.define do
|
|
21
21
|
t.references :role
|
22
22
|
end
|
23
23
|
|
24
|
+
create_table(:strict_users_roles, :id => false) do |t|
|
25
|
+
t.references :strict_user
|
26
|
+
t.references :role
|
27
|
+
end
|
28
|
+
|
24
29
|
create_table(:human_resources_roles, :id => false) do |t|
|
25
30
|
t.references :human_resource
|
26
31
|
t.references :role
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rolify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florent Monbillard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ammeter
|
@@ -84,7 +84,6 @@ files:
|
|
84
84
|
- README.md
|
85
85
|
- Rakefile
|
86
86
|
- UPGRADE.rdoc
|
87
|
-
- circle.yml
|
88
87
|
- gemfiles/Gemfile.rails-3.2
|
89
88
|
- gemfiles/Gemfile.rails-4.0
|
90
89
|
- gemfiles/Gemfile.rails-4.1
|
@@ -122,6 +121,9 @@ files:
|
|
122
121
|
- spec/generators/rolify/rolify_mongoid_generator_spec.rb
|
123
122
|
- spec/generators_helper.rb
|
124
123
|
- spec/rolify/config_spec.rb
|
124
|
+
- spec/rolify/coverage/.last_run.json
|
125
|
+
- spec/rolify/coverage/.resultset.json
|
126
|
+
- spec/rolify/coverage/.resultset.json.lock
|
125
127
|
- spec/rolify/custom_spec.rb
|
126
128
|
- spec/rolify/matchers_spec.rb
|
127
129
|
- spec/rolify/namespace_spec.rb
|
@@ -167,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
169
|
version: '0'
|
168
170
|
requirements: []
|
169
171
|
rubyforge_project: rolify
|
170
|
-
rubygems_version: 2.
|
172
|
+
rubygems_version: 2.4.5
|
171
173
|
signing_key:
|
172
174
|
specification_version: 4
|
173
175
|
summary: Roles library with resource scoping
|
@@ -177,6 +179,9 @@ test_files:
|
|
177
179
|
- spec/generators/rolify/rolify_mongoid_generator_spec.rb
|
178
180
|
- spec/generators_helper.rb
|
179
181
|
- spec/rolify/config_spec.rb
|
182
|
+
- spec/rolify/coverage/.last_run.json
|
183
|
+
- spec/rolify/coverage/.resultset.json
|
184
|
+
- spec/rolify/coverage/.resultset.json.lock
|
180
185
|
- spec/rolify/custom_spec.rb
|
181
186
|
- spec/rolify/matchers_spec.rb
|
182
187
|
- spec/rolify/namespace_spec.rb
|
data/circle.yml
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
machine:
|
2
|
-
ruby:
|
3
|
-
version: 2.1.3
|
4
|
-
environment:
|
5
|
-
CODECLIMATE_REPO_TOKEN: 6bd8d374b120a5449b9a4b7dfda40cc0609dbade48a1b6655f04a9bc8de3a3ee
|
6
|
-
ADAPTER: active_record
|
7
|
-
ADAPTER: mongoid
|
8
|
-
dependencies:
|
9
|
-
pre:
|
10
|
-
- gem install bundler
|
11
|
-
test:
|
12
|
-
override:
|
13
|
-
- bundle exec rake:spec_all
|