mongoid_ability 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mongoid_ability/lock.rb +1 -1
- data/lib/mongoid_ability/owner.rb +6 -0
- data/lib/mongoid_ability/subject.rb +31 -3
- data/lib/mongoid_ability/version.rb +1 -1
- data/test/mongoid_ability/lock_test.rb +13 -7
- data/test/mongoid_ability/owner_test.rb +20 -0
- data/test/mongoid_ability/subject_test.rb +42 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b22befcca304fbace4cd22f72704b7d5a109a0b
|
4
|
+
data.tar.gz: 56a19a326bdb60d7d462558c51cd0d7196146d8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 740466111f499e95e981197abc5567740c7ecb829126a863bf6720cddadb5f4b9a75ad9fc851f93bfecb8e90e55ce73a40b20ee8d7741b893412270a7ac71c3b
|
7
|
+
data.tar.gz: 83f00db0cdb31b4f1ebd024c40f5b1390059a0b686119bcf7e27d97a081f4e5d7208286920cf929b55253e73450182201133c63c1dcf882bc10b4ca24e2ab35b
|
data/lib/mongoid_ability/lock.rb
CHANGED
@@ -45,7 +45,7 @@ module MongoidAbility
|
|
45
45
|
return calculated_outcome unless owner.present?
|
46
46
|
cloned_owner = owner.clone
|
47
47
|
cloned_owner.locks_relation = cloned_owner.locks_relation - [self]
|
48
|
-
MongoidAbility::Ability.new(cloned_owner).can? action, (
|
48
|
+
MongoidAbility::Ability.new(cloned_owner).can? action, (subject.present? ? subject : subject_class)
|
49
49
|
end
|
50
50
|
|
51
51
|
# ---------------------------------------------------------------------
|
@@ -38,6 +38,12 @@ module MongoidAbility
|
|
38
38
|
@ability ||= MongoidAbility::Ability.new(self)
|
39
39
|
end
|
40
40
|
|
41
|
+
# ---------------------------------------------------------------------
|
42
|
+
|
43
|
+
def has_lock? lock
|
44
|
+
locks_relation.where(action: lock.action, subject_type: lock.subject_type, subject_id: lock.subject_id.presence).exists?
|
45
|
+
end
|
46
|
+
|
41
47
|
private # =============================================================
|
42
48
|
|
43
49
|
def cleanup_locks
|
@@ -7,8 +7,6 @@ module MongoidAbility
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
# ---------------------------------------------------------------------
|
11
|
-
|
12
10
|
module ClassMethods
|
13
11
|
def default_locks
|
14
12
|
@default_locks ||= []
|
@@ -19,15 +17,25 @@ module MongoidAbility
|
|
19
17
|
end
|
20
18
|
|
21
19
|
def default_lock lock_cls, action, outcome, attrs={}
|
20
|
+
unless is_root_class?
|
21
|
+
unless root_class.has_default_lock_for_action?(action)
|
22
|
+
raise StandardError, "action is not defined on root class (#{root_class})"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
22
26
|
lock = lock_cls.new( { subject_type: self.to_s, action: action, outcome: outcome }.merge(attrs))
|
23
27
|
|
24
|
-
|
28
|
+
# remove any existing locks
|
29
|
+
if existing_lock = default_locks.detect{ |l| l.action == lock.action }
|
25
30
|
default_locks.delete(existing_lock)
|
26
31
|
end
|
27
32
|
|
33
|
+
# add new lock
|
28
34
|
default_locks.push lock
|
29
35
|
end
|
30
36
|
|
37
|
+
# ---------------------------------------------------------------------
|
38
|
+
|
31
39
|
def self_and_ancestors_with_default_locks
|
32
40
|
ancestors.select { |a| a.is_a?(Class) && a.respond_to?(:default_locks) }
|
33
41
|
end
|
@@ -36,6 +44,26 @@ module MongoidAbility
|
|
36
44
|
self_and_ancestors_with_default_locks - [self]
|
37
45
|
end
|
38
46
|
|
47
|
+
def is_root_class?
|
48
|
+
root_class == self
|
49
|
+
end
|
50
|
+
|
51
|
+
def root_class
|
52
|
+
self_and_ancestors_with_default_locks.last
|
53
|
+
end
|
54
|
+
|
55
|
+
# ---------------------------------------------------------------------
|
56
|
+
|
57
|
+
def default_lock_for_action action
|
58
|
+
default_locks.detect{ |lock| lock.action == action.to_sym }
|
59
|
+
end
|
60
|
+
|
61
|
+
def has_default_lock_for_action? action
|
62
|
+
default_lock_for_action(action).present?
|
63
|
+
end
|
64
|
+
|
65
|
+
# ---------------------------------------------------------------------
|
66
|
+
|
39
67
|
def accessible_by ability, action=:read, options={}
|
40
68
|
AccessibleQueryBuilder.call(self, ability, action, options)
|
41
69
|
end
|
@@ -6,6 +6,11 @@ module MongoidAbility
|
|
6
6
|
subject { MyLock.new }
|
7
7
|
let(:my_subject) { MySubject.new }
|
8
8
|
let(:inherited_lock) { MyLock1.new }
|
9
|
+
# ---------------------------------------------------------------------
|
10
|
+
|
11
|
+
before do
|
12
|
+
MySubject.default_locks = [ MyLock.new(action: :read, outcome: true), MyLock.new(action: :update, outcome: false) ]
|
13
|
+
end
|
9
14
|
|
10
15
|
# ---------------------------------------------------------------------
|
11
16
|
|
@@ -54,12 +59,13 @@ module MongoidAbility
|
|
54
59
|
let(:subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: false) }
|
55
60
|
let(:subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: true) }
|
56
61
|
let(:owner) { MyOwner.new(my_locks: [subject_type_lock, subject_lock]) }
|
57
|
-
let(:ability) { Ability.new(owner) }
|
58
62
|
|
59
|
-
before
|
63
|
+
before do
|
64
|
+
@ability = Ability.new(owner) # initialize owner
|
65
|
+
end
|
60
66
|
|
61
67
|
it 'does not affect calculated_outcome' do
|
62
|
-
ability.can?(:read, my_subject).must_equal true
|
68
|
+
@ability.can?(:read, my_subject).must_equal true
|
63
69
|
end
|
64
70
|
|
65
71
|
it 'returns calculated_outcome without this lock' do
|
@@ -76,11 +82,11 @@ module MongoidAbility
|
|
76
82
|
# ---------------------------------------------------------------------
|
77
83
|
|
78
84
|
describe '#criteria' do
|
79
|
-
let(:open_subject_type_lock) {
|
80
|
-
let(:closed_subject_type_lock) {
|
85
|
+
let(:open_subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: true) }
|
86
|
+
let(:closed_subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: false) }
|
81
87
|
|
82
|
-
let(:open_subject_lock) {
|
83
|
-
let(:closed_subject_lock) {
|
88
|
+
let(:open_subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: true) }
|
89
|
+
let(:closed_subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: false) }
|
84
90
|
|
85
91
|
it 'returns conditions Hash' do
|
86
92
|
open_subject_type_lock.conditions.must_be_kind_of Hash
|
@@ -22,5 +22,25 @@ module MongoidAbility
|
|
22
22
|
it { subject.locks_relation.metadata[:name].must_equal :my_locks }
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
describe '#has_lock?' do
|
27
|
+
let(:subject_type_lock) { MyLock.new(action: :read, subject_type: MySubject) }
|
28
|
+
let(:subject_lock) { MyLock.new(action: :read, subject: MySubject.new) }
|
29
|
+
let(:other_lock) { MyLock.new(action: :update, subject: MySubject.new) }
|
30
|
+
let(:owner) { MyOwner.new(my_locks: [subject_type_lock, subject_lock]) }
|
31
|
+
|
32
|
+
it 'returns true when lock for same action & subject_type' do
|
33
|
+
owner.has_lock?(subject_type_lock).must_equal true
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns true when lock for same action & subject' do
|
37
|
+
owner.has_lock?(subject_lock).must_equal true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns false for non existing lock' do
|
41
|
+
owner.has_lock?(other_lock).must_equal false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
25
45
|
end
|
26
46
|
end
|
@@ -2,41 +2,66 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module MongoidAbility
|
4
4
|
describe Subject do
|
5
|
-
describe '.default_locks' do
|
6
5
|
|
6
|
+
describe '.default_lock' do
|
7
7
|
before do
|
8
8
|
MySubject.default_locks = []
|
9
9
|
MySubject1.default_locks = []
|
10
|
+
MySubject2.default_locks = []
|
10
11
|
|
11
12
|
MySubject.default_lock MyLock, :read, true
|
13
|
+
MySubject.default_lock MyLock, :update, true
|
12
14
|
MySubject1.default_lock MyLock1, :update, false
|
13
15
|
end
|
14
16
|
|
15
17
|
it 'stores them' do
|
16
|
-
MySubject.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(read)
|
18
|
+
MySubject.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(read update)
|
17
19
|
MySubject1.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(update)
|
18
20
|
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'when lock not defined on superclass' do
|
24
|
+
before do
|
25
|
+
MySubject.default_locks = []
|
26
|
+
MySubject1.default_locks = []
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'must raise error' do
|
30
|
+
-> { MySubject1.default_lock MyLock, :test, true }.must_raise StandardError
|
31
|
+
end
|
32
|
+
end
|
19
33
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
34
|
+
describe 'prevents conflicts' do
|
35
|
+
before do
|
36
|
+
MySubject.default_locks = []
|
37
|
+
MySubject.default_lock MyLock, :read, false
|
38
|
+
MySubject.default_lock MyLock1, :read, false
|
39
|
+
end
|
26
40
|
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
it 'does not allow multiple locks for same action' do
|
42
|
+
MySubject.default_locks.select{ |l| l.action == :read }.count.must_equal 1
|
43
|
+
end
|
30
44
|
|
31
|
-
|
32
|
-
|
33
|
-
|
45
|
+
it 'replace existing locks with new attributes' do
|
46
|
+
MySubject.default_locks.detect{ |l| l.action == :read }.outcome.must_equal false
|
47
|
+
end
|
34
48
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
49
|
+
it 'replaces existing locks with new one' do
|
50
|
+
MySubject.default_locks.detect{ |l| l.action == :read }.class.must_equal MyLock1
|
38
51
|
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '.is_root_class?' do
|
55
|
+
it { MySubject.is_root_class?.must_equal true }
|
56
|
+
it { MySubject1.is_root_class?.must_equal false }
|
57
|
+
it { MySubject2.is_root_class?.must_equal false }
|
58
|
+
end
|
39
59
|
|
60
|
+
describe ".root_class" do
|
61
|
+
it { MySubject.root_class.must_equal MySubject }
|
62
|
+
it { MySubject1.root_class.must_equal MySubject }
|
63
|
+
it { MySubject2.root_class.must_equal MySubject }
|
40
64
|
end
|
65
|
+
|
41
66
|
end
|
42
67
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_ability
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Celizna
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cancancan
|