rls_multi_tenant 0.1.6 → 0.1.8
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 +3 -0
- data/.rubocop.yml +2 -2
- data/README.md +66 -5
- data/lib/rls_multi_tenant/concerns/multi_tenant.rb +5 -0
- data/lib/rls_multi_tenant/concerns/tenant_context.rb +1 -0
- data/lib/rls_multi_tenant/generators/install/templates/rls_multi_tenant.rb +7 -0
- data/lib/rls_multi_tenant/generators/model/templates/migration.rb +1 -1
- data/lib/rls_multi_tenant/generators/shared/templates/create_tenant.rb +2 -0
- data/lib/rls_multi_tenant/middleware/subdomain_tenant_selector.rb +79 -0
- data/lib/rls_multi_tenant/railtie.rb +6 -0
- data/lib/rls_multi_tenant/security_validator.rb +2 -2
- data/lib/rls_multi_tenant/version.rb +1 -1
- data/lib/rls_multi_tenant.rb +12 -1
- data/rls_multi_tenant.gemspec +1 -0
- metadata +19 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3fb27124134b3487ef6f83347eca26c0ac64431e44a01d92cf70bd3dd5a03e20
|
|
4
|
+
data.tar.gz: a4fceedb11cdc42c788aad2c8c8ac11f6344d497ec2f62b002719c7cfc5a6179
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: adff1ce5bde6c15d358e67041982e0506c97fa5b1e7eee02fd69fbf9eab3799fa67be034a8b584ea8cf5864a556751d1d8a679e3adf49cddbedc995d988b98d7
|
|
7
|
+
data.tar.gz: 0c125b52250a2fce049e4f0965af09c4ae13f75f8a7516b58f6a6d136179821471a2f7ff24340ba3654f2cfa1ec4bcf2af29d4ab76ddb58ddad2e3643edc5dbd
|
data/.rspec
ADDED
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# RLS Multi-Tenant
|
|
2
2
|
|
|
3
|
+
[](https://github.com/codingways/rls_multi_tenant/actions/workflows/simple.yml)
|
|
4
|
+
[](https://www.ruby-lang.org/)
|
|
5
|
+
[](https://rubyonrails.org/)
|
|
6
|
+
[](https://badge.fury.io/rb/rls_multi_tenant)
|
|
7
|
+
[](https://rubygems.org/gems/rls_multi_tenant)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
3
10
|
A Rails gem that provides PostgreSQL Row Level Security (RLS) based multi-tenancy for Rails applications.
|
|
4
11
|
|
|
5
12
|
## Features
|
|
@@ -10,6 +17,7 @@ A Rails gem that provides PostgreSQL Row Level Security (RLS) based multi-tenanc
|
|
|
10
17
|
- 📦 **Auto-inclusion**: Automatic model configuration
|
|
11
18
|
- 🚀 **Generators**: Rails generators for quick setup
|
|
12
19
|
- ⚙️ **Configurable**: Flexible configuration options
|
|
20
|
+
- 🌐 **Subdomain Middleware**: Automatic tenant switching based on subdomain
|
|
13
21
|
|
|
14
22
|
## Installation
|
|
15
23
|
|
|
@@ -40,6 +48,8 @@ bundle install
|
|
|
40
48
|
config.tenant_id_column = :tenant_id # Tenant ID column name
|
|
41
49
|
config.app_user_env_var = "POSTGRES_APP_USER" # Environment variable for app user
|
|
42
50
|
config.enable_security_validation = true # Enable security checks
|
|
51
|
+
config.enable_subdomain_middleware = true # Enable subdomain-based tenant switching (default: true)
|
|
52
|
+
config.subdomain_field = :subdomain # Field to use for subdomain matching (default: :subdomain)
|
|
43
53
|
end
|
|
44
54
|
```
|
|
45
55
|
|
|
@@ -75,32 +85,78 @@ Your models automatically include the `MultiTenant` concern:
|
|
|
75
85
|
```ruby
|
|
76
86
|
class User < ApplicationRecord
|
|
77
87
|
# Automatically includes MultiTenant concern
|
|
78
|
-
|
|
88
|
+
include RlsMultiTenant::Concerns::MultiTenant
|
|
79
89
|
end
|
|
80
90
|
```
|
|
81
91
|
|
|
82
92
|
### Tenant Context Switching
|
|
83
93
|
|
|
84
94
|
```ruby
|
|
85
|
-
# Create a new tenant
|
|
86
|
-
tenant = Tenant.create!(name: "
|
|
95
|
+
# Create a new tenant with subdomain
|
|
96
|
+
tenant = Tenant.create!(name: "Company A", subdomain: "company-a")
|
|
87
97
|
```
|
|
88
98
|
|
|
89
99
|
```ruby
|
|
90
100
|
# Switch tenant context for a block
|
|
91
101
|
Tenant.switch(tenant) do
|
|
92
|
-
User.create!(name: "User from
|
|
102
|
+
User.create!(name: "User from Company A", email: "user@company-a.com") # Automatically assigned to current tenant
|
|
93
103
|
end
|
|
94
104
|
|
|
95
105
|
# Switch tenant context permanently
|
|
96
106
|
Tenant.switch!(tenant)
|
|
97
|
-
User.create!(name: "User from
|
|
107
|
+
User.create!(name: "User from Company A", email: "user@company-a.com")
|
|
98
108
|
Tenant.reset! # Reset context
|
|
99
109
|
|
|
100
110
|
# Get current tenant
|
|
101
111
|
current_tenant = Tenant.current
|
|
102
112
|
```
|
|
103
113
|
|
|
114
|
+
### Automatic Subdomain-Based Tenant Switching
|
|
115
|
+
|
|
116
|
+
The gem includes middleware that automatically switches tenants based on the request subdomain. This is enabled by default and works seamlessly with your tenant model.
|
|
117
|
+
|
|
118
|
+
**The middleware automatically:**
|
|
119
|
+
- Extracts the subdomain from the request host
|
|
120
|
+
- Finds the matching tenant by the subdomain field
|
|
121
|
+
- Switches the tenant context for the duration of the request
|
|
122
|
+
- Resets the context after the request completes
|
|
123
|
+
|
|
124
|
+
**Usage:**
|
|
125
|
+
```ruby
|
|
126
|
+
# Create tenants with subdomains
|
|
127
|
+
tenant1 = Tenant.create!(name: "Company A", subdomain: "company-a")
|
|
128
|
+
tenant2 = Tenant.create!(name: "Company B", subdomain: "company-b")
|
|
129
|
+
|
|
130
|
+
# Users visiting company-a.yourdomain.com will automatically be in tenant1's context
|
|
131
|
+
# Users visiting company-b.yourdomain.com will automatically be in tenant2's context
|
|
132
|
+
# Users visiting yourdomain.com (no subdomain) will have no tenant context
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Public Access (Non-Tenanted Models)
|
|
136
|
+
|
|
137
|
+
Models that don't include `RlsMultiTenant::Concerns::TenantContext` are automatically treated as public models and can be accessed without tenant context. This provides a secure, explicit way to separate tenant-specific and public models.
|
|
138
|
+
|
|
139
|
+
**Example:**
|
|
140
|
+
```ruby
|
|
141
|
+
# Public models (no tenant association)
|
|
142
|
+
class PublicPost < ApplicationRecord
|
|
143
|
+
# No TenantContext concern included
|
|
144
|
+
# These models are accessible without tenant context
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Tenant-specific models (automatically generated)
|
|
148
|
+
class User < ApplicationRecord
|
|
149
|
+
# Automatically includes MultiTenant concern
|
|
150
|
+
# These models require tenant context and are constrained by RLS
|
|
151
|
+
include RlsMultiTenant::Concerns::MultiTenant
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Security Benefits:**
|
|
156
|
+
- **Explicit Intent**: Models must explicitly include `TenantContext` to be tenant-constrained
|
|
157
|
+
- **Fail-Safe**: Public models are clearly separated from tenant models
|
|
158
|
+
- **No Configuration Drift**: Can't accidentally expose tenant data through misconfiguration
|
|
159
|
+
|
|
104
160
|
## Configuration
|
|
105
161
|
|
|
106
162
|
The gem is configured in `config/initializers/rls_multi_tenant.rb` (created by the install generator). You can customize the following options:
|
|
@@ -111,6 +167,8 @@ RlsMultiTenant.configure do |config|
|
|
|
111
167
|
config.tenant_id_column = :tenant_id # Tenant ID column name
|
|
112
168
|
config.app_user_env_var = "POSTGRES_APP_USER" # Environment variable for app user
|
|
113
169
|
config.enable_security_validation = true # Enable security checks (prevents running with superuser privileges)
|
|
170
|
+
config.enable_subdomain_middleware = true # Enable subdomain-based tenant switching (default: true)
|
|
171
|
+
config.subdomain_field = :subdomain # Field to use for subdomain matching (default: :subdomain)
|
|
114
172
|
end
|
|
115
173
|
```
|
|
116
174
|
|
|
@@ -126,6 +184,9 @@ rails db_as:admin[seed]
|
|
|
126
184
|
|
|
127
185
|
# Create database with admin privileges
|
|
128
186
|
rails db_as:admin[create]
|
|
187
|
+
|
|
188
|
+
# Drop database with admin privileges
|
|
189
|
+
rails db_as:admin[drop]
|
|
129
190
|
```
|
|
130
191
|
|
|
131
192
|
## Security Features
|
|
@@ -16,8 +16,13 @@ module RlsMultiTenant
|
|
|
16
16
|
|
|
17
17
|
def set_tenant_id
|
|
18
18
|
current_tenant = RlsMultiTenant.tenant_class.current
|
|
19
|
+
|
|
19
20
|
if current_tenant && self.send(RlsMultiTenant.tenant_id_column).blank?
|
|
20
21
|
self.send("#{RlsMultiTenant.tenant_id_column}=", current_tenant.id)
|
|
22
|
+
elsif current_tenant.nil?
|
|
23
|
+
raise RlsMultiTenant::Error,
|
|
24
|
+
"Cannot create #{self.class.name} without tenant context. " \
|
|
25
|
+
"This model requires a tenant context. "
|
|
21
26
|
end
|
|
22
27
|
end
|
|
23
28
|
end
|
|
@@ -12,4 +12,11 @@ RlsMultiTenant.configure do |config|
|
|
|
12
12
|
|
|
13
13
|
# Enable/disable security validation
|
|
14
14
|
config.enable_security_validation = true
|
|
15
|
+
|
|
16
|
+
# Enable/disable subdomain-based tenant switching middleware
|
|
17
|
+
config.enable_subdomain_middleware = true
|
|
18
|
+
|
|
19
|
+
# Configure the field to use for subdomain matching (default: :subdomain)
|
|
20
|
+
# This should be a field on your tenant model that contains the subdomain
|
|
21
|
+
config.subdomain_field = :subdomain
|
|
15
22
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class <%= migration_class_name %> < ActiveRecord::Migration[<%= Rails.version.to_f %>]
|
|
2
2
|
def change
|
|
3
3
|
# Create the table
|
|
4
|
-
create_table :<%= table_name
|
|
4
|
+
create_table :<%= table_name %> do |t|
|
|
5
5
|
t.references :<%= tenant_id_column.to_s.gsub('_id', '') %>, null: false, foreign_key: { to_table: :<%= tenant_class_name.underscore.pluralize %> }, type: :uuid
|
|
6
6
|
<% @attributes.each do |attribute| -%>
|
|
7
7
|
t.<%= attribute.type %> :<%= attribute.name %>
|
|
@@ -2,10 +2,12 @@ class Create<%= RlsMultiTenant.tenant_class_name.pluralize %> < ActiveRecord::Mi
|
|
|
2
2
|
def change
|
|
3
3
|
create_table :<%= RlsMultiTenant.tenant_class_name.underscore.pluralize %>, id: :uuid do |t|
|
|
4
4
|
t.string :name, null: false
|
|
5
|
+
t.string :subdomain, null: false
|
|
5
6
|
|
|
6
7
|
t.timestamps
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
add_index :<%= RlsMultiTenant.tenant_class_name.underscore.pluralize %>, :name, unique: true
|
|
11
|
+
add_index :<%= RlsMultiTenant.tenant_class_name.underscore.pluralize %>, :subdomain, unique: true
|
|
10
12
|
end
|
|
11
13
|
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RlsMultiTenant
|
|
4
|
+
module Middleware
|
|
5
|
+
class SubdomainTenantSelector
|
|
6
|
+
def initialize(app)
|
|
7
|
+
@app = app
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
request = ActionDispatch::Request.new(env)
|
|
12
|
+
tenant = resolve_tenant_from_subdomain(request)
|
|
13
|
+
|
|
14
|
+
if tenant
|
|
15
|
+
# Switch tenant context for the duration of the request
|
|
16
|
+
Rails.logger.info "[RLS Multi-Tenant] #{request.method} #{request.path} -> Tenant: #{tenant.name} (#{tenant.id})" if defined?(Rails)
|
|
17
|
+
RlsMultiTenant.tenant_class.switch(tenant) do
|
|
18
|
+
@app.call(env)
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
# No tenant found - check if we need tenant context
|
|
22
|
+
subdomain = extract_subdomain(request.host)
|
|
23
|
+
if subdomain.present? && subdomain != 'www'
|
|
24
|
+
# Subdomain exists but no tenant found - this is an error
|
|
25
|
+
Rails.logger.warn "[RLS Multi-Tenant] #{request.method} #{request.path} -> No tenant found for subdomain '#{subdomain}'" if defined?(Rails)
|
|
26
|
+
raise RlsMultiTenant::Error, "No tenant found for subdomain '#{subdomain}'. Please ensure the tenant exists with the correct subdomain."
|
|
27
|
+
end
|
|
28
|
+
# If no subdomain, allow access to public models (models without TenantContext)
|
|
29
|
+
# Models that include TenantContext will automatically be constrained by RLS
|
|
30
|
+
Rails.logger.info "[RLS Multi-Tenant] #{request.method} #{request.path} -> Public access (no subdomain)" if defined?(Rails)
|
|
31
|
+
@app.call(env)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def resolve_tenant_from_subdomain(request)
|
|
38
|
+
subdomain = extract_subdomain(request.host)
|
|
39
|
+
return nil if subdomain.blank? || subdomain == 'www'
|
|
40
|
+
|
|
41
|
+
# Look up tenant by subdomain only
|
|
42
|
+
tenant_class = RlsMultiTenant.tenant_class
|
|
43
|
+
subdomain_field = RlsMultiTenant.subdomain_field
|
|
44
|
+
|
|
45
|
+
# Only allow subdomain-based lookup
|
|
46
|
+
unless tenant_class.column_names.include?(subdomain_field.to_s)
|
|
47
|
+
raise RlsMultiTenant::ConfigurationError,
|
|
48
|
+
"Subdomain field '#{subdomain_field}' not found on #{tenant_class.name}. " \
|
|
49
|
+
"Please add a '#{subdomain_field}' column to your tenant model or configure a different subdomain_field."
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
tenant_class.find_by(subdomain_field => subdomain)
|
|
53
|
+
rescue => e
|
|
54
|
+
Rails.logger.error "Failed to resolve tenant from subdomain '#{subdomain}': #{e.message}" if defined?(Rails)
|
|
55
|
+
nil
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def extract_subdomain(host)
|
|
59
|
+
return nil if host.blank?
|
|
60
|
+
|
|
61
|
+
# Remove port if present
|
|
62
|
+
host = host.split(':').first
|
|
63
|
+
|
|
64
|
+
# Split by dots and get the first part (subdomain)
|
|
65
|
+
parts = host.split('.')
|
|
66
|
+
|
|
67
|
+
# Handle localhost development (e.g., foo.localhost:3000)
|
|
68
|
+
if parts.length == 2 && parts.last == 'localhost'
|
|
69
|
+
parts.first
|
|
70
|
+
# Handle standard domains (e.g., foo.example.com)
|
|
71
|
+
elsif parts.length >= 3
|
|
72
|
+
parts.first
|
|
73
|
+
else
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -34,5 +34,11 @@ module RlsMultiTenant
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
|
+
|
|
38
|
+
initializer "rls_multi_tenant.middleware", after: :load_config_initializers do |app|
|
|
39
|
+
if RlsMultiTenant.enable_subdomain_middleware
|
|
40
|
+
app.config.middleware.use RlsMultiTenant::Middleware::SubdomainTenantSelector
|
|
41
|
+
end
|
|
42
|
+
end
|
|
37
43
|
end
|
|
38
44
|
end
|
|
@@ -48,8 +48,8 @@ module RlsMultiTenant
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
50
|
def skip_validation?
|
|
51
|
-
# Skip validation if we're running install generator
|
|
52
|
-
return true if ARGV.any? { |arg| arg.include?('rls_multi_tenant:install') }
|
|
51
|
+
# Skip validation if we're running an install or setup generator
|
|
52
|
+
return true if ARGV.any? { |arg| arg.include?('rls_multi_tenant:install') || arg.include?('rls_multi_tenant:setup') }
|
|
53
53
|
|
|
54
54
|
# Skip validation if we're in admin mode (set by db_as:admin task)
|
|
55
55
|
return true if ENV['RLS_MULTI_TENANT_ADMIN_MODE'] == 'true'
|
data/lib/rls_multi_tenant.rb
CHANGED
|
@@ -5,6 +5,7 @@ require "rls_multi_tenant/concerns/multi_tenant"
|
|
|
5
5
|
require "rls_multi_tenant/concerns/tenant_context"
|
|
6
6
|
require "rls_multi_tenant/security_validator"
|
|
7
7
|
require "rls_multi_tenant/rls_helper"
|
|
8
|
+
require "rls_multi_tenant/middleware/subdomain_tenant_selector"
|
|
8
9
|
require "rls_multi_tenant/generators/shared/template_helper"
|
|
9
10
|
require "rls_multi_tenant/railtie" if defined?(Rails)
|
|
10
11
|
|
|
@@ -15,7 +16,7 @@ module RlsMultiTenant
|
|
|
15
16
|
|
|
16
17
|
# Configuration options
|
|
17
18
|
class << self
|
|
18
|
-
attr_accessor :tenant_class_name, :tenant_id_column, :app_user_env_var, :enable_security_validation
|
|
19
|
+
attr_accessor :tenant_class_name, :tenant_id_column, :app_user_env_var, :enable_security_validation, :enable_subdomain_middleware, :subdomain_field
|
|
19
20
|
|
|
20
21
|
def configure
|
|
21
22
|
yield self
|
|
@@ -36,6 +37,14 @@ module RlsMultiTenant
|
|
|
36
37
|
def enable_security_validation
|
|
37
38
|
@enable_security_validation.nil? ? true : @enable_security_validation
|
|
38
39
|
end
|
|
40
|
+
|
|
41
|
+
def enable_subdomain_middleware
|
|
42
|
+
@enable_subdomain_middleware.nil? ? false : @enable_subdomain_middleware
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def subdomain_field
|
|
46
|
+
@subdomain_field ||= :subdomain
|
|
47
|
+
end
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
# Default configuration
|
|
@@ -43,4 +52,6 @@ module RlsMultiTenant
|
|
|
43
52
|
self.tenant_id_column = :tenant_id
|
|
44
53
|
self.app_user_env_var = "POSTGRES_APP_USER"
|
|
45
54
|
self.enable_security_validation = true
|
|
55
|
+
self.enable_subdomain_middleware = true
|
|
56
|
+
self.subdomain_field = :subdomain
|
|
46
57
|
end
|
data/rls_multi_tenant.gemspec
CHANGED
|
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
# Dependencies
|
|
35
35
|
spec.add_dependency "rails", ">= 6.0", "< 9.0"
|
|
36
36
|
spec.add_dependency "pg", ">= 1.0", "< 3.0"
|
|
37
|
+
spec.add_dependency "ostruct", ">= 0.1.0"
|
|
37
38
|
|
|
38
39
|
# Development dependencies
|
|
39
40
|
spec.add_development_dependency "rspec-rails", "~> 6.0"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rls_multi_tenant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Coding Ways
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -50,6 +49,20 @@ dependencies:
|
|
|
50
49
|
- - "<"
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
51
|
version: '3.0'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: ostruct
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: 0.1.0
|
|
59
|
+
type: :runtime
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 0.1.0
|
|
53
66
|
- !ruby/object:Gem::Dependency
|
|
54
67
|
name: rspec-rails
|
|
55
68
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -157,6 +170,7 @@ executables: []
|
|
|
157
170
|
extensions: []
|
|
158
171
|
extra_rdoc_files: []
|
|
159
172
|
files:
|
|
173
|
+
- ".rspec"
|
|
160
174
|
- ".rubocop.yml"
|
|
161
175
|
- README.md
|
|
162
176
|
- lib/rls_multi_tenant.rb
|
|
@@ -177,6 +191,7 @@ files:
|
|
|
177
191
|
- lib/rls_multi_tenant/generators/shared/templates/db_admin.rake
|
|
178
192
|
- lib/rls_multi_tenant/generators/shared/templates/enable_uuid_extension.rb
|
|
179
193
|
- lib/rls_multi_tenant/generators/task/task_generator.rb
|
|
194
|
+
- lib/rls_multi_tenant/middleware/subdomain_tenant_selector.rb
|
|
180
195
|
- lib/rls_multi_tenant/railtie.rb
|
|
181
196
|
- lib/rls_multi_tenant/rls_helper.rb
|
|
182
197
|
- lib/rls_multi_tenant/rls_multi_tenant.rb
|
|
@@ -192,7 +207,6 @@ metadata:
|
|
|
192
207
|
changelog_uri: https://github.com/codingways/rls_multi_tenant/blob/main/CHANGELOG.md
|
|
193
208
|
bug_tracker_uri: https://github.com/codingways/rls_multi_tenant/issues
|
|
194
209
|
documentation_uri: https://github.com/codingways/rls_multi_tenant#readme
|
|
195
|
-
post_install_message:
|
|
196
210
|
rdoc_options: []
|
|
197
211
|
require_paths:
|
|
198
212
|
- lib
|
|
@@ -207,8 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
207
221
|
- !ruby/object:Gem::Version
|
|
208
222
|
version: '0'
|
|
209
223
|
requirements: []
|
|
210
|
-
rubygems_version: 3.
|
|
211
|
-
signing_key:
|
|
224
|
+
rubygems_version: 3.6.9
|
|
212
225
|
specification_version: 4
|
|
213
226
|
summary: Rails gem for PostgreSQL Row Level Security (RLS) multi-tenant applications
|
|
214
227
|
test_files: []
|