g5_authenticatable 0.7.5 → 0.8.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/g5_authenticatable/user.rb +8 -0
- data/app/policies/g5_authenticatable/base_policy.rb +5 -1
- data/app/policies/g5_updatable/client_policy.rb +10 -9
- data/app/policies/g5_updatable/location_policy.rb +40 -0
- data/app/policies/g5_updatable/selectable_client_policy.rb +38 -0
- data/lib/g5_authenticatable/version.rb +1 -1
- data/spec/dummy/config/application.rb +2 -0
- data/spec/policies/client_policy_spec.rb +34 -32
- data/spec/policies/location_policy_spec.rb +65 -0
- data/spec/policies/selectable_client_policy_spec.rb +82 -0
- metadata +10 -6
- data/spec/policies/post_policy_spec.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e740b6fbbb4a9876775c1e76db296562d6283bd6
|
4
|
+
data.tar.gz: 8c9d75eb84818206367591faeac2f675f2616769
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdd634b6c2ed9e3f7dfd75a0d11e4a9ea8deac800f88a154a8e76651650c75e776e0ccc9f7b13a39941ede01c44201987aea1450605bc3569e1739cf9d1696d7
|
7
|
+
data.tar.gz: f1a47879f8b0d9f5af31a53f5740b14bb016a1849ff65f30fbe08ee70466c1882fd2cb304c8d1debdfc40cafccc292dcac650be2d2207d01facbfb054cab1573
|
@@ -37,10 +37,18 @@ module G5Authenticatable
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
def selectable_clients
|
41
|
+
G5Updatable::SelectableClientPolicy::Scope.new(self, G5Updatable::Client).resolve
|
42
|
+
end
|
43
|
+
|
40
44
|
def clients
|
41
45
|
G5Updatable::ClientPolicy::Scope.new(self, G5Updatable::Client).resolve
|
42
46
|
end
|
43
47
|
|
48
|
+
def locations
|
49
|
+
G5Updatable::LocationPolicy::Scope.new(self, G5Updatable::Location).resolve
|
50
|
+
end
|
51
|
+
|
44
52
|
private
|
45
53
|
|
46
54
|
def self.extended_auth_attributes(auth_data)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class G5Authenticatable::BasePolicy
|
2
2
|
attr_reader :user, :record
|
3
3
|
|
4
|
-
def initialize(user, record)
|
4
|
+
def initialize(user, record=nil)
|
5
5
|
@user = user
|
6
6
|
@record = record
|
7
7
|
end
|
@@ -53,6 +53,10 @@ class G5Authenticatable::BasePolicy
|
|
53
53
|
scope.none
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
def has_global_role?
|
58
|
+
G5Authenticatable::BasePolicy.new(user, G5Updatable::Client).has_global_role?
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
def super_admin?
|
@@ -1,22 +1,23 @@
|
|
1
|
+
# Clients defined by this policy are ones for whom the user has access at the client level. This means that either
|
2
|
+
# they have a global role or that have a specific client role.
|
1
3
|
module G5Updatable
|
2
4
|
class ClientPolicy < G5Authenticatable::BasePolicy
|
3
5
|
class Scope < G5Authenticatable::BasePolicy::BaseScope
|
4
6
|
|
5
7
|
def resolve
|
6
8
|
return scope.all if has_global_role?
|
7
|
-
|
9
|
+
client_with_roles
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
G5Authenticatable::Role
|
12
|
-
.joins('INNER JOIN g5_updatable_clients ON g5_updatable_clients.id = g5_authenticatable_roles.resource_id')
|
13
|
-
.joins('INNER JOIN g5_authenticatable_users_roles ON g5_authenticatable_roles.id = g5_authenticatable_users_roles.role_id')
|
14
|
-
.where('g5_authenticatable_roles.resource_type = ? and g5_authenticatable_users_roles.user_id = ?', G5Updatable::Client.name, user.id)
|
15
|
-
end
|
12
|
+
private
|
16
13
|
|
17
|
-
def
|
18
|
-
|
14
|
+
def client_with_roles
|
15
|
+
G5Updatable::Client
|
16
|
+
.joins('INNER JOIN g5_authenticatable_roles as r ON r.resource_id = g5_updatable_clients.id')
|
17
|
+
.joins('INNER JOIN g5_authenticatable_users_roles as ur ON r.id = ur.role_id')
|
18
|
+
.where('r.resource_type = ? and ur.user_id = ?', G5Updatable::Client.name, user.id)
|
19
19
|
end
|
20
|
+
|
20
21
|
end
|
21
22
|
|
22
23
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# The policy will resolve to all locations that a user has access. This includes locations that a user has roles for
|
2
|
+
# but also those locations for which a user has a client role. Global roles grant access to ALL locations.
|
3
|
+
module G5Updatable
|
4
|
+
class LocationPolicy < G5Authenticatable::BasePolicy
|
5
|
+
class Scope < G5Authenticatable::BasePolicy::BaseScope
|
6
|
+
|
7
|
+
def resolve
|
8
|
+
locations_from_client_location_roles
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def location_roles
|
14
|
+
G5Authenticatable::Role
|
15
|
+
.joins('INNER JOIN g5_updatable_locations as l ON l.id = g5_authenticatable_roles.resource_id')
|
16
|
+
.joins('INNER JOIN g5_authenticatable_users_roles as ur ON g5_authenticatable_roles.id = ur.role_id')
|
17
|
+
.where('g5_authenticatable_roles.resource_type = ? and ur.user_id = ?',
|
18
|
+
G5Updatable::Location.name, user.id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def locations_from_client_roles
|
22
|
+
G5Updatable::Location
|
23
|
+
.joins('INNER JOIN g5_updatable_clients as c on g5_updatable_locations.client_uid=c.uid')
|
24
|
+
.joins('INNER JOIN g5_authenticatable_roles as r on r.resource_id=c.id')
|
25
|
+
.joins('INNER JOIN g5_authenticatable_users_roles as ur on r.id=ur.role_id')
|
26
|
+
.where('ur.user_id=?',user.id)
|
27
|
+
.where('r.resource_type=?', G5Updatable::Client.name)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def locations_from_client_location_roles
|
32
|
+
return scope.all if has_global_role?
|
33
|
+
location_ids = locations_from_client_roles.map(&:id) | location_roles.map(&:resource_id)
|
34
|
+
G5Updatable::Location.where(id: location_ids)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Policy to define which clients are show to users to select. This includes all clients for whom a user only
|
2
|
+
# has a location scoped role. Clients defined by this policy are not necessarily granted view permissions at the client
|
3
|
+
# level.
|
4
|
+
module G5Updatable
|
5
|
+
class SelectableClientPolicy < G5Authenticatable::BasePolicy
|
6
|
+
class Scope < G5Authenticatable::BasePolicy::BaseScope
|
7
|
+
|
8
|
+
def resolve
|
9
|
+
return clients_from_client_and_location_roles
|
10
|
+
end
|
11
|
+
|
12
|
+
def client_roles
|
13
|
+
G5Authenticatable::Role
|
14
|
+
.joins('INNER JOIN g5_updatable_clients as c ON c.id = g5_authenticatable_roles.resource_id')
|
15
|
+
.joins('INNER JOIN g5_authenticatable_users_roles as ur ON g5_authenticatable_roles.id = ur.role_id')
|
16
|
+
.where('g5_authenticatable_roles.resource_type = ? and ur.user_id = ?', G5Updatable::Client.name, user.id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def clients_from_client_and_location_roles
|
20
|
+
return scope.all if has_global_role?
|
21
|
+
client_ids = clients_from_location_roles.map(&:id) | client_roles.map(&:resource_id)
|
22
|
+
G5Updatable::Client.where(id: client_ids)
|
23
|
+
end
|
24
|
+
|
25
|
+
def clients_from_location_roles
|
26
|
+
G5Updatable::Client
|
27
|
+
.joins('INNER JOIN g5_updatable_locations as l on l.client_uid=g5_updatable_clients.uid')
|
28
|
+
.joins('INNER JOIN g5_authenticatable_roles as r on l.id=r.resource_id')
|
29
|
+
.joins('INNER JOIN g5_authenticatable_users_roles as ur on r.id=ur.role_id')
|
30
|
+
.where('r.resource_type = ? and ur.user_id = ?',
|
31
|
+
G5Updatable::Location.name, user.id)
|
32
|
+
.group('g5_updatable_clients.id')
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -16,44 +16,46 @@ describe G5Updatable::ClientPolicy do
|
|
16
16
|
let!(:client_2) { FactoryGirl.create(:g5_updatable_client) }
|
17
17
|
let!(:client_3) { FactoryGirl.create(:g5_updatable_client) }
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
19
|
+
describe '.resolve' do
|
20
|
+
|
21
|
+
subject { G5Updatable::ClientPolicy::Scope.new(user, G5Updatable::Client).resolve }
|
22
|
+
|
23
|
+
context 'with global role' do
|
24
|
+
before { user.add_role :admin }
|
25
|
+
it 'returns all clients' do
|
26
|
+
expect(subject.length).to eq(3)
|
27
|
+
expect(subject).to include(client_1)
|
28
|
+
expect(subject).to include(client_2)
|
29
|
+
expect(subject).to include(client_3)
|
30
|
+
end
|
28
31
|
end
|
29
|
-
end
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
context 'with client role' do
|
34
|
+
before { user.add_role(:admin, client_1) }
|
35
|
+
it 'returns a single client' do
|
36
|
+
expect(subject.length).to eq(1)
|
37
|
+
expect(subject).to include(client_1)
|
38
|
+
end
|
36
39
|
end
|
37
|
-
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
context 'with many client roles' do
|
42
|
+
before do
|
43
|
+
user.add_role(:admin, client_1)
|
44
|
+
user.add_role(:admin, client_2)
|
45
|
+
user.add_role(:admin, client_3)
|
46
|
+
end
|
47
|
+
it 'returns all assigned clients' do
|
48
|
+
expect(subject.length).to eq(3)
|
49
|
+
expect(subject).to include(client_1)
|
50
|
+
expect(subject).to include(client_2)
|
51
|
+
expect(subject).to include(client_3)
|
52
|
+
end
|
50
53
|
end
|
51
|
-
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
context 'with no role' do
|
56
|
+
it 'returns no clients' do
|
57
|
+
expect(subject.length).to eq(0)
|
58
|
+
end
|
56
59
|
end
|
57
60
|
end
|
58
|
-
|
59
61
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe G5Updatable::LocationPolicy do
|
4
|
+
subject(:policy) { described_class }
|
5
|
+
|
6
|
+
let(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
7
|
+
let(:user2) { FactoryGirl.create(:g5_authenticatable_user) }
|
8
|
+
|
9
|
+
let!(:client_1) { FactoryGirl.create(:g5_updatable_client) }
|
10
|
+
let!(:client_2) { FactoryGirl.create(:g5_updatable_client) }
|
11
|
+
|
12
|
+
let!(:location_1) { FactoryGirl.create(:g5_updatable_location, client: client_1) }
|
13
|
+
let!(:location_2) { FactoryGirl.create(:g5_updatable_location, client: client_1) }
|
14
|
+
|
15
|
+
let!(:location_3) { FactoryGirl.create(:g5_updatable_location, client: client_2) }
|
16
|
+
let!(:location_4) { FactoryGirl.create(:g5_updatable_location, client: client_2) }
|
17
|
+
|
18
|
+
before do
|
19
|
+
user.roles = []
|
20
|
+
user.save!
|
21
|
+
user2.add_role(:viewer, location_1)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.resolve' do
|
25
|
+
subject { G5Updatable::LocationPolicy::Scope.new(user, G5Updatable::Location).resolve }
|
26
|
+
|
27
|
+
context 'with global role' do
|
28
|
+
before { user.add_role :admin }
|
29
|
+
it 'returns all locations' do
|
30
|
+
expect(subject.length).to eq(4)
|
31
|
+
expect(subject).to include(location_1)
|
32
|
+
expect(subject).to include(location_2)
|
33
|
+
expect(subject).to include(location_3)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with location role' do
|
38
|
+
before { user.add_role(:admin, location_1) }
|
39
|
+
it 'returns a single location' do
|
40
|
+
expect(subject.length).to eq(1)
|
41
|
+
expect(subject).to include(location_1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with many client roles' do
|
46
|
+
before do
|
47
|
+
user.add_role(:admin, location_1)
|
48
|
+
user.add_role(:admin, location_2)
|
49
|
+
user.add_role(:admin, location_3)
|
50
|
+
end
|
51
|
+
it 'returns all assigned clients' do
|
52
|
+
expect(subject.length).to eq(3)
|
53
|
+
expect(subject).to include(location_1)
|
54
|
+
expect(subject).to include(location_2)
|
55
|
+
expect(subject).to include(location_3)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with no role' do
|
60
|
+
it 'returns no locations' do
|
61
|
+
expect(subject.length).to eq(0)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe G5Updatable::SelectableClientPolicy do
|
4
|
+
subject(:policy) { described_class }
|
5
|
+
|
6
|
+
let(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
7
|
+
let(:user2) { FactoryGirl.create(:g5_authenticatable_user) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
user.roles = []
|
11
|
+
user.save!
|
12
|
+
user2.add_role(:viewer, client_1)
|
13
|
+
end
|
14
|
+
|
15
|
+
let!(:client_1) { FactoryGirl.create(:g5_updatable_client) }
|
16
|
+
let!(:client_2) { FactoryGirl.create(:g5_updatable_client) }
|
17
|
+
let!(:client_3) { FactoryGirl.create(:g5_updatable_client) }
|
18
|
+
|
19
|
+
describe '.resolve' do
|
20
|
+
subject { G5Updatable::SelectableClientPolicy::Scope.new(user, G5Updatable::Client).resolve }
|
21
|
+
|
22
|
+
let!(:location_1) { FactoryGirl.create(:g5_updatable_location, client: client_1) }
|
23
|
+
let!(:location_2) { FactoryGirl.create(:g5_updatable_location, client: client_1) }
|
24
|
+
|
25
|
+
let!(:location_3) { FactoryGirl.create(:g5_updatable_location, client: client_2) }
|
26
|
+
let!(:location_4) { FactoryGirl.create(:g5_updatable_location, client: client_2) }
|
27
|
+
|
28
|
+
context 'with global role' do
|
29
|
+
before { user.add_role :admin }
|
30
|
+
it 'returns all clients' do
|
31
|
+
expect(subject.length).to eq(3)
|
32
|
+
expect(subject).to include(client_1)
|
33
|
+
expect(subject).to include(client_2)
|
34
|
+
expect(subject).to include(client_3)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with role for location and for client that location belongs to' do
|
39
|
+
before do
|
40
|
+
user.add_role :admin, location_1
|
41
|
+
user.add_role :admin, client_1
|
42
|
+
end
|
43
|
+
it 'returns 1 client' do
|
44
|
+
expect(subject.length).to eq(1)
|
45
|
+
expect(subject).to include(client_1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with role for location and client that location does not belong to' do
|
50
|
+
before do
|
51
|
+
user.add_role :admin, location_1
|
52
|
+
user.add_role :admin, client_2
|
53
|
+
end
|
54
|
+
it 'returns 1 client' do
|
55
|
+
expect(subject.length).to eq(2)
|
56
|
+
expect(subject).to include(client_1)
|
57
|
+
expect(subject).to include(client_2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with a client role' do
|
62
|
+
before do
|
63
|
+
user.add_role :admin, client_2
|
64
|
+
end
|
65
|
+
it 'returns 1 client' do
|
66
|
+
expect(subject.length).to eq(1)
|
67
|
+
expect(subject).to include(client_2)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with a location role' do
|
72
|
+
before do
|
73
|
+
user.add_role :admin, location_1
|
74
|
+
end
|
75
|
+
it 'returns 1 client' do
|
76
|
+
expect(subject.length).to eq(1)
|
77
|
+
expect(subject).to include(client_1)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: g5_authenticatable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maeve
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: devise_g5_authenticatable
|
@@ -126,6 +126,8 @@ files:
|
|
126
126
|
- app/models/g5_authenticatable/user.rb
|
127
127
|
- app/policies/g5_authenticatable/base_policy.rb
|
128
128
|
- app/policies/g5_updatable/client_policy.rb
|
129
|
+
- app/policies/g5_updatable/location_policy.rb
|
130
|
+
- app/policies/g5_updatable/selectable_client_policy.rb
|
129
131
|
- app/services/g5_authenticatable/impersonate_sessionable.rb
|
130
132
|
- app/views/g5_authenticatable/error/auth_error.html.erb
|
131
133
|
- app/views/layouts/g5_authenticatable/application.html.erb
|
@@ -236,7 +238,8 @@ files:
|
|
236
238
|
- spec/models/post_spec.rb
|
237
239
|
- spec/policies/application_policy_spec.rb
|
238
240
|
- spec/policies/client_policy_spec.rb
|
239
|
-
- spec/policies/
|
241
|
+
- spec/policies/location_policy_spec.rb
|
242
|
+
- spec/policies/selectable_client_policy_spec.rb
|
240
243
|
- spec/requests/default_role_authorization_spec.rb
|
241
244
|
- spec/requests/grape_api_spec.rb
|
242
245
|
- spec/requests/rails_api_spec.rb
|
@@ -266,9 +269,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
266
269
|
version: '0'
|
267
270
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
268
271
|
requirements:
|
269
|
-
- - "
|
272
|
+
- - ">"
|
270
273
|
- !ruby/object:Gem::Version
|
271
|
-
version:
|
274
|
+
version: 1.3.1
|
272
275
|
requirements: []
|
273
276
|
rubyforge_project:
|
274
277
|
rubygems_version: 2.2.2
|
@@ -357,7 +360,8 @@ test_files:
|
|
357
360
|
- spec/models/post_spec.rb
|
358
361
|
- spec/policies/application_policy_spec.rb
|
359
362
|
- spec/policies/client_policy_spec.rb
|
360
|
-
- spec/policies/
|
363
|
+
- spec/policies/location_policy_spec.rb
|
364
|
+
- spec/policies/selectable_client_policy_spec.rb
|
361
365
|
- spec/requests/default_role_authorization_spec.rb
|
362
366
|
- spec/requests/grape_api_spec.rb
|
363
367
|
- spec/requests/rails_api_spec.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe PostPolicy do
|
4
|
-
subject(:policy) { described_class }
|
5
|
-
|
6
|
-
let(:record) { FactoryGirl.create(:post) }
|
7
|
-
|
8
|
-
permissions :index? do
|
9
|
-
it_behaves_like 'a super_admin authorizer'
|
10
|
-
end
|
11
|
-
|
12
|
-
permissions :show? do
|
13
|
-
it_behaves_like 'a super_admin authorizer'
|
14
|
-
end
|
15
|
-
|
16
|
-
permissions :new? do
|
17
|
-
it_behaves_like 'a super_admin authorizer'
|
18
|
-
end
|
19
|
-
|
20
|
-
permissions :create? do
|
21
|
-
it_behaves_like 'a super_admin authorizer'
|
22
|
-
end
|
23
|
-
|
24
|
-
permissions :edit? do
|
25
|
-
it_behaves_like 'a super_admin authorizer'
|
26
|
-
end
|
27
|
-
|
28
|
-
permissions :update? do
|
29
|
-
it_behaves_like 'a super_admin authorizer'
|
30
|
-
end
|
31
|
-
|
32
|
-
permissions :destroy? do
|
33
|
-
it_behaves_like 'a super_admin authorizer'
|
34
|
-
end
|
35
|
-
end
|