acts_as_multi_tenant 0.5.1 → 1.0.0.pre.rc1
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/README.md +13 -13
- data/lib/multi_tenant/middleware.rb +33 -36
- data/lib/multi_tenant/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de0c6576d3305ddd5a2bc8b939351675e799e755
|
4
|
+
data.tar.gz: d6ccc7ffbe9f7251f46dffe2618879d265c173e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d71a6bb84ed043f4b8f4314cdd7d54f9c1389643bd34300699946f4d89d2052204689dfb7a3f901a4a7a5be0e9c0e76efa66bea2a3b59218a493e55e2d61b517
|
7
|
+
data.tar.gz: b6869cef3c3c3023f41771c400bd387f79535696eea3bd7242029e1f74e66048500e6cd7f7638d3003e53c619f8475a5374e00ae8398cff0aa5cde9d26615613
|
data/README.md
CHANGED
@@ -21,19 +21,19 @@ use MultiTenant::Middleware,
|
|
21
21
|
# (required) Fetch the identifier of the current tenant from a Rack::Request object
|
22
22
|
identifier: ->(req) { req.host.split(/\./)[0] },
|
23
23
|
|
24
|
-
# (optional)
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# (optional) Returns a Rack response when a tenant couldn't be found in the db
|
36
|
-
# a tenant isn't given
|
24
|
+
# (optional) A Hash of fake identifiers that should be allowed through. Each identifier will have a
|
25
|
+
# Hash of Regex paths with Symbol http methods (or arrays thereof), or :any. These path & method combos
|
26
|
+
# will be allowed through when the identifier matches. All others will be blocked.
|
27
|
+
# IMPORTANT Tenant.current will be nil!
|
28
|
+
globals: {
|
29
|
+
"global" => {
|
30
|
+
%r{\A/api/widgets/} => :any,
|
31
|
+
%r{\A/api/splines/} => [:get, :post]
|
32
|
+
}
|
33
|
+
},
|
34
|
+
|
35
|
+
# (optional) Returns a Rack response when a tenant couldn't be found in the db (excluding globals),
|
36
|
+
# or when a tenant isn't given.
|
37
37
|
not_found: ->(x) {
|
38
38
|
body = {errors: ["'%s' is not a valid tenant!" % x]}.to_json
|
39
39
|
[400, {'Content-Type' => 'application/json', 'Content-Length' => body.size.to_s}, [body]]
|
@@ -13,16 +13,16 @@ module MultiTenant
|
|
13
13
|
# # A Proc that returns the tenant identifier that's used to look up the tenant. (i.e. :using option passed to acts_as_tenant)
|
14
14
|
# identifier: ->(req) { req.host.split(/\./)[0] },
|
15
15
|
#
|
16
|
-
# # (optional)
|
17
|
-
# #
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
16
|
+
# # (optional) A Hash of fake identifiers that should be allowed through. Each identifier will have a
|
17
|
+
# # Hash of Regex paths with Symbol http methods (or arrays thereof), or :any. These path & method combos
|
18
|
+
# # will be allowed through when the identifier matches. All others will be blocked.
|
19
|
+
# # IMPORTANT Tenant.current will be nil!
|
20
|
+
# globals: {
|
21
|
+
# "global" => {
|
22
|
+
# %r{\A/api/widgets/} => :any,
|
23
|
+
# %r{\A/api/splines/} => [:get, :post]
|
24
|
+
# }
|
25
|
+
# },
|
26
26
|
#
|
27
27
|
# # (optional) Returns a Rack response when a tenant couldn't be found in the db, or when
|
28
28
|
# # a tenant isn't given (and isn't in the `global_paths` list)
|
@@ -38,14 +38,8 @@ module MultiTenant
|
|
38
38
|
# @return [Proc] A Proc which accepts a Rack::Request and returns some identifier for tenant lookup
|
39
39
|
attr_accessor :identifier
|
40
40
|
|
41
|
-
# @return [
|
42
|
-
attr_accessor :
|
43
|
-
|
44
|
-
# @return [Set<String>] An array of path strings that don't requite a tenant to be given
|
45
|
-
attr_accessor :global_strings
|
46
|
-
|
47
|
-
# @return [Set<String>] An array of path regexes that don't requite a tenant to be given
|
48
|
-
attr_accessor :global_regexes
|
41
|
+
# @return [Hash] Global identifiers and their allowed paths and methods
|
42
|
+
attr_accessor :globals
|
49
43
|
|
50
44
|
# @return [Proc] A Proc which accepts a (non-existent or blank) tenant identifier and returns a rack response describing
|
51
45
|
# the error. Defaults to a 404 and some shitty html.
|
@@ -60,39 +54,36 @@ module MultiTenant
|
|
60
54
|
# Initialize a new multi tenant Rack middleware.
|
61
55
|
#
|
62
56
|
# @param app the Rack app
|
63
|
-
# @param opts [Hash] Required: :model, :identifier. Optional: :
|
57
|
+
# @param opts [Hash] Required: :model, :identifier. Optional: :globals, :not_found.
|
64
58
|
#
|
65
59
|
def initialize(app, opts)
|
66
60
|
@app = app
|
67
61
|
self.model = opts.fetch :model
|
68
62
|
self.identifier = opts.fetch :identifier
|
69
|
-
self.
|
70
|
-
|
71
|
-
|
63
|
+
self.globals = (opts[:globals] || {}).reduce({}) { |a, (global, patterns)|
|
64
|
+
a[global] = patterns.reduce({}) { |aa, (path, methods)|
|
65
|
+
aa[path] = methods == :any ? :any : Set.new(Array(methods).map { |m| m.to_s.upcase })
|
66
|
+
aa
|
67
|
+
}
|
68
|
+
a
|
69
|
+
}
|
72
70
|
self.not_found = opts[:not_found] || DEFAULT_NOT_FOUND
|
73
71
|
end
|
74
72
|
|
75
73
|
# Rack request call
|
76
74
|
def call(env)
|
75
|
+
tenant_class.current = nil
|
77
76
|
request = Rack::Request.new env
|
78
77
|
tenant_identifier = identifier.(request)
|
79
78
|
|
80
|
-
if tenant_identifier
|
81
|
-
|
82
|
-
|
83
|
-
return @app.call env
|
84
|
-
else
|
85
|
-
return not_found.(tenant_identifier)
|
86
|
-
end
|
87
|
-
end
|
79
|
+
if (allowed_paths = globals[tenant_identifier])
|
80
|
+
allowed = path_matches?(request, allowed_paths)
|
81
|
+
return allowed ? @app.call(env) : not_found.(tenant_identifier)
|
88
82
|
|
89
|
-
|
90
|
-
|
91
|
-
tenant_class.current = tenant_record
|
92
|
-
return @app.call env
|
93
|
-
elsif global_identifiers.include? tenant_identifier
|
94
|
-
tenant_class.current = nil
|
83
|
+
elsif (tenant = tenant_class.where({tenant_class.tenant_identifier => tenant_identifier}).first)
|
84
|
+
tenant_class.current = tenant
|
95
85
|
return @app.call env
|
86
|
+
|
96
87
|
else
|
97
88
|
return not_found.(tenant_identifier)
|
98
89
|
end
|
@@ -100,6 +91,12 @@ module MultiTenant
|
|
100
91
|
tenant_class.current = nil
|
101
92
|
end
|
102
93
|
|
94
|
+
def path_matches?(req, paths)
|
95
|
+
paths.any? { |(path, methods)|
|
96
|
+
(path == req.path || path =~ req.path) && (methods == :any || methods.include?(req.request_method))
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
103
100
|
# Infers and returns the tenant model class this middleware is handling
|
104
101
|
def tenant_class
|
105
102
|
@tenant_class ||= if self.model.respond_to?(:call)
|
data/lib/multi_tenant/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_multi_tenant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Hollinger
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2018-02-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -76,12 +76,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
76
|
version: 2.1.0
|
77
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- - "
|
79
|
+
- - ">"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
81
|
+
version: 1.3.1
|
82
82
|
requirements: []
|
83
83
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.5.2
|
84
|
+
rubygems_version: 2.5.2.1
|
85
85
|
signing_key:
|
86
86
|
specification_version: 4
|
87
87
|
summary: An ActiveRecord plugin for multi-tenant databases
|