rolify 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Gem Version](https://badge.fury.io/rb/rolify.svg)](http://badge.fury.io/rb/rolify) [![build status](https://secure.travis-ci.org/RolifyCommunity/rolify.png)](http://travis-ci.org/RolifyCommunity/rolify) [![Dependency Status](https://gemnasium.com/RolifyCommunity/rolify.svg)](https://gemnasium.com/RolifyCommunity/rolify) [![Code Climate](https://codeclimate.com/github/RolifyCommunity/rolify.png)](https://codeclimate.com/github/RolifyCommunity/rolify) [![Coverage Status](https://img.shields.io/coveralls/RolifyCommunity/rolify.svg)](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
|