pg_rls 0.0.2.6.12 → 0.1.1
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/.rubocop.yml +21 -157
- data/Gemfile +4 -1
- data/Gemfile.lock +192 -139
- data/README.md +3 -6
- data/lib/generators/pg_rls/active_record/active_record_generator.rb +10 -10
- data/lib/generators/pg_rls/active_record/templates/convert_migration_backport.rb.tt +1 -1
- data/lib/generators/pg_rls/install_generator.rb +10 -23
- data/lib/generators/templates/README +1 -3
- data/lib/generators/templates/pg_rls.rb.tt +0 -7
- data/lib/pg_rls/database/configurations.rb +33 -0
- data/lib/pg_rls/database/prepared.rb +1 -1
- data/lib/pg_rls/database/tasks/admin_database.rake +20 -43
- data/lib/pg_rls/errors/admin_username.rb +12 -0
- data/lib/pg_rls/errors/index.rb +5 -0
- data/lib/pg_rls/errors/rake_only_error.rb +12 -0
- data/lib/pg_rls/errors/tenant_not_found.rb +2 -10
- data/lib/pg_rls/middleware/sidekiq/client.rb +10 -1
- data/lib/pg_rls/middleware/sidekiq/server.rb +5 -1
- data/lib/pg_rls/multi_tenancy.rb +4 -4
- data/lib/pg_rls/schema/down_statements.rb +5 -5
- data/lib/pg_rls/schema/statements.rb +4 -4
- data/lib/pg_rls/schema/up_statements.rb +8 -8
- data/lib/pg_rls/tenant.rb +23 -26
- data/lib/pg_rls/version.rb +1 -1
- data/lib/pg_rls.rb +71 -61
- metadata +8 -8
- data/lib/pg_rls/schema/solo/statements.rb +0 -24
- data/lib/pg_rls/schema/solo/up_statements.rb +0 -106
- data/lib/pg_rls/secure_connection.rb +0 -23
- data/lib/pg_rls/solo/tenant.rb +0 -50
|
@@ -20,11 +20,11 @@ module PgRls
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def create_tenant_migration_file
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
return unless creating?
|
|
24
|
+
|
|
25
|
+
migration_template(create_migration_template_path,
|
|
26
|
+
"#{migration_path}/#{create_file_sub_name}_#{table_name}.rb",
|
|
27
|
+
migration_version:)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def convert_tenant_migration_file
|
|
@@ -34,11 +34,11 @@ module PgRls
|
|
|
34
34
|
migration_version:)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
return unless installation_in_progress?
|
|
38
|
+
|
|
39
|
+
migration_template('convert_migration_backport.rb.tt',
|
|
40
|
+
"#{migration_path}/pg_rls_backport_#{table_name}.rb",
|
|
41
|
+
migration_version:)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def create_model_file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class PgRlsBackport<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
|
4
4
|
def up
|
|
5
5
|
# Suggested Code:
|
|
6
|
-
# PgRls.
|
|
6
|
+
# PgRls.on_each_tenant do |tenant|
|
|
7
7
|
# tenant.<%= table_name %>.in_batches(of: 100) do |<%= table_name %>|
|
|
8
8
|
# <%= table_name %>.each { |<%= table_name.singularize %>| <%= table_name.singularize %>.update_attribute('tenant_id', tenant.tenant_id) }
|
|
9
9
|
# end
|
|
@@ -32,13 +32,13 @@ module PgRls
|
|
|
32
32
|
hook_for :orm, required: true
|
|
33
33
|
|
|
34
34
|
def orm_error_message
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
<<~ERROR
|
|
36
|
+
An ORM must be set to install PgRls in your application.
|
|
37
|
+
Be sure to have an ORM like Active Record or loaded in your
|
|
38
|
+
app or configure your own at `config/application.rb`.
|
|
39
|
+
config.generators do |g|
|
|
40
|
+
g.orm :your_orm_gem
|
|
41
|
+
end
|
|
42
42
|
ERROR
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -46,7 +46,6 @@ module PgRls
|
|
|
46
46
|
raise MissingORMError, orm_error_message unless options[:orm]
|
|
47
47
|
|
|
48
48
|
inject_include_to_application
|
|
49
|
-
inject_include_to_application_record
|
|
50
49
|
inject_include_to_application_controller
|
|
51
50
|
template 'pg_rls.rb.tt', 'config/initializers/pg_rls.rb'
|
|
52
51
|
end
|
|
@@ -54,23 +53,15 @@ module PgRls
|
|
|
54
53
|
def inject_include_to_application
|
|
55
54
|
return if aplication_already_included?
|
|
56
55
|
|
|
57
|
-
gsub_file(APPLICATION_PATH, /(#{Regexp.escape(APPLICATION_LINE)})/
|
|
56
|
+
gsub_file(APPLICATION_PATH, /(#{Regexp.escape(APPLICATION_LINE)})/mio) do |match|
|
|
58
57
|
"#{match}\n config.active_record.schema_format = :sql\n"
|
|
59
58
|
end
|
|
60
59
|
end
|
|
61
60
|
|
|
62
|
-
def inject_include_to_application_record
|
|
63
|
-
return if aplication_record_already_included?
|
|
64
|
-
|
|
65
|
-
gsub_file(APPLICATION_RECORD_PATH, /(#{Regexp.escape(APPLICATION_RECORD_LINE)})/mi) do |match|
|
|
66
|
-
"#{match}\n include PgRls::SecureConnection\n"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
61
|
def inject_include_to_application_controller
|
|
71
62
|
return if aplication_controller_already_included?
|
|
72
63
|
|
|
73
|
-
gsub_file(APPLICATION_CONTROLLER_PATH, /(#{Regexp.escape(APPLICATION_CONTROLLER_LINE)})/
|
|
64
|
+
gsub_file(APPLICATION_CONTROLLER_PATH, /(#{Regexp.escape(APPLICATION_CONTROLLER_LINE)})/mio) do |match|
|
|
74
65
|
"#{match}\n include PgRls::MultiTenancy\n"
|
|
75
66
|
end
|
|
76
67
|
end
|
|
@@ -79,16 +70,12 @@ module PgRls
|
|
|
79
70
|
File.readlines(APPLICATION_CONTROLLER_PATH).grep(/include PgRls::MultiTenancy/).any?
|
|
80
71
|
end
|
|
81
72
|
|
|
82
|
-
def aplication_record_already_included?
|
|
83
|
-
File.readlines(APPLICATION_RECORD_PATH).grep(/include PgRls::SecureConnection/).any?
|
|
84
|
-
end
|
|
85
|
-
|
|
86
73
|
def aplication_already_included?
|
|
87
74
|
File.readlines(APPLICATION_PATH).grep(/config.active_record.schema_format = :sql/).any?
|
|
88
75
|
end
|
|
89
76
|
|
|
90
77
|
def initialize_error_text
|
|
91
|
-
|
|
78
|
+
<<~ERROR
|
|
92
79
|
TO DO
|
|
93
80
|
ERROR
|
|
94
81
|
end
|
|
@@ -2,12 +2,10 @@ README
|
|
|
2
2
|
===============================================================================
|
|
3
3
|
WARNING!!
|
|
4
4
|
|
|
5
|
-
PgRls required that ActiveRecord format migration as SQL
|
|
5
|
+
PgRls required that ActiveRecord format migration as SQL
|
|
6
6
|
|
|
7
7
|
Once you remove a tenant all of his data would be removed as well
|
|
8
8
|
|
|
9
|
-
PgRls::SecureConnection was included to your ApplicationRecord do not remove it
|
|
10
|
-
|
|
11
9
|
If you're setting a custom user, make sure to regenerate the structure.sql since
|
|
12
10
|
Postgresql policies are created on each user
|
|
13
11
|
|
|
@@ -20,13 +20,6 @@ PgRls.setup do |config|
|
|
|
20
20
|
# config.username = Rails.application.credentials.dig(:database, :username)
|
|
21
21
|
# config.password = Rails.application.credentials.dig(:database, :password)
|
|
22
22
|
|
|
23
|
-
##
|
|
24
|
-
## Uncomment this lines in order to enable solo mode
|
|
25
|
-
## Solo mode is made for API mode where we don't want to repeate the same
|
|
26
|
-
## data structure across many project, Solo mode create a hidden tenant table
|
|
27
|
-
## which is autopopulated on each request
|
|
28
|
-
# config.solo_mode = true
|
|
29
|
-
|
|
30
23
|
## ------------------------------ Middleware SetResetConnection -----------------------------
|
|
31
24
|
## Uncomment this lines if you're using SetResetConnection Middleware
|
|
32
25
|
#
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_record/database_configurations'
|
|
4
|
+
|
|
5
|
+
module ActiveRecord
|
|
6
|
+
# ActiveRecord::DatabaseConfigurations
|
|
7
|
+
class DatabaseConfigurations
|
|
8
|
+
class HashConfig
|
|
9
|
+
def initialize(env_name, name, configuration_hash)
|
|
10
|
+
@env_name = env_name
|
|
11
|
+
@name = name
|
|
12
|
+
@configuration_hash = configuration_hash
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def configuration_hash
|
|
16
|
+
return admin_configuration_hash if PgRls.as_db_admin?
|
|
17
|
+
|
|
18
|
+
rls_configuration_hash
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def admin_configuration_hash
|
|
22
|
+
@admin_configuration_hash ||= @configuration_hash
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def rls_configuration_hash
|
|
26
|
+
@rls_configuration_hash ||= @configuration_hash.deep_dup.tap do |config|
|
|
27
|
+
config[:username] = PgRls.username
|
|
28
|
+
config[:password] = PgRls.password
|
|
29
|
+
end.freeze
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -22,128 +22,105 @@ end
|
|
|
22
22
|
namespace :db do
|
|
23
23
|
include PgRls::Schema::UpStatements
|
|
24
24
|
|
|
25
|
-
def admin_connection
|
|
26
|
-
PgRls.as_db_admin = true
|
|
27
|
-
PgRls.establish_new_connection
|
|
28
|
-
|
|
29
|
-
yield
|
|
30
|
-
ensure
|
|
31
|
-
PgRls.as_db_admin = false
|
|
32
|
-
ActiveRecord::Base.connection.disconnect!
|
|
33
|
-
PgRls.establish_new_connection
|
|
34
|
-
end
|
|
35
|
-
|
|
36
25
|
override_task grant_usage: :load_config do
|
|
37
|
-
|
|
26
|
+
PgRls.admin_tasks_execute do
|
|
38
27
|
create_rls_user
|
|
39
28
|
end
|
|
40
29
|
end
|
|
41
30
|
|
|
42
31
|
override_task create: :load_config do
|
|
43
|
-
|
|
32
|
+
PgRls.admin_tasks_execute do
|
|
44
33
|
Rake::Task['db:create:original'].invoke
|
|
45
34
|
end
|
|
46
35
|
end
|
|
47
36
|
|
|
48
37
|
override_task drop: :load_config do
|
|
49
|
-
|
|
38
|
+
PgRls.admin_tasks_execute do
|
|
50
39
|
Rake::Task['db:drop:original'].invoke
|
|
51
40
|
end
|
|
52
41
|
end
|
|
53
42
|
|
|
54
43
|
override_task migrate: :load_config do
|
|
55
|
-
|
|
44
|
+
PgRls.admin_tasks_execute do
|
|
56
45
|
Rake::Task['db:migrate:original'].invoke
|
|
57
46
|
end
|
|
58
47
|
end
|
|
59
48
|
|
|
60
49
|
override_task rollback: :load_config do
|
|
61
|
-
|
|
50
|
+
PgRls.admin_tasks_execute do
|
|
62
51
|
Rake::Task['db:rollback:original'].invoke
|
|
63
52
|
end
|
|
64
53
|
end
|
|
65
54
|
|
|
66
55
|
override_task prepare: :load_config do
|
|
67
|
-
|
|
56
|
+
PgRls.admin_tasks_execute do
|
|
68
57
|
Rake::Task['db:prepare:original'].invoke
|
|
69
58
|
end
|
|
70
59
|
end
|
|
71
60
|
|
|
72
61
|
override_task setup: :load_config do
|
|
73
|
-
|
|
62
|
+
PgRls.admin_tasks_execute do
|
|
74
63
|
Rake::Task['db:setup:original'].invoke
|
|
75
64
|
end
|
|
76
65
|
end
|
|
77
66
|
|
|
78
67
|
override_task prepare: :load_config do
|
|
79
|
-
|
|
68
|
+
PgRls.admin_tasks_execute do
|
|
80
69
|
Rake::Task['db:reset:original'].invoke
|
|
81
70
|
end
|
|
82
71
|
end
|
|
83
72
|
|
|
84
73
|
override_task purge: :load_config do
|
|
85
|
-
|
|
74
|
+
PgRls.admin_tasks_execute do
|
|
86
75
|
Rake::Task['db:purge:original'].invoke
|
|
87
76
|
end
|
|
88
77
|
end
|
|
89
78
|
|
|
90
79
|
override_task abort_if_pending_migrations: :load_config do
|
|
91
|
-
|
|
80
|
+
PgRls.admin_tasks_execute do
|
|
92
81
|
Rake::Task['db:abort_if_pending_migrations:original'].invoke
|
|
93
82
|
end
|
|
94
83
|
end
|
|
95
84
|
|
|
96
85
|
namespace :test do
|
|
97
|
-
def admin_connection_test_db
|
|
98
|
-
Rails.env = 'test'
|
|
99
|
-
PgRls.as_db_admin = true
|
|
100
|
-
PgRls.establish_new_connection
|
|
101
|
-
|
|
102
|
-
yield
|
|
103
|
-
ensure
|
|
104
|
-
PgRls.as_db_admin = false
|
|
105
|
-
ActiveRecord::Base.connection.disconnect!
|
|
106
|
-
PgRls.establish_new_connection
|
|
107
|
-
end
|
|
108
|
-
|
|
109
86
|
override_task grant_usage: :load_config do
|
|
110
|
-
|
|
87
|
+
PgRls.admin_tasks_execute do
|
|
111
88
|
create_rls_user
|
|
112
89
|
end
|
|
113
90
|
end
|
|
114
91
|
|
|
115
92
|
override_task create: :load_config do
|
|
116
|
-
|
|
93
|
+
PgRls.admin_tasks_execute do
|
|
117
94
|
Rake::Task['db:test:create:original'].invoke
|
|
118
95
|
end
|
|
119
96
|
end
|
|
120
97
|
|
|
121
98
|
override_task drop: :load_config do
|
|
122
|
-
|
|
99
|
+
PgRls.admin_tasks_execute do
|
|
123
100
|
Rake::Task['db:test:drop:original'].invoke
|
|
124
101
|
end
|
|
125
102
|
end
|
|
126
103
|
|
|
127
104
|
override_task prepare: :load_config do
|
|
128
|
-
|
|
105
|
+
PgRls.admin_tasks_execute do
|
|
129
106
|
Rake::Task['db:test:prepare:original'].invoke
|
|
130
107
|
end
|
|
131
108
|
end
|
|
132
109
|
|
|
133
110
|
override_task setup: :load_config do
|
|
134
|
-
|
|
111
|
+
PgRls.admin_tasks_execute do
|
|
135
112
|
Rake::Task['db:test:setup:original'].invoke
|
|
136
113
|
end
|
|
137
114
|
end
|
|
138
115
|
|
|
139
116
|
override_task purge: :load_config do
|
|
140
|
-
|
|
117
|
+
PgRls.admin_tasks_execute do
|
|
141
118
|
Rake::Task['db:test:purge:original'].invoke
|
|
142
119
|
end
|
|
143
120
|
end
|
|
144
121
|
|
|
145
122
|
override_task load_schema: :load_config do
|
|
146
|
-
|
|
123
|
+
PgRls.admin_tasks_execute do
|
|
147
124
|
Rake::Task['db:test:load_schema:original'].invoke
|
|
148
125
|
end
|
|
149
126
|
end
|
|
@@ -151,7 +128,7 @@ namespace :db do
|
|
|
151
128
|
|
|
152
129
|
namespace :environment do
|
|
153
130
|
override_task set: :load_config do
|
|
154
|
-
|
|
131
|
+
PgRls.admin_tasks_execute do
|
|
155
132
|
Rake::Task['db:environment:set:original'].invoke
|
|
156
133
|
end
|
|
157
134
|
end
|
|
@@ -159,7 +136,7 @@ namespace :db do
|
|
|
159
136
|
|
|
160
137
|
namespace :schema do
|
|
161
138
|
override_task load: :load_config do
|
|
162
|
-
|
|
139
|
+
PgRls.admin_tasks_execute do
|
|
163
140
|
Rake::Task['db:schema:load:original'].invoke
|
|
164
141
|
Rake::Task['db:grant_usage'].invoke
|
|
165
142
|
Rake::Task['db:test:grant_usage'].invoke
|
|
@@ -167,7 +144,7 @@ namespace :db do
|
|
|
167
144
|
end
|
|
168
145
|
|
|
169
146
|
override_task dump: :load_config do
|
|
170
|
-
|
|
147
|
+
PgRls.admin_tasks_execute do
|
|
171
148
|
Rake::Task['db:schema:dump:original'].invoke
|
|
172
149
|
end
|
|
173
150
|
end
|
|
@@ -5,18 +5,10 @@ module PgRls
|
|
|
5
5
|
# Raise Tenant Not found and ensure that the tenant is resetted
|
|
6
6
|
class TenantNotFound < StandardError
|
|
7
7
|
def initialize(msg = nil)
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
PgRls::Tenant.reset_rls!
|
|
9
|
+
msg ||= "Tenant Doesn't exist"
|
|
10
10
|
super(msg)
|
|
11
11
|
end
|
|
12
|
-
|
|
13
|
-
def message
|
|
14
|
-
@msg || "Tenant Doesn't exist"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def reset_tenant_id
|
|
18
|
-
PgRls.connection_class.connection.execute('RESET rls.tenant_id')
|
|
19
|
-
end
|
|
20
12
|
end
|
|
21
13
|
end
|
|
22
14
|
end
|
|
@@ -7,9 +7,18 @@ module PgRls
|
|
|
7
7
|
# Set PgRls Policies
|
|
8
8
|
class Client
|
|
9
9
|
def call(_job_class, msg, _queue, _redis_pool)
|
|
10
|
-
msg
|
|
10
|
+
load_tenant_attribute!(msg)
|
|
11
11
|
yield
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
def load_tenant_attribute!(msg)
|
|
15
|
+
if PgRls.admin_connection?
|
|
16
|
+
msg['admin'] = true
|
|
17
|
+
else
|
|
18
|
+
tenant = PgRls::Tenant.fetch!
|
|
19
|
+
msg['pg_rls'] = tenant.id
|
|
20
|
+
end
|
|
21
|
+
end
|
|
13
22
|
end
|
|
14
23
|
end
|
|
15
24
|
end
|
|
@@ -7,7 +7,11 @@ module PgRls
|
|
|
7
7
|
# Set PgRls Policies
|
|
8
8
|
class Server
|
|
9
9
|
def call(_job_instance, msg, _queue, &)
|
|
10
|
-
|
|
10
|
+
if msg['admin']
|
|
11
|
+
PgRls.admin_execute(&)
|
|
12
|
+
else
|
|
13
|
+
PgRls::Tenant.with_tenant!(msg['pg_rls'], &)
|
|
14
|
+
end
|
|
11
15
|
end
|
|
12
16
|
end
|
|
13
17
|
end
|
data/lib/pg_rls/multi_tenancy.rb
CHANGED
|
@@ -16,13 +16,13 @@ module PgRls
|
|
|
16
16
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
|
-
def switch_tenant!
|
|
19
|
+
def switch_tenant!
|
|
20
20
|
fetched_tenant = session[:_tenant] || current_tenant
|
|
21
|
-
return
|
|
21
|
+
return yield if PgRls::Tenant.fetch.present?
|
|
22
22
|
|
|
23
23
|
Tenant.with_tenant!(fetched_tenant) do |tenant|
|
|
24
24
|
session[:_tenant] = tenant
|
|
25
|
-
|
|
25
|
+
yield(tenant)
|
|
26
26
|
end
|
|
27
27
|
rescue NoMethodError
|
|
28
28
|
session[:_tenant] = nil
|
|
@@ -32,7 +32,7 @@ module PgRls
|
|
|
32
32
|
def switch_tenant_by_resource!(resource = nil)
|
|
33
33
|
Tenant.switch!(resource)
|
|
34
34
|
session[:_tenant] = resource
|
|
35
|
-
rescue PgRls::Errors::TenantNotFound
|
|
35
|
+
rescue PgRls::Errors::TenantNotFound
|
|
36
36
|
Tenant.switch(session[:_tenant])
|
|
37
37
|
rescue NoMethodError
|
|
38
38
|
session[:tenant] = nil
|
|
@@ -5,7 +5,7 @@ module PgRls
|
|
|
5
5
|
# Down Schema Statements
|
|
6
6
|
module DownStatements
|
|
7
7
|
def drop_rls_user
|
|
8
|
-
ActiveRecord::Migration.execute <<~SQL
|
|
8
|
+
ActiveRecord::Migration.execute <<~SQL.squish
|
|
9
9
|
DROP OWNED BY #{PgRls.username};
|
|
10
10
|
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM #{PgRls.username};
|
|
11
11
|
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM #{PgRls.username};
|
|
@@ -23,28 +23,28 @@ module PgRls
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def detach_blocking_function(table_name)
|
|
26
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
26
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
27
27
|
DROP TRIGGER IF EXISTS id_safe_guard
|
|
28
28
|
ON #{table_name};
|
|
29
29
|
SQL
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def detach_trigger_function(table_name)
|
|
33
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
33
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
34
34
|
DROP TRIGGER IF EXISTS tenant_id_setter
|
|
35
35
|
ON #{table_name};
|
|
36
36
|
SQL
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def drop_rls_column(table_name)
|
|
40
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
40
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
41
41
|
ALTER TABLE #{table_name}
|
|
42
42
|
DROP COLUMN IF EXISTS tenant_id;
|
|
43
43
|
SQL
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def drop_rls_policy(table_name)
|
|
47
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
47
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
48
48
|
DROP POLICY #{table_name}_#{PgRls.username} ON #{table_name};
|
|
49
49
|
ALTER TABLE #{table_name} DISABLE ROW LEVEL SECURITY;
|
|
50
50
|
SQL
|
|
@@ -10,17 +10,17 @@ module PgRls
|
|
|
10
10
|
include UpStatements
|
|
11
11
|
include DownStatements
|
|
12
12
|
|
|
13
|
-
def create_rls_tenant_table(table_name,
|
|
13
|
+
def create_rls_tenant_table(table_name, **, &)
|
|
14
14
|
create_rls_user
|
|
15
15
|
create_rls_setter_function
|
|
16
16
|
create_rls_blocking_function
|
|
17
|
-
create_table(table_name,
|
|
17
|
+
create_table(table_name, **, &)
|
|
18
18
|
add_rls_column_to_tenant_table(table_name)
|
|
19
19
|
append_blocking_function(table_name)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def create_rls_table(table_name,
|
|
23
|
-
create_table(table_name,
|
|
22
|
+
def create_rls_table(table_name, **, &)
|
|
23
|
+
create_table(table_name, **, &)
|
|
24
24
|
add_rls_column(table_name)
|
|
25
25
|
create_rls_policy(table_name)
|
|
26
26
|
append_trigger_function(table_name)
|
|
@@ -5,7 +5,7 @@ module PgRls
|
|
|
5
5
|
# Up Schema Statements
|
|
6
6
|
module UpStatements
|
|
7
7
|
def create_rls_user(name: PgRls.username, password: PgRls.password, schema: 'public')
|
|
8
|
-
|
|
8
|
+
ActiveRecord::Migration.execute <<-SQL
|
|
9
9
|
DO
|
|
10
10
|
$do$
|
|
11
11
|
BEGIN
|
|
@@ -35,7 +35,7 @@ module PgRls
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def create_rls_blocking_function
|
|
38
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
38
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
39
39
|
CREATE OR REPLACE FUNCTION id_safe_guard ()
|
|
40
40
|
RETURNS TRIGGER LANGUAGE plpgsql AS $$
|
|
41
41
|
BEGIN
|
|
@@ -45,7 +45,7 @@ module PgRls
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def create_rls_setter_function
|
|
48
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
48
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
49
49
|
CREATE OR REPLACE FUNCTION tenant_id_setter ()
|
|
50
50
|
RETURNS TRIGGER LANGUAGE plpgsql AS $$
|
|
51
51
|
BEGIN
|
|
@@ -56,7 +56,7 @@ module PgRls
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def append_blocking_function(table_name)
|
|
59
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
59
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
60
60
|
CREATE TRIGGER id_safe_guard
|
|
61
61
|
BEFORE UPDATE OF id ON #{table_name}
|
|
62
62
|
FOR EACH ROW EXECUTE PROCEDURE id_safe_guard();
|
|
@@ -64,7 +64,7 @@ module PgRls
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def append_trigger_function(table_name)
|
|
67
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
67
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
68
68
|
CREATE TRIGGER tenant_id_setter
|
|
69
69
|
BEFORE INSERT OR UPDATE ON #{table_name}
|
|
70
70
|
FOR EACH ROW EXECUTE PROCEDURE tenant_id_setter();
|
|
@@ -72,7 +72,7 @@ module PgRls
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def add_rls_column_to_tenant_table(table_name)
|
|
75
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
75
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
76
76
|
ALTER TABLE #{table_name}
|
|
77
77
|
ADD COLUMN IF NOT EXISTS
|
|
78
78
|
tenant_id uuid UNIQUE DEFAULT gen_random_uuid();
|
|
@@ -80,7 +80,7 @@ module PgRls
|
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def add_rls_column(table_name)
|
|
83
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
83
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
84
84
|
ALTER TABLE #{table_name}
|
|
85
85
|
ADD COLUMN IF NOT EXISTS tenant_id uuid,
|
|
86
86
|
ADD CONSTRAINT fk_#{PgRls.table_name}
|
|
@@ -91,7 +91,7 @@ module PgRls
|
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
def create_rls_policy(table_name, user = PgRls.username)
|
|
94
|
-
ActiveRecord::Migration.execute <<-SQL
|
|
94
|
+
ActiveRecord::Migration.execute <<-SQL.squish
|
|
95
95
|
ALTER TABLE #{table_name} ENABLE ROW LEVEL SECURITY;
|
|
96
96
|
CREATE POLICY #{table_name}_#{user}
|
|
97
97
|
ON #{table_name}
|