scoped_rolify 0.0.4 → 0.0.5
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/.ruby-version +1 -1
- data/CHANGELOG.md +14 -0
- data/README.md +65 -0
- data/lib/scoped_rolify/finders.rb +15 -7
- data/lib/scoped_rolify/policy.rb +1 -1
- data/lib/scoped_rolify/role.rb +37 -3
- data/lib/scoped_rolify/version.rb +1 -1
- data/spec/scoped_rolify/finders_spec.rb +29 -9
- data/spec/scoped_rolify/role_spec.rb +35 -1
- data/spec/spec_helper.rb +8 -3
- data/spec/support/adapters/active_record.rb +11 -2
- data/spec/support/data.rb +3 -7
- data/spec/support/schema.rb +5 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ccae7235a31e93ee0b08d01aa8f6e8b15289389
|
4
|
+
data.tar.gz: 2e9e9177bf449409e77178e480fc7f6a3808d222
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddb035951cee915f2c3dc380818885b82c1d34fab18746ae375e37a9a20bbfb1f086fd97f092df2e2696cfcd249526af0fd1d4dc1b132ef14bee05200c09888f
|
7
|
+
data.tar.gz: 158e81b64ab7521155e2a751b5028053e531b327837ee7d12b4273a92dc66647b2737c4db330a0695532e4b10a02a3e8a55c75fe450ecd4eefa5dfae2ebc9437
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0-
|
1
|
+
ruby-2.0.0-p451
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -61,6 +61,71 @@ You can't play with none persisted object
|
|
61
61
|
|
62
62
|
Method ```with_any_scoped_role``` return an ```ActiveRecord::Relation``` of all users with all roles asked for one resource
|
63
63
|
|
64
|
+
## Root Resource
|
65
|
+
|
66
|
+
In some case you can add right on child resource instead of parent resource, the problem is you haven't access directly to objects throught Parent resource, for exemple
|
67
|
+
|
68
|
+
You grant user on specifc Forum, user.add_role(:moderator, Forum.first) the Forum have one Category, if you want get all moderators of this Category you can't. This modification make this possible.
|
69
|
+
|
70
|
+
moderator_john = User.new
|
71
|
+
moderator_jane = User.new
|
72
|
+
|
73
|
+
geek_world = Category.new
|
74
|
+
|
75
|
+
geek_forum = Forum.new
|
76
|
+
nerd_forum = Forum.new
|
77
|
+
|
78
|
+
class Forum < ActiveRecord::Base
|
79
|
+
belongs_to :category
|
80
|
+
|
81
|
+
def root_resource
|
82
|
+
:category
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Category < ActiveRecord::Base
|
87
|
+
has_many :forums
|
88
|
+
end
|
89
|
+
|
90
|
+
geek_world.forums << geek_forum
|
91
|
+
geek_world.forums << nerd_forum
|
92
|
+
|
93
|
+
moderator_john.add_role(:moderator, nerd_forum)
|
94
|
+
moderator_jane.add_role(:moderator, geek_forum)
|
95
|
+
|
96
|
+
For grab all moderators of this Category
|
97
|
+
|
98
|
+
User.with_scoped_role :moderator, geek_world, root=true
|
99
|
+
|
100
|
+
## Roadmap
|
101
|
+
|
102
|
+
Refactoring on root resource API
|
103
|
+
|
104
|
+
Change
|
105
|
+
|
106
|
+
User.with_scoped_role :moderator, geek_world, root=true
|
107
|
+
|
108
|
+
to
|
109
|
+
|
110
|
+
User.with_scoped_role :moderator, geek_world, scope: :forum
|
111
|
+
|
112
|
+
And change
|
113
|
+
|
114
|
+
class Forum < ActiveRecord::Base
|
115
|
+
belongs_to :category
|
116
|
+
|
117
|
+
def root_resource
|
118
|
+
:category
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
to
|
123
|
+
|
124
|
+
class Forum < ActiveRecord::Base
|
125
|
+
belongs_to :category
|
126
|
+
scoped_roles belongs_to: :category
|
127
|
+
end
|
128
|
+
|
64
129
|
## Contributing
|
65
130
|
|
66
131
|
1. Fork it ( http://github.com/<my-github-username>/scoped_rolify/fork )
|
@@ -1,26 +1,34 @@
|
|
1
1
|
module Rolify
|
2
2
|
module Finders
|
3
3
|
|
4
|
-
def with_scoped_role role_name, resource
|
4
|
+
def with_scoped_role role_name, resource, root_only=false
|
5
5
|
ScopedRolify::Policy.new(self, resource).check_persisted!
|
6
|
-
self.joins(:roles).where(rolify_constraints(role_name, resource))
|
6
|
+
self.joins(:roles).where(rolify_constraints(role_name, resource, root_only))
|
7
7
|
end
|
8
8
|
|
9
|
-
def with_any_scoped_role role_names, resource
|
9
|
+
def with_any_scoped_role role_names, resource, root_only=false
|
10
10
|
ScopedRolify::Policy.new(self, resource).check_persisted!
|
11
|
-
self.joins(:roles).where(rolify_constraints(role_names, resource))
|
11
|
+
self.joins(:roles).where(rolify_constraints(role_names, resource, root_only))
|
12
12
|
end
|
13
13
|
|
14
|
-
def rolify_constraints role_names, resource
|
14
|
+
def rolify_constraints role_names, resource, root_only=false
|
15
15
|
raise 'You should give somes role' if role_names.nil? or (role_names||[]).empty?
|
16
|
+
|
16
17
|
ScopedRolify::Policy.new(self, resource).check_persisted!
|
18
|
+
|
17
19
|
table = Arel::Table.new(:roles)
|
20
|
+
|
18
21
|
[].tap do |_constraints|
|
19
22
|
Array.wrap(role_names).each do |name|
|
20
23
|
_constraints << [].tap do |_constraint|
|
21
24
|
_constraint << table[:name].eq(name)
|
22
|
-
|
23
|
-
|
25
|
+
if root_only
|
26
|
+
_constraint << table[:root_resource_type].eq(resource.class.name)
|
27
|
+
_constraint << table[:root_resource_id].eq(resource.id)
|
28
|
+
else
|
29
|
+
_constraint << table[:resource_type].eq(resource.class.name)
|
30
|
+
_constraint << table[:resource_id].eq(resource.id)
|
31
|
+
end
|
24
32
|
end.reduce(:and)
|
25
33
|
end
|
26
34
|
end.reduce(:or)
|
data/lib/scoped_rolify/policy.rb
CHANGED
@@ -8,7 +8,7 @@ module ScopedRolify
|
|
8
8
|
|
9
9
|
def check_persisted!
|
10
10
|
check!
|
11
|
-
raise
|
11
|
+
raise PersistenceError, "You should ask on persisted resource" unless self.resource.persisted?
|
12
12
|
end
|
13
13
|
|
14
14
|
end
|
data/lib/scoped_rolify/role.rb
CHANGED
@@ -12,25 +12,59 @@ module Rolify
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def has_role?(role_name, resource = nil)
|
15
|
+
root_resource = resource.respond_to?(:root_resource) ? resource.send(resource.root_resource) : nil
|
15
16
|
if self.new_record?
|
16
|
-
self.roles.detect { |r| r.name.to_s == role_name.to_s && (r.resource == resource || resource.nil?) }
|
17
|
+
self.roles.detect { |r| r.name.to_s == role_name.to_s && (r.resource == resource || resource.nil?) && (r.root_resource == root_resource || root_resource.nil?) }
|
17
18
|
else
|
18
|
-
self.class.adapter.where(self.roles, :
|
19
|
+
self.class.adapter.where(self.roles, name: role_name, resource: resource, root_resource: root_resource)
|
19
20
|
end.present?
|
20
21
|
end
|
21
22
|
|
22
23
|
private
|
23
24
|
|
24
25
|
def add_resourced_role(role_name, resource)
|
26
|
+
root_resource = resource.respond_to?(:root_resource) ? resource.send(resource.root_resource) : nil
|
25
27
|
if self.new_record?
|
26
|
-
self.class.adapter.role_class.new(name: role_name, resource: resource).tap do |role|
|
28
|
+
role = self.class.adapter.role_class.new(name: role_name, resource: resource, root_resource: root_resource).tap do |role|
|
27
29
|
self.roles << role
|
28
30
|
if Rolify.dynamic_shortcuts and !self.respond_to?("is_#{role_name}?".to_sym)
|
29
31
|
self.class.define_dynamic_method(role_name, resource)
|
30
32
|
end
|
31
33
|
end
|
32
34
|
else
|
35
|
+
role = add_role_with_root(role_name, resource, root_resource)
|
36
|
+
end
|
37
|
+
add_role_to_resource(role)
|
38
|
+
load_dynamic_shortcuts(role_name, resource)
|
39
|
+
role
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_dynamic_shortcuts(role_name, resource)
|
43
|
+
if Rolify.dynamic_shortcuts and !self.respond_to?("is_#{role_name}?".to_sym)
|
44
|
+
self.class.define_dynamic_method(role_name, resource)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_role_to_resource(role)
|
49
|
+
self.roles << role unless self.roles.include?(role)
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_role_with_root(role_name, resource, root_resource)
|
53
|
+
unless root_resource
|
33
54
|
add_role(role_name, resource)
|
55
|
+
else
|
56
|
+
conditions = {
|
57
|
+
name: role_name.to_s,
|
58
|
+
resource_type: resource.class.name,
|
59
|
+
resource_id: resource.id,
|
60
|
+
}
|
61
|
+
if root_resource
|
62
|
+
conditions.merge!({ root_resource_type: (root_resource.is_a?(Class) ? root_resource.to_s : root_resource.class.name) })
|
63
|
+
unless root_resource.is_a?(Class) # Useless for the moment (Already false)
|
64
|
+
conditions.merge!({ root_resource_id: root_resource.id })
|
65
|
+
end
|
66
|
+
end
|
67
|
+
self.class.adapter.role_class.where(conditions).first_or_create
|
34
68
|
end
|
35
69
|
end
|
36
70
|
|
@@ -1,28 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Rolify::Finders do
|
4
|
-
let(:resource) { Forum.first }
|
4
|
+
let(:resource) { Forum.where(name: 'forum 1').first }
|
5
5
|
let(:admin) { User.where(login: 'admin').first }
|
6
6
|
|
7
7
|
before { admin.add_role(:admin, resource) }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
it { expect { subject.with_scoped_role(:admin, Forum) }.to raise_error InstanceResourceError }
|
12
|
-
it { expect { subject.with_scoped_role(:admin, resource) }.to_not raise_error }
|
9
|
+
it { expect { User.with_scoped_role(:admin, Forum) }.to raise_error InstanceResourceError }
|
10
|
+
it { expect { User.with_scoped_role(:admin, resource) }.to_not raise_error }
|
13
11
|
|
14
12
|
context 'regular way' do
|
15
|
-
it {
|
13
|
+
it { User.with_scoped_role(:admin, resource).should eq([admin]) }
|
16
14
|
end
|
17
15
|
|
18
16
|
context '#with_any_scoped_role' do
|
19
|
-
let(:moderator) {
|
17
|
+
let(:moderator) { User.where(login: 'moderator').first }
|
20
18
|
before { moderator.add_role(:moderator, resource) }
|
21
19
|
it do
|
22
|
-
expect(
|
20
|
+
expect(User.with_any_scoped_role([:admin, :moderator], resource)).to be_a(ActiveRecord::Relation)
|
23
21
|
end
|
24
22
|
it do
|
25
|
-
expect(
|
23
|
+
expect(User.with_any_scoped_role([:admin, :moderator], resource).to_a).to eq([admin, moderator])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with root resource' do
|
28
|
+
let(:root_resource) { Category.where(name: 'category 1').first }
|
29
|
+
let(:another_resource) { Forum.where(name: 'forum 2').first }
|
30
|
+
let(:super_admin) { User.where(login: 'super admin').first }
|
31
|
+
let(:moderator) { User.where(login: 'moderator').first }
|
32
|
+
|
33
|
+
before do
|
34
|
+
root_resource.forums << resource
|
35
|
+
root_resource.forums << another_resource
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'add role to user' do
|
39
|
+
before do
|
40
|
+
super_admin.add_scope_role(:super_admin, resource)
|
41
|
+
moderator.add_scope_role(:super_admin, another_resource)
|
42
|
+
end
|
43
|
+
|
44
|
+
it('should retreive super_admin') { expect(User.with_scoped_role(:super_admin, resource).to_a).to eq([super_admin]) }
|
45
|
+
it('should retreive all user for Category') { expect(User.with_scoped_role(:super_admin, root_resource, true).to_a).to eq([super_admin, moderator]) }
|
26
46
|
end
|
27
47
|
end
|
28
48
|
end
|
@@ -17,6 +17,7 @@ describe Rolify::Role do
|
|
17
17
|
|
18
18
|
it { expect { subject.add_scope_role(:admin, resource) }.to_not raise_error }
|
19
19
|
it { should have_role :admin, resource }
|
20
|
+
it { expect(User.with_scoped_role(:admin, resource).to_a).to eq([user]) }
|
20
21
|
end
|
21
22
|
|
22
23
|
context 'new record way' do
|
@@ -33,5 +34,38 @@ describe Rolify::Role do
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
|
37
|
+
context 'with root resource' do
|
38
|
+
context 'persisted way' do
|
39
|
+
let(:root_resource) { Category.first }
|
37
40
|
|
41
|
+
before { root_resource.forums << resource }
|
42
|
+
|
43
|
+
context 'add role to user' do
|
44
|
+
before { subject.add_scope_role(:admin, resource) }
|
45
|
+
it('should retreive user') do
|
46
|
+
expect(
|
47
|
+
User.joins(:roles).where(
|
48
|
+
Role.where(name: :admin, resource_type: 'Forum', resource_id: resource.id,
|
49
|
+
root_resource_type: 'Category', root_resource_id: root_resource.id).arel.constraints.first
|
50
|
+
).to_a
|
51
|
+
).to eq([subject])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'unpersisted way' do
|
57
|
+
let(:root_resource) { Category.new(name: 'UnCategoized') }
|
58
|
+
let(:resource) { Forum.new(name: 'forum 42') }
|
59
|
+
let(:user) { User.new(login: 'John Doe') }
|
60
|
+
|
61
|
+
before { root_resource.forums << resource }
|
62
|
+
|
63
|
+
it { expect(root_resource.forums).to eq([resource]) }
|
64
|
+
|
65
|
+
context 'add role to user' do
|
66
|
+
before { user.add_scope_role(:admin, resource) }
|
67
|
+
it { should have_role :admin, resource }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,9 +10,14 @@ Coveralls.wear!
|
|
10
10
|
ENV['ADAPTER'] ||= 'active_record'
|
11
11
|
|
12
12
|
load File.dirname(__FILE__) + "/support/adapters/#{ENV['ADAPTER']}.rb"
|
13
|
-
load File.dirname(__FILE__) + '/support/data.rb'
|
14
13
|
|
15
|
-
RSpec.configure do |
|
16
|
-
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.filter_run focused: true
|
16
|
+
config.run_all_when_everything_filtered = true
|
17
|
+
|
18
|
+
config.before(:each) do
|
19
|
+
[ User, Role, Forum, Category].each &:destroy_all
|
20
|
+
load File.dirname(__FILE__) + '/support/data.rb'
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
@@ -13,11 +13,20 @@ end
|
|
13
13
|
class Role < ActiveRecord::Base
|
14
14
|
has_and_belongs_to_many :users, join_table: :users_roles
|
15
15
|
belongs_to :resource, polymorphic: true
|
16
|
+
belongs_to :root_resource, polymorphic: true
|
16
17
|
|
17
18
|
extend Rolify::Adapter::Scopes
|
18
19
|
end
|
19
20
|
|
20
|
-
# Resources classes
|
21
21
|
class Forum < ActiveRecord::Base
|
22
|
-
|
22
|
+
belongs_to :category
|
23
|
+
|
24
|
+
def root_resource
|
25
|
+
:category
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Resources classes
|
30
|
+
class Category < ActiveRecord::Base
|
31
|
+
has_many :forums
|
23
32
|
end
|
data/spec/support/data.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
# Users
|
2
|
-
User.destroy_all
|
3
1
|
User.create login: 'admin'
|
2
|
+
User.create login: 'super admin'
|
4
3
|
User.create login: 'moderator'
|
5
|
-
|
6
|
-
# Roles
|
7
|
-
Role.destroy_all
|
8
|
-
|
9
|
-
# Resources
|
10
4
|
Forum.create name: 'forum 1'
|
5
|
+
Forum.create name: 'forum 2'
|
6
|
+
Category.create name: 'category 1'
|
data/spec/support/schema.rb
CHANGED
@@ -8,6 +8,7 @@ ActiveRecord::Schema.define do
|
|
8
8
|
create_table(:roles) do |t|
|
9
9
|
t.string :name
|
10
10
|
t.references :resource, polymorphic: true
|
11
|
+
t.references :root_resource, polymorphic: true
|
11
12
|
t.timestamps
|
12
13
|
end
|
13
14
|
|
@@ -18,6 +19,10 @@ ActiveRecord::Schema.define do
|
|
18
19
|
|
19
20
|
create_table(:forums) do |t|
|
20
21
|
t.string :name
|
22
|
+
t.integer :category_id
|
21
23
|
end
|
22
24
|
|
25
|
+
create_table(:categories) do |t|
|
26
|
+
t.string :name
|
27
|
+
end
|
23
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scoped_rolify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel AZEMAR
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rolify
|
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
133
|
version: '0'
|
134
134
|
requirements: []
|
135
135
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.
|
136
|
+
rubygems_version: 2.2.2
|
137
137
|
signing_key:
|
138
138
|
specification_version: 4
|
139
139
|
summary: This is a monkey patch of rolify
|