pg_rls 0.0.1.4 → 0.0.1.4.1

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: 00bc08507823f0659023716267357992118618dd2d69536cf1936f7ffa903961
4
- data.tar.gz: 499004adf0eb1db60bba0e1899a08cc943c64f0e90495016b0acf1a322520731
3
+ metadata.gz: fa0740a77d93fc9f87723797b3bca421e957a5661e4f82211762e21e9a29e53e
4
+ data.tar.gz: 47c18a7af64db89155056eaa370131134581f56769730865bf4c9e7781208ca2
5
5
  SHA512:
6
- metadata.gz: e9ed07f6dfb3477c100eebc4afc2fd72fd639637fc200dd4ce6130e2cbdcb9fb3c6b9c4e5b3955397eb3bd08811542e0c96b954497110d148f048ef8f2583bed
7
- data.tar.gz: 04d74bc577004804a4a5cb039f48dfb32b1bdc8b018aee47729202e6c58bfb7711698b789dfdb575ae715e50c4f78f5a36516841176169481b64bbeafd071dc1
6
+ metadata.gz: c0cfdbfb358da830cabf1fae1406e52d208960331f9a871aef2829a9c18d7d5f31d0e6aa5c0d96942148bb6c64060faa875ec11dfe8dd0d9e2da4d14e41637b0
7
+ data.tar.gz: f420cf2bfc326cc3b8404f5059a9e1e6b398c377319939d196539be4e2aa4c43d88d27dfd579ca0ceea71cded49a78956687798a88b788a39c5076f2de88f970
data/README.md CHANGED
@@ -1,3 +1,10 @@
1
+ <!--
2
+ Title: PgRls Rails
3
+ Description: rails multitenancy with pg rls
4
+ Author: dandush03
5
+ -->
6
+ <meta name="google-site-verification" content="Mc1vBv8PRYPw_cdd3EiKhF2vlOeIEIk3VYhAg75ertI" />
7
+
1
8
  [![Contributors][contributors-shield]][contributors-url]
2
9
  [![Forks][forks-shield]][forks-url]
3
10
  [![Stargazers][stars-shield]][stars-url]
@@ -77,7 +84,28 @@ You can swtich to another tenant by using
77
84
  ```ruby
78
85
  PgRls::Tenant.switch :app #=> where app eq tenant name
79
86
  ```
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`
87
+ 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`
88
+
89
+ You can add the following configuration to your Database Config File to improve performance and remove `PgRls::SecureConnection` from `aplication_record.rb`
90
+
91
+ ```yml
92
+ # app/config/database.yml
93
+ <% def db_username
94
+ return PgRls::SECURE_USERNAME unless ENV['AS_DB_ADMIN']
95
+
96
+ Rails.application.credentials.dig(:database, :server_1, :username)
97
+ end %>
98
+
99
+ ...
100
+
101
+ development:
102
+ <<: *default
103
+ database: example_development
104
+ username: <%= db_username %> # Apply this to production and all env including tests
105
+
106
+ ...
107
+
108
+ ```
81
109
  ### Testing
82
110
 
83
111
  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:
@@ -2,8 +2,6 @@
2
2
 
3
3
  class PgRlsBackport<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
4
  def up
5
- PgRls.establish_default_connection
6
-
7
5
  # Suggested Code:
8
6
  # PgRls.all_tenants do |tenant|
9
7
  # tenant.<%= table_name %>.in_batches(of: 100) do |<%= table_name %>|
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../pg_rls'
4
+
5
+ path = File.expand_path(__dir__)
6
+ Dir.glob("#{path}/database/tasks/**/*.rake").each { |f| import f }
@@ -5,16 +5,31 @@ module PgRls
5
5
  # Prepare database for test unit
6
6
  module Prepared
7
7
  class << self
8
- def grant_user_credentials(name: PgRls::SECURE_USERNAME)
9
- return unless Rails.env.test?
8
+ def grant_user_credentials(name: PgRls::SECURE_USERNAME, password: 'password')
9
+ return unless Rails.env.test? || PgRls.default_connection?
10
10
 
11
- PgRls.execute <<-SQL
12
- GRANT USAGE, SELECT
13
- ON ALL SEQUENCES IN SCHEMA public
14
- TO #{name};
11
+ PgRls.admin_execute <<-SQL
12
+ DO
13
+ $do$
14
+ BEGIN
15
+ IF NOT EXISTS (
16
+ SELECT FROM pg_catalog.pg_roles AS r
17
+ WHERE r.rolname = '#{name}') THEN
18
+
19
+ CREATE USER #{name} WITH PASSWORD '#{password}';
20
+ END IF;
21
+ END
22
+ $do$;
23
+ GRANT USAGE ON SCHEMA public TO #{name};
24
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
25
+ GRANT SELECT, INSERT, UPDATE, DELETE
26
+ ON TABLES TO #{name};
15
27
  GRANT SELECT, INSERT, UPDATE, DELETE
16
28
  ON ALL TABLES IN SCHEMA public
17
- TO #{name};
29
+ TO #{name};
30
+ GRANT USAGE, SELECT
31
+ ON ALL SEQUENCES IN SCHEMA public
32
+ TO #{name};
18
33
  SQL
19
34
  end
20
35
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # OVERIDE RAILS TASK
4
+ Rake::TaskManager.class_eval do
5
+ def alias_task(fq_name)
6
+ new_name = "#{fq_name}:original"
7
+ @tasks[new_name] = @tasks.delete(fq_name)
8
+ end
9
+ end
10
+
11
+ def alias_task(fq_name)
12
+ Rake.application.alias_task(fq_name)
13
+ end
14
+
15
+ def override_task(*args, &block)
16
+ name, _params, _deps = Rake.application.resolve_args(args.dup)
17
+ fq_name = Rake.application.instance_variable_get(:@scope).to_a.reverse.push(name).join(':')
18
+ alias_task(fq_name)
19
+ Rake::Task.define_task(*args, &block)
20
+ end
21
+
22
+ namespace :db do
23
+ override_task create: :load_config do
24
+ system('AS_DB_ADMIN=true rake db:create:original')
25
+ end
26
+
27
+ override_task drop: :load_config do
28
+ system('AS_DB_ADMIN=true rake db:drop:original')
29
+ end
30
+
31
+ override_task migrate: :load_config do
32
+ system('AS_DB_ADMIN=true rake db:migrate:original')
33
+ end
34
+
35
+ override_task rollback: :load_config do
36
+ system('AS_DB_ADMIN=true rake db:rollback:original')
37
+ end
38
+
39
+ override_task prepare: :load_config do
40
+ system('AS_DB_ADMIN=true rake db:prepare:original')
41
+ end
42
+
43
+ override_task setup: :load_config do
44
+ system('AS_DB_ADMIN=true rake db:setup:original')
45
+ end
46
+
47
+ override_task prepare: :load_config do
48
+ system('AS_DB_ADMIN=true rake db:reset:original')
49
+ end
50
+
51
+ override_task purge: :load_config do
52
+ system('AS_DB_ADMIN=true rake db:purge:original')
53
+ end
54
+
55
+ override_task abort_if_pending_migrations: :load_config do
56
+ system('AS_DB_ADMIN=true rake db:abort_if_pending_migrations:original')
57
+ end
58
+
59
+ override_task seed: :load_config do
60
+ system('AS_DB_ADMIN=true rake db:seed:original')
61
+ end
62
+
63
+ namespace :test do
64
+ override_task create: :load_config do
65
+ system('AS_DB_ADMIN=true rake db:test:create:original')
66
+ end
67
+
68
+ override_task drop: :load_config do
69
+ system('AS_DB_ADMIN=true rake db:test:drop:original')
70
+ end
71
+
72
+ override_task prepare: :load_config do
73
+ system('AS_DB_ADMIN=true rake db:test:prepare:original')
74
+ end
75
+
76
+ override_task setup: :load_config do
77
+ system('AS_DB_ADMIN=true rake db:test:setup:original')
78
+ end
79
+
80
+ override_task purge: :load_config do
81
+ system('AS_DB_ADMIN=true rake db:test:purge:original')
82
+ end
83
+
84
+ override_task load_schema: :load_config do
85
+ system('AS_DB_ADMIN=true rake db:test:load_schema:original')
86
+ end
87
+ end
88
+
89
+ namespace :enviroment do
90
+ override_task set: :load_config do
91
+ system('AS_DB_ADMIN=true rake db:enviroment:set:original')
92
+ end
93
+ end
94
+
95
+ namespace :schema do
96
+ override_task load: :load_config do
97
+ system('AS_DB_ADMIN=true rake db:schema:load:original')
98
+ PgRls.admin_execute do
99
+ PgRls.execute <<-SQL
100
+ DROP ROLE IF EXISTS #{PgRls::SECURE_USERNAME};
101
+ CREATE USER #{PgRls::SECURE_USERNAME} WITH PASSWORD '#{PgRls.database_configuration['password']}';
102
+ GRANT ALL PRIVILEGES ON TABLE schema_migrations TO #{PgRls::SECURE_USERNAME};
103
+ GRANT USAGE ON SCHEMA public TO #{PgRls::SECURE_USERNAME};
104
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
105
+ GRANT SELECT, INSERT, UPDATE, DELETE
106
+ ON TABLES TO #{PgRls::SECURE_USERNAME};
107
+ GRANT SELECT, INSERT, UPDATE, DELETE
108
+ ON ALL TABLES IN SCHEMA public
109
+ TO #{PgRls::SECURE_USERNAME};
110
+ GRANT USAGE, SELECT
111
+ ON ALL SEQUENCES IN SCHEMA public
112
+ TO #{PgRls::SECURE_USERNAME};
113
+ SQL
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../pg_rls'
4
+ require 'rails'
5
+
6
+ module PgRls
7
+ # Extend Rails Railties
8
+ class Railtie < Rails::Railtie
9
+ railtie_name :my_gem
10
+
11
+ rake_tasks do
12
+ path = File.dirname(__FILE__)
13
+ Dir.glob("#{path}/database/tasks/**/*.rake").each { |f| load f }
14
+ end
15
+ end
16
+ end
data/lib/pg_rls/tenant.rb CHANGED
@@ -9,7 +9,7 @@ module PgRls
9
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
- "RLS changed to '#{tenant.name}'"
12
+ "RLS changed to '#{tenant.send(@method)}'"
13
13
  rescue StandardError => e
14
14
  puts 'connection was not made'
15
15
  puts @error || e
@@ -31,6 +31,7 @@ module PgRls
31
31
  @tenant = nil
32
32
 
33
33
  PgRls.search_methods.each do |method|
34
+ @method = method
34
35
  @tenant ||= PgRls.main_model.send("find_by_#{method}", resource)
35
36
  rescue NoMethodError => e
36
37
  @error = e
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRls
4
- VERSION = '0.0.1.4'
4
+ VERSION = '0.0.1.4.1'
5
5
  end
data/lib/pg_rls.rb CHANGED
@@ -8,6 +8,7 @@ require_relative 'pg_rls/schema/statements'
8
8
  require_relative 'pg_rls/tenant'
9
9
  require_relative 'pg_rls/secure_connection'
10
10
  require_relative 'pg_rls/multi_tenancy'
11
+ require_relative 'pg_rls/railtie' if defined?(Rails)
11
12
 
12
13
  # PostgreSQL Row Level Security
13
14
  module PgRls
@@ -17,9 +18,9 @@ module PgRls
17
18
  class << self
18
19
  extend Forwardable
19
20
 
20
- WRITER_METHODS = %i[table_name class_name search_methods].freeze
21
+ WRITER_METHODS = %i[table_name class_name search_methods establish_default_connection].freeze
21
22
  READER_METHODS = %i[
22
- connection_class database_configuration execute table_name class_name search_methods
23
+ connection_class database_configuration execute table_name class_name search_methods establish_default_connection
23
24
  ].freeze
24
25
  DELEGATORS_METHODS = %i[
25
26
  connection_class database_configuration execute table_name search_methods
@@ -51,8 +52,20 @@ module PgRls
51
52
  )
52
53
  end
53
54
 
54
- def establish_default_connection
55
- @default_connection = true
55
+ def admin_execute(query = nil)
56
+ self.establish_default_connection = true
57
+ establish_new_connection
58
+ return yield if block_given?
59
+
60
+ execute(query)
61
+ ensure
62
+ self.establish_default_connection = false
63
+ establish_new_connection
64
+ end
65
+
66
+ def establish_default_connection=(value)
67
+ ENV['AS_DB_ADMIN'] = value.to_s
68
+ @default_connection = value
56
69
  end
57
70
 
58
71
  def default_connection?
@@ -77,12 +90,12 @@ module PgRls
77
90
  end
78
91
 
79
92
  def execute(query)
80
- @execute = ActiveRecord::Migration.execute(query)
93
+ ActiveRecord::Migration.execute(query)
81
94
  end
82
95
 
83
96
  def database_configuration
84
- @database_configuration ||= database_connection_file[Rails.env].tap do |config|
85
- config['username'] = PgRls::SECURE_USERNAME
97
+ database_connection_file[Rails.env].tap do |config|
98
+ config['username'] = PgRls::SECURE_USERNAME unless default_connection?
86
99
  end
87
100
  end
88
101
  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
4
+ version: 0.0.1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Laloush
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-08 00:00:00.000000000 Z
11
+ date: 2022-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,8 +60,11 @@ files:
60
60
  - lib/generators/templates/README
61
61
  - lib/generators/templates/pg_rls.rb.tt
62
62
  - lib/pg_rls.rb
63
+ - lib/pg_rls/Rakefile
63
64
  - lib/pg_rls/database/prepared.rb
65
+ - lib/pg_rls/database/tasks/admin_database.rake
64
66
  - lib/pg_rls/multi_tenancy.rb
67
+ - lib/pg_rls/railtie.rb
65
68
  - lib/pg_rls/schema/down_statements.rb
66
69
  - lib/pg_rls/schema/statements.rb
67
70
  - lib/pg_rls/schema/up_statements.rb
@@ -88,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
91
  - !ruby/object:Gem::Version
89
92
  version: '0'
90
93
  requirements: []
91
- rubygems_version: 3.2.22
94
+ rubygems_version: 3.3.3
92
95
  signing_key:
93
96
  specification_version: 4
94
97
  summary: Write a short summary, because RubyGems requires one.