pg_rls 0.0.1 → 0.0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4f0bd5f9878604a5f34c33b24221a9e7bb1efe25b526c825044dd7927f870f6
4
- data.tar.gz: 1e51d31dccc7b7787921775f856d96cb630bf006fe5108df8fb65aba6560cf98
3
+ metadata.gz: 00bc08507823f0659023716267357992118618dd2d69536cf1936f7ffa903961
4
+ data.tar.gz: 499004adf0eb1db60bba0e1899a08cc943c64f0e90495016b0acf1a322520731
5
5
  SHA512:
6
- metadata.gz: 86bafd3671e72de8a0f7fb84891c76530a28065dfb799b06de600bb0199a41cd8c22fed269e44076f79a05e2d874e63eeeb7f5728518d15ceddf89e6ff7bf824
7
- data.tar.gz: f99445e75de533cb9ef7acfc5215c14ca78d629bd65cef1cb497f3adc1ae43f8689d46bcf7dcab8a5ac7684b79290630841ef33142434366800af9cf94e448d2
6
+ metadata.gz: e9ed07f6dfb3477c100eebc4afc2fd72fd639637fc200dd4ce6130e2cbdcb9fb3c6b9c4e5b3955397eb3bd08811542e0c96b954497110d148f048ef8f2583bed
7
+ data.tar.gz: 04d74bc577004804a4a5cb039f48dfb32b1bdc8b018aee47729202e6c58bfb7711698b789dfdb575ae715e50c4f78f5a36516841176169481b64bbeafd071dc1
data/README.md CHANGED
@@ -4,28 +4,23 @@
4
4
  [![Issues][issues-shield]][issues-url]
5
5
  [![LinkedIn][linkedin-shield2]][linkedin-url2]
6
6
  [![Hireable][hireable]][hireable-url]
7
+ [![Donate][donate]][paypal-donate-code]
7
8
 
8
9
  <!-- PROJECT LOGO -->
9
10
  <br />
10
11
  <p align="center">
11
- <h1 align="center">PgRls</h1>
12
- <h2 align="center"> PostgreSQL Row Level Security </h2>
13
- <h1 align="center"></h1>
12
+ <h1 align="center">PgRls<h2 align="center">PostgreSQL Row Level Security<br />The Rails right way to do multitenancy</h2></h1>
14
13
 
15
14
  <p align="center">
16
15
  <br />
17
- <a href="https://github.com/Dandush03/pg_rls"><strong>Explore the docs »</strong></a>
16
+ <a href="https://github.com/Dandush03/pg_rls/wiki"><strong>Explore the docs »</strong></a>
18
17
  <br />
19
18
  <br />
20
- <a href="https://dl-final-webapp.herokuapp.com/">View Live Demo</a>
21
- ·
22
19
  <a href="https://github.com/Dandush03/pg_rls/issues">Report Bug</a>
23
20
  ·
24
21
  <a href="https://github.com/Dandush03/pg_rls/issues">Request Feature</a>
25
22
  ·
26
23
  <a href="https://github.com/Dandush03/pg_rls">API Repo</a>
27
- ·
28
- <a href="https://github.com/Dandush03/pg_rls">WebApp Repo</a>
29
24
  </p>
30
25
 
31
26
  </p>
@@ -34,6 +29,7 @@
34
29
  * [Required Installations](#required-Installations)
35
30
  * [Installing](#installing)
36
31
  * [Instructions](#instructions)
32
+ * [Testing](#Testing)
37
33
  * [Development](#testing)
38
34
  * [Contact](#contact)
39
35
  * [Contributing](#contributing)
@@ -41,9 +37,11 @@
41
37
  * [Code of Conduct](#Code-of-Conduct)
42
38
  * [Show your support](#Show-your-support)
43
39
 
44
- This gem will help you to integrate PostgreSQL RLS to help you develop an easy multitenancy application
40
+ ### It's time we start doing multitenancy right! You can avoid creating a separate Postgres schema/databases for each customer or trying to ensure the WHERE clause of every single query includes the particular company. Just integrate PgRls seamlessly to your application.
41
+
42
+ ### This gem will integrate PostgreSQL RLS to help you develop a great multitenancy application.
45
43
 
46
- ## Required Installations
44
+ ## Required Installation
47
45
  ### Installing
48
46
 
49
47
  Add this line to your application's Gemfile:
@@ -56,31 +54,51 @@ And then execute:
56
54
 
57
55
  $ bundle install
58
56
 
59
- Or install it yourself as:
57
+ Or install it yourself with:
60
58
 
61
59
  $ gem install pg_rls
62
60
 
63
61
  ### Instructions
64
62
 
65
63
  ```bash
66
- rails generate pg_rls:install company #=> where app eq tenant model name
64
+ rails generate pg_rls:install company #=> where company eq tenant model name
67
65
  ```
68
- You can change company to anything you'd like like for example `tenant`
69
- this will generate the model and inject all the required code
66
+ You can change company to anything you'd like, for example, `tenant`
67
+ This will generate the model and inject all the required code
70
68
 
71
- for any new model that required to be under rls you can generate it by writing
69
+ For any new model that needs to be under rls, you can generate it by writing
72
70
 
73
71
  ```bash
74
- rails generate pg_rls user #=> where app eq model name
72
+ rails generate pg_rls user #=> where user eq model name
75
73
  ```
76
- and it will generate all the necesary information for you
74
+ and it will generate all the necesary information for you.
77
75
 
78
- you can swtich tenant by using
76
+ You can swtich to another tenant by using
79
77
  ```ruby
80
- PgRls::Tenant::switch :app #=> where app eq tenant name
78
+ PgRls::Tenant.switch :app #=> where app eq tenant name
81
79
  ```
80
+ Don't forget to update how you want `PgRls` to find your tenant, you can set multiple options by modifying `api/config/initializers/pg_rls.rb` `search_methods`
81
+ ### Testing
82
+
83
+ Many application uses some sort of database cleaner before running thair spec so on each test that we run we'll have an empty state. Usually, those gems clear our user configuration for the database. To solve this issue, we must implement the following:
84
+
85
+ ```ruby
86
+ # spec/rails_helper.rb
82
87
 
83
- enjoy the gem :)
88
+ ...
89
+ # some database cleaning strategy
90
+
91
+ config.before(:suite) do
92
+ # Create A Default Tenant and Grant Test User Credentials
93
+ PgRls::Database::Prepared.grant_user_credentials
94
+ # Create the tenant which in this example is company and we are using FactoryBot
95
+ FactoryBot.create(:company, subdomain: 'app')
96
+ # In this default case our initializer is set to search by subdomain so will use it
97
+ PgRls::Tenant.switch :app
98
+ end
99
+
100
+ ...
101
+ ```
84
102
  ## Development
85
103
 
86
104
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -100,12 +118,16 @@ The gem is available as open source under the terms of the [MIT License](https:/
100
118
  Everyone interacting in the PgRls project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/dandush03/pg_rls/blob/master/CODE_OF_CONDUCT.md).
101
119
 
102
120
  ## Note
103
- Currently we only support subdomain as a searcher but soon will integrate slug/domain and cookies support
121
+ Currently we only support subdomain as a searcher but will soon integrate slug/domain and cookies support
104
122
 
105
123
  ## Show your support
106
124
 
107
125
  Give a ⭐️ if you like this project!
108
126
 
127
+ If this project help you reduce time to develop, you can give me a cup of coffee :)
128
+
129
+ [![paypal][paypal-url]][paypal-donate-code]
130
+
109
131
  <!-- MARKDOWN LINKS & IMAGES -->
110
132
  [contributors-shield]: https://img.shields.io/github/contributors/Dandush03/React-Calculator.svg?style=flat-square
111
133
  [contributors-url]: https://github.com/Dandush03/pg_rls/graphs/contributors
@@ -120,4 +142,7 @@ Give a ⭐️ if you like this project!
120
142
  [linkedin-shield2]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555
121
143
  [linkedin-url2]: https://www.linkedin.com/in/daniel-laloush/
122
144
  [hireable]: https://cdn.rawgit.com/hiendv/hireable/master/styles/flat/yes.svg
145
+ [paypal-url]: https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif
146
+ [paypal-donate-code]: https://www.paypal.com/donate?hosted_button_id=QKZFZAMQNC8JL
123
147
  [hireable-url]: https://www.linkedin.com/in/daniel-laloush/
148
+ [donate]: https://img.shields.io/badge/Donate-PayPal-blue.svg
@@ -11,34 +11,86 @@ module PgRls
11
11
 
12
12
  source_root File.expand_path('./templates', __dir__)
13
13
 
14
- def create_migration_file
15
- migration_template migration_template_path, "#{migration_path}/#{file_sub_name}_#{table_name}.rb",
14
+ def check_class_collision; end
15
+
16
+ def create_migration_file; end
17
+
18
+ def migration_exist?
19
+ @migration_exist ||= Dir.glob("#{migration_path}/*create_#{table_name}.rb").present?
20
+ end
21
+
22
+ def create_tenant_migration_file
23
+ return if migration_exist?
24
+
25
+ migration_template create_migration_template_path,
26
+ "#{migration_path}/#{create_file_sub_name}_#{table_name}.rb",
27
+ migration_version: migration_version
28
+ end
29
+
30
+ def convert_tenant_migration_file
31
+ return unless migration_exist?
32
+
33
+ migration_template convert_migration_template_path,
34
+ "#{migration_path}/#{convert_file_sub_name}_#{table_name}.rb",
35
+ migration_version: migration_version
36
+
37
+ return if installation_in_progress?
38
+
39
+ migration_template 'convert_migration_backport.rb.tt',
40
+ "#{migration_path}/pg_rls_backport_#{table_name}.rb",
16
41
  migration_version: migration_version
17
42
  end
18
43
 
19
44
  def create_model_file
45
+ return if migration_exist?
46
+
20
47
  generate_abstract_class if database && !parent
21
- template model_template_path, File.join('app/models', class_path, "#{file_name}.rb")
48
+
49
+ template model_template_path, model_file
50
+ end
51
+
52
+ def inject_method_to_model
53
+ return unless installation_in_progress?
54
+
55
+ gsub_file(model_file, /Class #{class_name} < #{parent_class_name.classify}/mi) do |match|
56
+ "#{match}\n def self.current\n PgRls::Tenant.fetch\n end\n"
57
+ end
58
+ end
59
+
60
+ def model_file
61
+ File.join('app/models', class_path, "#{file_name}.rb")
22
62
  end
23
63
 
24
- def migration_template_path
64
+ def create_migration_template_path
25
65
  return 'init_migration.rb.tt' if installation_in_progress?
26
66
 
27
67
  'migration.rb.tt'
28
68
  end
29
69
 
70
+ def convert_migration_template_path
71
+ return 'init_convert_migration.rb.tt' if installation_in_progress?
72
+
73
+ 'convert_migration.rb.tt'
74
+ end
75
+
30
76
  def model_template_path
31
77
  return 'init_model.rb.tt' if installation_in_progress?
32
78
 
33
79
  'model.rb.tt'
34
80
  end
35
81
 
36
- def file_sub_name
37
- return 'pg_rls_tenant_create' if installation_in_progress?
82
+ def create_file_sub_name
83
+ return 'pg_rls_create_tenant' if installation_in_progress?
38
84
 
39
85
  'pg_rls_create'
40
86
  end
41
87
 
88
+ def convert_file_sub_name
89
+ return 'pg_rls_convert_tenant' if installation_in_progress?
90
+
91
+ 'pg_rls_convert'
92
+ end
93
+
42
94
  def installation_in_progress?
43
95
  shell.base.class.name.include?('Install')
44
96
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PgRlsConvert<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
+ def up
5
+ convert_to_rls_table :<%= table_name %>
6
+ end
7
+
8
+ def down
9
+ revert_rls_table :<%= table_name %>
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PgRlsBackport<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
+ def up
5
+ PgRls.establish_default_connection
6
+
7
+ # Suggested Code:
8
+ # PgRls.all_tenants do |tenant|
9
+ # tenant.<%= table_name %>.in_batches(of: 100) do |<%= table_name %>|
10
+ # <%= table_name %>.each { |<%= table_name.singularize %>| <%= table_name.singularize %>.update_attribute('tenant_id', tenant.tenant_id) }
11
+ # end
12
+ # end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PgRlsConvertTenant<%= PgRls.table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
+ def up
5
+ convert_to_rls_tenant_table :<%= table_name %>
6
+ end
7
+
8
+ def down
9
+ revert_rls_tenant_table :<%= table_name %>
10
+ end
11
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class PgRlsTenantCreate<%= PgRls.table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
3
+ class PgRlsCreateTenant<%= PgRls.table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
4
  def up
5
5
  create_rls_tenant_table :<%= table_name %>, id: :uuid do |t|
6
6
  t.string :name
@@ -8,4 +8,5 @@ PgRls.setup do |config|
8
8
  # Do not remove this value after initialization
9
9
  config.class_name = :<%= PgRls.class_name %>
10
10
  config.table_name = :<%= PgRls.table_name %>
11
+ config.search_methods = <%= PgRls.search_methods %>
11
12
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgRls
4
+ module Database
5
+ # Prepare database for test unit
6
+ module Prepared
7
+ class << self
8
+ def grant_user_credentials(name: PgRls::SECURE_USERNAME)
9
+ return unless Rails.env.test?
10
+
11
+ PgRls.execute <<-SQL
12
+ GRANT USAGE, SELECT
13
+ ON ALL SEQUENCES IN SCHEMA public
14
+ TO #{name};
15
+ GRANT SELECT, INSERT, UPDATE, DELETE
16
+ ON ALL TABLES IN SCHEMA public
17
+ TO #{name};
18
+ SQL
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -5,7 +5,13 @@ module PgRls
5
5
  # Down Schema Statements
6
6
  module DownStatements
7
7
  def drop_rls_user
8
- ActiveRecord::Migration.execute "DROP USER #{PgRls::SECURE_USERNAME};"
8
+ ActiveRecord::Migration.execute <<~SQL
9
+ DROP OWNED BY #{PgRls::SECURE_USERNAME};
10
+ REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM #{PgRls::SECURE_USERNAME};
11
+ REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM #{PgRls::SECURE_USERNAME};
12
+ REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM #{PgRls::SECURE_USERNAME};
13
+ DROP USER #{PgRls::SECURE_USERNAME};
14
+ SQL
9
15
  end
10
16
 
11
17
  def drop_rls_blocking_function
@@ -27,11 +27,11 @@ module PgRls
27
27
  end
28
28
 
29
29
  def drop_rls_tenant_table(table_name)
30
- drop_rls_user
31
30
  drop_rls_setter_function
32
31
  detach_blocking_function(table_name)
33
32
  drop_table(table_name)
34
33
  drop_rls_blocking_function
34
+ drop_rls_user
35
35
  end
36
36
 
37
37
  def drop_rls_table(table_name)
@@ -39,6 +39,34 @@ module PgRls
39
39
  drop_rls_policy(table_name)
40
40
  drop_table(table_name)
41
41
  end
42
+
43
+ def convert_to_rls_tenant_table(table_name, **_options)
44
+ create_rls_user(password: PgRls.database_configuration['password'])
45
+ create_rls_setter_function
46
+ create_rls_blocking_function
47
+ add_rls_column_to_tenant_table(table_name)
48
+ append_blocking_function(table_name)
49
+ end
50
+
51
+ def revert_rls_tenant_table(table_name)
52
+ drop_rls_setter_function
53
+ detach_blocking_function(table_name)
54
+ drop_rls_blocking_function
55
+ drop_rls_user
56
+ drop_rls_column(table_name)
57
+ end
58
+
59
+ def convert_to_rls_table(table_name)
60
+ add_rls_column(table_name)
61
+ create_rls_policy(table_name)
62
+ append_trigger_function(table_name)
63
+ end
64
+
65
+ def revert_rls_table(table_name)
66
+ detach_trigger_function(table_name)
67
+ drop_rls_policy(table_name)
68
+ drop_rls_column(table_name)
69
+ end
42
70
  end
43
71
  end
44
72
  end
@@ -9,9 +9,16 @@ module PgRls
9
9
  DROP ROLE IF EXISTS #{name};
10
10
  CREATE USER #{name} WITH PASSWORD '#{password}';
11
11
  GRANT ALL PRIVILEGES ON TABLE schema_migrations TO #{name};
12
+ GRANT USAGE ON SCHEMA public TO #{name};
12
13
  ALTER DEFAULT PRIVILEGES IN SCHEMA public
13
14
  GRANT SELECT, INSERT, UPDATE, DELETE
14
15
  ON TABLES TO #{name};
16
+ GRANT SELECT, INSERT, UPDATE, DELETE
17
+ ON ALL TABLES IN SCHEMA public
18
+ TO #{name};
19
+ GRANT USAGE, SELECT
20
+ ON ALL SEQUENCES IN SCHEMA public
21
+ TO #{name};
15
22
  SQL
16
23
  end
17
24
 
@@ -12,6 +12,8 @@ module PgRls
12
12
  private
13
13
 
14
14
  def establish_secure_connection
15
+ return if PgRls.default_connection?
16
+
15
17
  return if secure_connection_established?
16
18
 
17
19
  PgRls.establish_new_connection
data/lib/pg_rls/tenant.rb CHANGED
@@ -6,21 +6,19 @@ module PgRls
6
6
  class << self
7
7
  def switch(resource)
8
8
  connection_adapter = PgRls.connection_class
9
- tenant = tenant_by_subdomain_uuid_or_tenant_id(resource)
9
+ find_tenant(resource)
10
10
  connection_adapter.connection.execute(format('SET rls.tenant_id = %s',
11
11
  connection_adapter.connection.quote(tenant.tenant_id)))
12
12
  "RLS changed to '#{tenant.name}'"
13
13
  rescue StandardError => e
14
14
  puts 'connection was not made'
15
- puts e
15
+ puts @error || e
16
16
  end
17
17
 
18
- def tenant
19
- PgRls.class_name.to_s.camelize.constantize
20
- end
18
+ attr_reader :tenant
21
19
 
22
20
  def fetch
23
- tenant.find_by_tenant_id(
21
+ @fetch ||= tenant.find_by_tenant_id(
24
22
  PgRls.connection_class.connection.execute(
25
23
  "SELECT current_setting('rls.tenant_id')"
26
24
  ).getvalue(0, 0)
@@ -29,8 +27,14 @@ module PgRls
29
27
  'no tenant is selected'
30
28
  end
31
29
 
32
- def tenant_by_subdomain_uuid_or_tenant_id(resource)
33
- tenant.find_by_subdomain(resource) || tenant.find_by_id(resource) || tenant.find_by_tenant_id(resource)
30
+ def find_tenant(resource)
31
+ @tenant = nil
32
+
33
+ PgRls.search_methods.each do |method|
34
+ @tenant ||= PgRls.main_model.send("find_by_#{method}", resource)
35
+ rescue NoMethodError => e
36
+ @error = e
37
+ end
34
38
  end
35
39
  end
36
40
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRls
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.1.4'
5
5
  end
data/lib/pg_rls.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'active_record'
4
4
  require 'forwardable'
5
5
  require_relative 'pg_rls/version'
6
+ require_relative 'pg_rls/database/prepared'
6
7
  require_relative 'pg_rls/schema/statements'
7
8
  require_relative 'pg_rls/tenant'
8
9
  require_relative 'pg_rls/secure_connection'
@@ -11,17 +12,18 @@ require_relative 'pg_rls/multi_tenancy'
11
12
  # PostgreSQL Row Level Security
12
13
  module PgRls
13
14
  class Error < StandardError; end
14
- SECURE_USERNAME = 'app_user'
15
+ SECURE_USERNAME = "#{Rails.env}_app_user".freeze
15
16
 
16
17
  class << self
17
18
  extend Forwardable
18
19
 
19
- WRITER_METHODS = %i[table_name class_name].freeze
20
+ WRITER_METHODS = %i[table_name class_name search_methods].freeze
20
21
  READER_METHODS = %i[
21
- connection_class database_configuration execute table_name class_name
22
+ connection_class database_configuration execute table_name class_name search_methods
22
23
  ].freeze
23
24
  DELEGATORS_METHODS = %i[
24
- connection_class database_configuration execute table_name class_name
25
+ connection_class database_configuration execute table_name search_methods
26
+ class_name all_tenants main_model establish_default_connection
25
27
  ].freeze
26
28
 
27
29
  attr_writer(*WRITER_METHODS)
@@ -49,8 +51,29 @@ module PgRls
49
51
  )
50
52
  end
51
53
 
54
+ def establish_default_connection
55
+ @default_connection = true
56
+ end
57
+
58
+ def default_connection?
59
+ @default_connection
60
+ end
61
+
62
+ def main_model
63
+ class_name.to_s.camelize.constantize
64
+ end
65
+
66
+ def all_tenants
67
+ main_model.all.each do |tenant|
68
+ allowed_search_fields = search_methods.map(&:to_s).intersection(main_model.column_names)
69
+ Tenant.switch tenant.send(allowed_search_fields.first)
70
+
71
+ yield(tenant) if block_given?
72
+ end
73
+ end
74
+
52
75
  def current_connection_username
53
- PgRls.connection_class.connection_db_config.configuration_hash[:username]
76
+ connection_class.connection_db_config.configuration_hash[:username]
54
77
  end
55
78
 
56
79
  def execute(query)
@@ -68,4 +91,7 @@ module PgRls
68
91
 
69
92
  mattr_accessor :class_name
70
93
  @@class_name = 'Company'
94
+
95
+ mattr_accessor :search_methods
96
+ @@search_methods = %i[subdomain id tenant_id]
71
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_rls
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Laloush
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-11 00:00:00.000000000 Z
11
+ date: 2022-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,7 +24,9 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.2.10
27
- description: Write a longer description or delete this line.
27
+ description: |2
28
+ This gem will help you to integrate PostgreSQL RLS to help you develop a great multitenancy application
29
+ checkout the repository at https://github.com/Dandush03/pg_rls
28
30
  email:
29
31
  - daniel.laloush@influitive.com
30
32
  executables: []
@@ -45,6 +47,9 @@ files:
45
47
  - lib/generators/pg_rls.rb
46
48
  - lib/generators/pg_rls/active_record/active_record_generator.rb
47
49
  - lib/generators/pg_rls/active_record/templates/abstract_base_class.rb.tt
50
+ - lib/generators/pg_rls/active_record/templates/convert_migration.rb.tt
51
+ - lib/generators/pg_rls/active_record/templates/convert_migration_backport.rb.tt
52
+ - lib/generators/pg_rls/active_record/templates/init_convert_migration.rb.tt
48
53
  - lib/generators/pg_rls/active_record/templates/init_migration.rb.tt
49
54
  - lib/generators/pg_rls/active_record/templates/init_model.rb.tt
50
55
  - lib/generators/pg_rls/active_record/templates/migration.rb.tt
@@ -55,6 +60,7 @@ files:
55
60
  - lib/generators/templates/README
56
61
  - lib/generators/templates/pg_rls.rb.tt
57
62
  - lib/pg_rls.rb
63
+ - lib/pg_rls/database/prepared.rb
58
64
  - lib/pg_rls/multi_tenancy.rb
59
65
  - lib/pg_rls/schema/down_statements.rb
60
66
  - lib/pg_rls/schema/statements.rb
@@ -65,7 +71,8 @@ files:
65
71
  homepage: https://github.com/Dandush03/pg_rls
66
72
  licenses:
67
73
  - MIT
68
- metadata: {}
74
+ metadata:
75
+ rubygems_mfa_required: 'true'
69
76
  post_install_message:
70
77
  rdoc_options: []
71
78
  require_paths:
@@ -81,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
88
  - !ruby/object:Gem::Version
82
89
  version: '0'
83
90
  requirements: []
84
- rubygems_version: 3.2.27
91
+ rubygems_version: 3.2.22
85
92
  signing_key:
86
93
  specification_version: 4
87
94
  summary: Write a short summary, because RubyGems requires one.