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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b9f204d757588d80887b2193a4eb9ea1b0fd471
4
- data.tar.gz: 97030122590f294b06b595af6edc1dec44d13176
3
+ metadata.gz: edae47a21706d1859520df05876acf68d95c0d48
4
+ data.tar.gz: 09dbd84321d04321d1ef889db0911fa86f1ccbe4
5
5
  SHA512:
6
- metadata.gz: 75dc73295700924357b77c4359f43939c3e44d0857015f7f30dc26e4f06c99e1667f7767977e1a9bb332028ee177cab6ba860538a4d1dd640da5175246989a68
7
- data.tar.gz: 01e0a0874a8ded544155535b4b9cff68f643b20fce6e71e21615ef7c4a5f7ca47b68e4b6ea9de34ec13af5e51bce6fb781f52351483ede4e05e152f21a662c5e
6
+ metadata.gz: 910c97443cd78a0386a36f2d6645708c7f6eadf5b84815ca51f8b1cbd39f4a6e1236a16688c37ef99a48234deb44a25c684e7852ce146f7d0e75cc22817a841c
7
+ data.tar.gz: 4525bec755d35bb470d364088bdfe2c7f2a39b61cf140944363518ed5626de9f4c438c088d432002a7b41edc750dccc7a032b94f76d075d068f0770b762223cb
data/.gitignore CHANGED
@@ -8,3 +8,4 @@ coverage/*
8
8
  log*/*
9
9
  .rbx/*
10
10
  .rspec
11
+ *.swp
@@ -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
- In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
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.with_roles([:admin, :user], current_user)
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 CanCan](https://github.com/RolifyCommunity/rolify/wiki/Tutorial)
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
 
@@ -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.adapter = Rolify::Adapter::Base.create("resource_adapter", self.role_cname, self.name)
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
@@ -37,6 +37,11 @@ module Rolify
37
37
  end
38
38
  end
39
39
 
40
+ def all_except(resource, excluded_obj)
41
+ prime_key = resource.primary_key.to_sym
42
+ resource.where(prime_key => (resource.all - excluded_obj).map(&prime_key))
43
+ end
44
+
40
45
  private
41
46
 
42
47
  def quote(column)
@@ -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)
@@ -59,6 +59,7 @@ module Rolify
59
59
  def in(resources, roles)
60
60
  raise NotImplementedError.new("You must implement in")
61
61
  end
62
+
62
63
  end
63
64
  end
64
65
  end
@@ -39,6 +39,10 @@ module Rolify
39
39
  end
40
40
  end
41
41
 
42
+ def all_except(resource, excluded_obj)
43
+ resource.not_in(_id: excluded_obj.to_a)
44
+ end
45
+
42
46
  end
43
47
  end
44
48
  end
@@ -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)
@@ -52,13 +52,13 @@ module Rolify
52
52
  private
53
53
 
54
54
  def sanity_check(role_cnames)
55
- return true if "assets:precompile"==ARGV[0]
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 ? Ignoring rolify config."
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
@@ -1,8 +1,19 @@
1
+ require "rolify/configure"
2
+
1
3
  module Rolify
2
4
  module Dynamic
3
5
  def load_dynamic_methods
4
- self.role_class.all.each do |r|
5
- define_dynamic_method(r.name, r.resource)
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
@@ -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|
@@ -6,7 +6,7 @@ module Rolify
6
6
 
7
7
  module ClassMethods
8
8
  def find_roles(role_name = nil, user = nil)
9
- self.adapter.find_roles(role_name, self, user)
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.adapter.resources_find(self.role_table_name, self, role_name) #.map(&:id)
20
- user ? self.adapter.in(resources, user, role_name) : resources
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.adapter.applied_roles(self, children)
37
+ self.resource_adapter.applied_roles(self, children)
26
38
  end
39
+
40
+
41
+
27
42
  end
28
43
 
29
44
  def applied_roles
@@ -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| r.name.to_s == role_name.to_s && (r.resource == resource || resource.nil?) }
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
@@ -1,3 +1,3 @@
1
1
  module Rolify
2
- VERSION = "4.0.0"
2
+ VERSION = "4.1.0"
3
3
  end
@@ -57,7 +57,7 @@ describe Rolify do
57
57
 
58
58
  subject { Forum }
59
59
 
60
- its("adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
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("adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
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("adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
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("adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
187
+ its("resource_adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
188
188
  end
189
189
  end
190
190
  end
@@ -0,0 +1,5 @@
1
+ {
2
+ "result": {
3
+ "covered_percent": 100.0
4
+ }
5
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "RSpec": {
3
+ "coverage": {
4
+ },
5
+ "timestamp": 1427836082
6
+ }
7
+ }
@@ -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 ".with_roles" do
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.with_role(:forum).should =~ [ Forum.first, Forum.last ]
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.with_role(:godfather).should =~ Forum.all.to_a
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.with_role(:forum).first
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.with_role(:group).should =~ [ Group.last ]
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.with_role(:group).should =~ [ ]
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.with_roles([:group, :grouper]).should =~ [ Group.first, Group.last ]
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.with_role(:forum, admin).should =~ [ Forum.first ]
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.with_role(:forum, tourist).should =~ [ Forum.last ]
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.with_role(:godfather, admin).should =~ Forum.all.to_a
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.with_role(:godfather, tourist).should be_empty
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.with_role(:group, tourist).should =~ [ Forum.first ]
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.with_role(:group, tourist).should_not include(Forum.last)
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.with_role(:group, admin).should =~ [ Group.last ]
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.with_role(:group, admin).should_not include(Group.first)
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.with_roles([:forum, :group], tourist).should =~ [ Forum.first, Forum.last ]
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.with_roles([:group, :grouper], admin).should =~ [ Group.first, Group.last ]
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.with_roles([:captain, :player], captain).should =~ [ Team.first, Team.last ]
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.with_roles(:owner, admin).should =~ [ Company.first ]
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
@@ -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
@@ -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.0.0
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-02-12 00:00:00.000000000 Z
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.2.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