mongoid-multitenancy 0.4.4 → 1.0.0
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/.rspec +1 -0
- data/.travis.yml +4 -3
- data/CHANGELOG.md +13 -0
- data/Gemfile +5 -5
- data/README.md +44 -15
- data/Rakefile +1 -1
- data/gemfiles/Gemfile.mongoid-4.0 +3 -4
- data/gemfiles/{Gemfile.mongoid-3.0 → Gemfile.mongoid-5.0} +3 -4
- data/lib/mongoid/multitenancy.rb +6 -10
- data/lib/mongoid/multitenancy/document.rb +117 -49
- data/lib/mongoid/multitenancy/validators/tenancy.rb +36 -0
- data/lib/mongoid/multitenancy/validators/tenant_uniqueness.rb +72 -0
- data/lib/mongoid/multitenancy/version.rb +2 -1
- data/mongoid-multitenancy.gemspec +8 -8
- data/spec/immutable_spec.rb +30 -18
- data/spec/indexable_spec.rb +6 -6
- data/spec/inheritance_spec.rb +11 -6
- data/spec/mandatory_spec.rb +70 -44
- data/spec/models/immutable.rb +3 -3
- data/spec/models/indexable.rb +2 -2
- data/spec/models/mandatory.rb +5 -5
- data/spec/models/mutable.rb +3 -3
- data/spec/models/optional.rb +5 -5
- data/spec/mongoid-multitenancy_spec.rb +17 -11
- data/spec/mutable_child_spec.rb +31 -17
- data/spec/mutable_spec.rb +34 -18
- data/spec/optional_spec.rb +88 -46
- data/spec/spec_helper.rb +16 -60
- data/spec/support/database_cleaner.rb +38 -0
- data/spec/support/mongoid_matchers.rb +17 -0
- data/spec/support/shared_examples.rb +81 -0
- metadata +14 -8
- data/lib/mongoid/validators/tenant_validator.rb +0 -20
- data/spec/support/mongoid.rb +0 -30
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
class DatabaseCleaner
|
4
|
+
class << self
|
5
|
+
def clean
|
6
|
+
new.clean
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def clean
|
11
|
+
if mongoid4?
|
12
|
+
collections.each { |c| database[c].find.remove_all }
|
13
|
+
else
|
14
|
+
collections.each { |c| database[c].find.delete_many }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def mongoid4?
|
21
|
+
Mongoid::VERSION.start_with? '4'
|
22
|
+
end
|
23
|
+
|
24
|
+
def database
|
25
|
+
if mongoid4?
|
26
|
+
Mongoid.default_session
|
27
|
+
else
|
28
|
+
Mongoid::Clients.default
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def collections
|
33
|
+
database['system.namespaces'].find(name: { '$not' => /\.system\.|\$/ }).to_a.map do |collection|
|
34
|
+
_, name = collection['name'].split('.', 2)
|
35
|
+
name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
class ValidateTenantUniquenessOfMatcher < ValidateUniquenessOfMatcher
|
5
|
+
def initialize(field)
|
6
|
+
@field = field.to_s
|
7
|
+
@type = 'tenant_uniqueness'
|
8
|
+
@options = {}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_tenant_uniqueness_of(field)
|
13
|
+
ValidateTenantUniquenessOfMatcher.new(field)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
shared_examples_for 'a tenantable model' do
|
2
|
+
|
3
|
+
it { is_expected.to belong_to(:client) }
|
4
|
+
it { is_expected.to have_index_for(client_id: 1, title: 1) }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
context 'within a client context' do
|
8
|
+
before do
|
9
|
+
Mongoid::Multitenancy.current_tenant = client
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'set the client' do
|
13
|
+
expect(item.client).to eq client
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'without a client context' do
|
18
|
+
before do
|
19
|
+
Mongoid::Multitenancy.current_tenant = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'does not set any client' do
|
23
|
+
expect(item.client).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#valid?' do
|
29
|
+
context 'within a client context' do
|
30
|
+
before do
|
31
|
+
Mongoid::Multitenancy.current_tenant = client
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with the client id' do
|
35
|
+
before do
|
36
|
+
item.client = client
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'is valid' do
|
40
|
+
expect(item).to be_valid
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with another client id' do
|
45
|
+
before do
|
46
|
+
item.client = another_client
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'is not valid' do
|
50
|
+
expect(item).not_to be_valid
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'without a client context' do
|
56
|
+
before do
|
57
|
+
Mongoid::Multitenancy.current_tenant = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with the client id' do
|
61
|
+
before do
|
62
|
+
item.client = client
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'is valid' do
|
66
|
+
expect(item).to be_valid
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with another client id' do
|
71
|
+
before do
|
72
|
+
item.client = another_client
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'is valid' do
|
76
|
+
expect(item).to be_valid
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-multitenancy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aymeric Brisse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.0'
|
27
27
|
description: MultiTenancy with Mongoid
|
28
28
|
email:
|
29
29
|
- aymeric.brisse@mperfect-memory.com
|
@@ -34,17 +34,19 @@ files:
|
|
34
34
|
- ".gitignore"
|
35
35
|
- ".rspec"
|
36
36
|
- ".travis.yml"
|
37
|
+
- CHANGELOG.md
|
37
38
|
- Gemfile
|
38
39
|
- LICENSE.TXT
|
39
40
|
- README.md
|
40
41
|
- Rakefile
|
41
|
-
- gemfiles/Gemfile.mongoid-3.0
|
42
42
|
- gemfiles/Gemfile.mongoid-4.0
|
43
|
+
- gemfiles/Gemfile.mongoid-5.0
|
43
44
|
- lib/mongoid-multitenancy.rb
|
44
45
|
- lib/mongoid/multitenancy.rb
|
45
46
|
- lib/mongoid/multitenancy/document.rb
|
47
|
+
- lib/mongoid/multitenancy/validators/tenancy.rb
|
48
|
+
- lib/mongoid/multitenancy/validators/tenant_uniqueness.rb
|
46
49
|
- lib/mongoid/multitenancy/version.rb
|
47
|
-
- lib/mongoid/validators/tenant_validator.rb
|
48
50
|
- mongoid-multitenancy.gemspec
|
49
51
|
- spec/immutable_spec.rb
|
50
52
|
- spec/indexable_spec.rb
|
@@ -62,7 +64,9 @@ files:
|
|
62
64
|
- spec/mutable_spec.rb
|
63
65
|
- spec/optional_spec.rb
|
64
66
|
- spec/spec_helper.rb
|
65
|
-
- spec/support/
|
67
|
+
- spec/support/database_cleaner.rb
|
68
|
+
- spec/support/mongoid_matchers.rb
|
69
|
+
- spec/support/shared_examples.rb
|
66
70
|
homepage: https://github.com/PerfectMemory/mongoid-multitenancy
|
67
71
|
licenses:
|
68
72
|
- MIT
|
@@ -104,5 +108,7 @@ test_files:
|
|
104
108
|
- spec/mutable_spec.rb
|
105
109
|
- spec/optional_spec.rb
|
106
110
|
- spec/spec_helper.rb
|
107
|
-
- spec/support/
|
111
|
+
- spec/support/database_cleaner.rb
|
112
|
+
- spec/support/mongoid_matchers.rb
|
113
|
+
- spec/support/shared_examples.rb
|
108
114
|
has_rdoc:
|
@@ -1,20 +0,0 @@
|
|
1
|
-
class TenantValidator < ActiveModel::EachValidator
|
2
|
-
def validate_each(object, attribute, value)
|
3
|
-
# Immutable Check
|
4
|
-
if options[:immutable]
|
5
|
-
if object.send(:attribute_changed?, attribute) and object.send(:attribute_was, attribute)
|
6
|
-
object.errors.add(attribute, 'is immutable and cannot be updated')
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
# Ownership check
|
11
|
-
if value and Mongoid::Multitenancy.current_tenant and value != Mongoid::Multitenancy.current_tenant.id
|
12
|
-
object.errors.add(attribute, "not authorized")
|
13
|
-
end
|
14
|
-
|
15
|
-
# Optional Check
|
16
|
-
if !options[:optional] and value.nil?
|
17
|
-
object.errors.add(attribute, 'is mandatory')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/spec/support/mongoid.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Mongoid
|
2
|
-
module Matchers
|
3
|
-
class HaveIndexForMatcher
|
4
|
-
def matches?(klass)
|
5
|
-
@klass = klass.is_a?(Class) ? klass : klass.class
|
6
|
-
@errors = []
|
7
|
-
|
8
|
-
if Mongoid::VERSION.to_i < 4
|
9
|
-
index_options = @klass.index_options
|
10
|
-
else
|
11
|
-
index_options = Hash[@klass.index_specifications.map{|i| [i.key, i.options]}]
|
12
|
-
end
|
13
|
-
|
14
|
-
unless index_options[@index_fields]
|
15
|
-
@errors.push "no index for #{@index_fields}"
|
16
|
-
else
|
17
|
-
if !@options.nil? && !@options.empty?
|
18
|
-
@options.each do |option, option_value|
|
19
|
-
if index_options[@index_fields][option] != option_value
|
20
|
-
@errors.push "index for #{@index_fields.inspect} with options of #{index_options[@index_fields].inspect}"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
@errors.empty?
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|