pg_rls 0.0.1.beta → 0.0.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/Gemfile +0 -2
- data/Gemfile.lock +2 -11
- data/README.md +82 -11
- data/lib/generators/pg_rls/active_record/active_record_generator.rb +0 -2
- data/lib/generators/pg_rls/active_record/templates/init_migration.rb.tt +6 -6
- data/lib/generators/pg_rls/active_record/templates/init_model.rb.tt +2 -4
- data/lib/generators/pg_rls/install_generator.rb +12 -4
- data/lib/generators/templates/pg_rls.rb.tt +5 -1
- data/lib/pg_rls/schema/up_statements.rb +2 -2
- data/lib/pg_rls/tenant.rb +17 -4
- data/lib/pg_rls/version.rb +1 -1
- data/lib/pg_rls.rb +12 -3
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c4f0bd5f9878604a5f34c33b24221a9e7bb1efe25b526c825044dd7927f870f6
|
|
4
|
+
data.tar.gz: 1e51d31dccc7b7787921775f856d96cb630bf006fe5108df8fb65aba6560cf98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 86bafd3671e72de8a0f7fb84891c76530a28065dfb799b06de600bb0199a41cd8c22fed269e44076f79a05e2d874e63eeeb7f5728518d15ceddf89e6ff7bf824
|
|
7
|
+
data.tar.gz: f99445e75de533cb9ef7acfc5215c14ca78d629bd65cef1cb497f3adc1ae43f8689d46bcf7dcab8a5ac7684b79290630841ef33142434366800af9cf94e448d2
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
pg_rls (0.0.1
|
|
4
|
+
pg_rls (0.0.1)
|
|
5
5
|
bundler (>= 2.2.10)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -83,7 +83,7 @@ GEM
|
|
|
83
83
|
mini_mime (>= 0.1.1)
|
|
84
84
|
marcel (1.0.2)
|
|
85
85
|
method_source (1.0.0)
|
|
86
|
-
mini_mime (1.1.
|
|
86
|
+
mini_mime (1.1.2)
|
|
87
87
|
minitest (5.14.4)
|
|
88
88
|
nio4r (2.5.8)
|
|
89
89
|
nokogiri (1.12.5-x86_64-linux)
|
|
@@ -137,14 +137,6 @@ GEM
|
|
|
137
137
|
rspec-mocks (3.10.2)
|
|
138
138
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
139
139
|
rspec-support (~> 3.10.0)
|
|
140
|
-
rspec-rails (5.0.2)
|
|
141
|
-
actionpack (>= 5.2)
|
|
142
|
-
activesupport (>= 5.2)
|
|
143
|
-
railties (>= 5.2)
|
|
144
|
-
rspec-core (~> 3.10)
|
|
145
|
-
rspec-expectations (~> 3.10)
|
|
146
|
-
rspec-mocks (~> 3.10)
|
|
147
|
-
rspec-support (~> 3.10)
|
|
148
140
|
rspec-support (3.10.2)
|
|
149
141
|
rubocop (1.22.1)
|
|
150
142
|
parallel (~> 1.10)
|
|
@@ -182,7 +174,6 @@ DEPENDENCIES
|
|
|
182
174
|
rails (~> 6.1.4, >= 6.1.4.1)
|
|
183
175
|
rake
|
|
184
176
|
rspec
|
|
185
|
-
rspec-rails
|
|
186
177
|
rubocop
|
|
187
178
|
|
|
188
179
|
RUBY VERSION
|
data/README.md
CHANGED
|
@@ -1,10 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
[![Contributors][contributors-shield]][contributors-url]
|
|
2
|
+
[![Forks][forks-shield]][forks-url]
|
|
3
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
4
|
+
[![Issues][issues-shield]][issues-url]
|
|
5
|
+
[![LinkedIn][linkedin-shield2]][linkedin-url2]
|
|
6
|
+
[![Hireable][hireable]][hireable-url]
|
|
7
|
+
|
|
8
|
+
<!-- PROJECT LOGO -->
|
|
9
|
+
<br />
|
|
10
|
+
<p align="center">
|
|
11
|
+
<h1 align="center">PgRls</h1>
|
|
12
|
+
<h2 align="center"> PostgreSQL Row Level Security </h2>
|
|
13
|
+
<h1 align="center"></h1>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<br />
|
|
17
|
+
<a href="https://github.com/Dandush03/pg_rls"><strong>Explore the docs »</strong></a>
|
|
18
|
+
<br />
|
|
19
|
+
<br />
|
|
20
|
+
<a href="https://dl-final-webapp.herokuapp.com/">View Live Demo</a>
|
|
21
|
+
·
|
|
22
|
+
<a href="https://github.com/Dandush03/pg_rls/issues">Report Bug</a>
|
|
23
|
+
·
|
|
24
|
+
<a href="https://github.com/Dandush03/pg_rls/issues">Request Feature</a>
|
|
25
|
+
·
|
|
26
|
+
<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
|
+
</p>
|
|
30
|
+
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
### Table of Contents
|
|
34
|
+
* [Required Installations](#required-Installations)
|
|
35
|
+
* [Installing](#installing)
|
|
36
|
+
* [Instructions](#instructions)
|
|
37
|
+
* [Development](#testing)
|
|
38
|
+
* [Contact](#contact)
|
|
39
|
+
* [Contributing](#contributing)
|
|
40
|
+
* [License](#license)
|
|
41
|
+
* [Code of Conduct](#Code-of-Conduct)
|
|
42
|
+
* [Show your support](#Show-your-support)
|
|
43
|
+
|
|
44
|
+
This gem will help you to integrate PostgreSQL RLS to help you develop an easy multitenancy application
|
|
45
|
+
|
|
46
|
+
## Required Installations
|
|
47
|
+
### Installing
|
|
8
48
|
|
|
9
49
|
Add this line to your application's Gemfile:
|
|
10
50
|
|
|
@@ -20,18 +60,26 @@ Or install it yourself as:
|
|
|
20
60
|
|
|
21
61
|
$ gem install pg_rls
|
|
22
62
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
RUN `rails generate pg_rls:install company`
|
|
63
|
+
### Instructions
|
|
26
64
|
|
|
65
|
+
```bash
|
|
66
|
+
rails generate pg_rls:install company #=> where app eq tenant model name
|
|
67
|
+
```
|
|
27
68
|
You can change company to anything you'd like like for example `tenant`
|
|
28
69
|
this will generate the model and inject all the required code
|
|
29
70
|
|
|
30
71
|
for any new model that required to be under rls you can generate it by writing
|
|
31
72
|
|
|
32
|
-
|
|
73
|
+
```bash
|
|
74
|
+
rails generate pg_rls user #=> where app eq model name
|
|
75
|
+
```
|
|
33
76
|
and it will generate all the necesary information for you
|
|
34
77
|
|
|
78
|
+
you can swtich tenant by using
|
|
79
|
+
```ruby
|
|
80
|
+
PgRls::Tenant::switch :app #=> where app eq tenant name
|
|
81
|
+
```
|
|
82
|
+
|
|
35
83
|
enjoy the gem :)
|
|
36
84
|
## Development
|
|
37
85
|
|
|
@@ -50,3 +98,26 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
50
98
|
## Code of Conduct
|
|
51
99
|
|
|
52
100
|
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
|
+
|
|
102
|
+
## Note
|
|
103
|
+
Currently we only support subdomain as a searcher but soon will integrate slug/domain and cookies support
|
|
104
|
+
|
|
105
|
+
## Show your support
|
|
106
|
+
|
|
107
|
+
Give a ⭐️ if you like this project!
|
|
108
|
+
|
|
109
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
110
|
+
[contributors-shield]: https://img.shields.io/github/contributors/Dandush03/React-Calculator.svg?style=flat-square
|
|
111
|
+
[contributors-url]: https://github.com/Dandush03/pg_rls/graphs/contributors
|
|
112
|
+
[forks-shield]: https://img.shields.io/github/forks/Dandush03/pg_rls.svg?style=flat-square
|
|
113
|
+
[forks-url]: https://github.com/Dandush03/pg_rls/network/members
|
|
114
|
+
[stars-shield]: https://img.shields.io/github/stars/Dandush03/pg_rls.svg?style=flat-square
|
|
115
|
+
[stars-url]: https://github.com/Dandush03/pg_rls/stargazers
|
|
116
|
+
[issues-shield]: https://img.shields.io/github/issues/Dandush03/pg_rls.svg?style=flat-square
|
|
117
|
+
[issues-url]: https://github.com/Dandush03/pg_rls/issues
|
|
118
|
+
[license-shield]: https://img.shields.io/github/license/Dandush03/pg_rls.svg?style=flat-square
|
|
119
|
+
[license-url]: https://github.com/Dandush03/pg_rls/blob/master/LICENSE.txt
|
|
120
|
+
[linkedin-shield2]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555
|
|
121
|
+
[linkedin-url2]: https://www.linkedin.com/in/daniel-laloush/
|
|
122
|
+
[hireable]: https://cdn.rawgit.com/hiendv/hireable/master/styles/flat/yes.svg
|
|
123
|
+
[hireable-url]: https://www.linkedin.com/in/daniel-laloush/
|
|
@@ -11,8 +11,6 @@ module PgRls
|
|
|
11
11
|
|
|
12
12
|
source_root File.expand_path('./templates', __dir__)
|
|
13
13
|
|
|
14
|
-
hook_for :test_framework
|
|
15
|
-
|
|
16
14
|
def create_migration_file
|
|
17
15
|
migration_template migration_template_path, "#{migration_path}/#{file_sub_name}_#{table_name}.rb",
|
|
18
16
|
migration_version: migration_version
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class PgRlsTenantCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
|
3
|
+
class PgRlsTenantCreate<%= 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
|
|
@@ -13,13 +13,13 @@ class PgRlsTenantCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= m
|
|
|
13
13
|
t.timestamps
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
add_index
|
|
17
|
-
add_index
|
|
18
|
-
add_index
|
|
19
|
-
add_index
|
|
16
|
+
add_index :<%= table_name %>, :name, unique: true
|
|
17
|
+
add_index :<%= table_name %>, :identification, unique: true
|
|
18
|
+
add_index :<%= table_name %>, :domain, unique: true
|
|
19
|
+
add_index :<%= table_name %>, :subdomain, unique: true
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def down
|
|
23
|
-
drop_rls_tenant_table
|
|
23
|
+
drop_rls_tenant_table :<%= table_name %>
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
<% module_namespacing do -%>
|
|
4
|
-
class <%= class_name %> < <%= parent_class_name.classify %>
|
|
4
|
+
class <%= PgRls.class_name.camelize %> < <%= parent_class_name.classify %>
|
|
5
5
|
def self.current
|
|
6
|
-
|
|
7
|
-
rescue ActiveRecord::StatementInvalid
|
|
8
|
-
'no tenant is selected'
|
|
6
|
+
PgRls::Tenant.fetch
|
|
9
7
|
end
|
|
10
8
|
<% attributes.select(&:reference?).each do |attribute| -%>
|
|
11
9
|
belongs_to :<%= attribute.name %><%= ", polymorphic: true" if attribute.polymorphic? %>
|
|
@@ -8,14 +8,25 @@ module PgRls
|
|
|
8
8
|
MissingORMError = Class.new(Thor::Error)
|
|
9
9
|
# Installer Generator
|
|
10
10
|
class InstallGenerator < Rails::Generators::Base
|
|
11
|
+
def initialize(*args)
|
|
12
|
+
tenant_model_or_table = args.first
|
|
13
|
+
if tenant_model_or_table.present?
|
|
14
|
+
PgRls.table_name = tenant_model_or_table.first.pluralize
|
|
15
|
+
PgRls.class_name = tenant_model_or_table.first.singularize
|
|
16
|
+
end
|
|
17
|
+
super
|
|
18
|
+
end
|
|
11
19
|
APPLICATION_RECORD_LINE = 'class ApplicationRecord < ActiveRecord::Base'
|
|
12
20
|
APPLICATION_RECORD_PATH = 'app/models/application_record.rb'
|
|
13
21
|
APPLICATION_CONTROLLER_LINE = 'class ApplicationController < ActionController::Base'
|
|
14
22
|
APPLICATION_CONTROLLER_PATH = 'app/controllers/application_controller.rb'
|
|
23
|
+
|
|
15
24
|
source_root File.expand_path('../templates', __dir__)
|
|
16
25
|
|
|
17
26
|
desc 'Creates a PgRls initializer and copy locale files to your application.'
|
|
18
27
|
|
|
28
|
+
hook_for :orm, required: true
|
|
29
|
+
|
|
19
30
|
def orm_error_message
|
|
20
31
|
<<-ERROR.strip_heredoc
|
|
21
32
|
An ORM must be set to install PgRls in your application.
|
|
@@ -30,10 +41,9 @@ module PgRls
|
|
|
30
41
|
def copy_initializer
|
|
31
42
|
raise MissingORMError, orm_error_message unless options[:orm]
|
|
32
43
|
|
|
33
|
-
template 'pg_rls.rb.tt', 'config/initializers/pg_rls.rb'
|
|
34
|
-
|
|
35
44
|
inject_include_to_application_record
|
|
36
45
|
inject_include_to_application_controller
|
|
46
|
+
template 'pg_rls.rb.tt', 'config/initializers/pg_rls.rb'
|
|
37
47
|
end
|
|
38
48
|
|
|
39
49
|
def inject_include_to_application_record
|
|
@@ -68,8 +78,6 @@ module PgRls
|
|
|
68
78
|
def show_readme
|
|
69
79
|
readme 'README' if behavior == :invoke
|
|
70
80
|
end
|
|
71
|
-
|
|
72
|
-
hook_for :orm, required: true
|
|
73
81
|
end
|
|
74
82
|
end
|
|
75
83
|
end
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require 'pg_rls'
|
|
4
4
|
|
|
5
|
-
PgRls.setup do |
|
|
5
|
+
PgRls.setup do |config|
|
|
6
6
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.include PgRls::Schema::Statements
|
|
7
|
+
|
|
8
|
+
# Do not remove this value after initialization
|
|
9
|
+
config.class_name = :<%= PgRls.class_name %>
|
|
10
|
+
config.table_name = :<%= PgRls.table_name %>
|
|
7
11
|
end
|
|
@@ -64,9 +64,9 @@ module PgRls
|
|
|
64
64
|
ActiveRecord::Migration.execute <<-SQL
|
|
65
65
|
ALTER TABLE #{table_name}
|
|
66
66
|
ADD COLUMN IF NOT EXISTS tenant_id uuid,
|
|
67
|
-
ADD CONSTRAINT
|
|
67
|
+
ADD CONSTRAINT fk_#{PgRls.table_name}
|
|
68
68
|
FOREIGN KEY (tenant_id)
|
|
69
|
-
REFERENCES
|
|
69
|
+
REFERENCES #{PgRls.table_name}(tenant_id)
|
|
70
70
|
ON DELETE CASCADE;
|
|
71
71
|
SQL
|
|
72
72
|
end
|
data/lib/pg_rls/tenant.rb
CHANGED
|
@@ -4,20 +4,33 @@ module PgRls
|
|
|
4
4
|
# Tenant Controller
|
|
5
5
|
module Tenant
|
|
6
6
|
class << self
|
|
7
|
-
SET_COMPANY_ID_SQL = 'SET rls.tenant_id = %s'
|
|
8
7
|
def switch(resource)
|
|
9
8
|
connection_adapter = PgRls.connection_class
|
|
10
9
|
tenant = tenant_by_subdomain_uuid_or_tenant_id(resource)
|
|
11
|
-
connection_adapter.connection.execute(format(
|
|
10
|
+
connection_adapter.connection.execute(format('SET rls.tenant_id = %s',
|
|
12
11
|
connection_adapter.connection.quote(tenant.tenant_id)))
|
|
13
|
-
"RLS changed to '#{tenant}'"
|
|
12
|
+
"RLS changed to '#{tenant.name}'"
|
|
14
13
|
rescue StandardError => e
|
|
15
14
|
puts 'connection was not made'
|
|
16
15
|
puts e
|
|
17
16
|
end
|
|
18
17
|
|
|
18
|
+
def tenant
|
|
19
|
+
PgRls.class_name.to_s.camelize.constantize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fetch
|
|
23
|
+
tenant.find_by_tenant_id(
|
|
24
|
+
PgRls.connection_class.connection.execute(
|
|
25
|
+
"SELECT current_setting('rls.tenant_id')"
|
|
26
|
+
).getvalue(0, 0)
|
|
27
|
+
)
|
|
28
|
+
rescue ActiveRecord::StatementInvalid
|
|
29
|
+
'no tenant is selected'
|
|
30
|
+
end
|
|
31
|
+
|
|
19
32
|
def tenant_by_subdomain_uuid_or_tenant_id(resource)
|
|
20
|
-
|
|
33
|
+
tenant.find_by_subdomain(resource) || tenant.find_by_id(resource) || tenant.find_by_tenant_id(resource)
|
|
21
34
|
end
|
|
22
35
|
end
|
|
23
36
|
end
|
data/lib/pg_rls/version.rb
CHANGED
data/lib/pg_rls.rb
CHANGED
|
@@ -16,9 +16,13 @@ module PgRls
|
|
|
16
16
|
class << self
|
|
17
17
|
extend Forwardable
|
|
18
18
|
|
|
19
|
-
WRITER_METHODS = %i[].freeze
|
|
20
|
-
READER_METHODS = %i[
|
|
21
|
-
|
|
19
|
+
WRITER_METHODS = %i[table_name class_name].freeze
|
|
20
|
+
READER_METHODS = %i[
|
|
21
|
+
connection_class database_configuration execute table_name class_name
|
|
22
|
+
].freeze
|
|
23
|
+
DELEGATORS_METHODS = %i[
|
|
24
|
+
connection_class database_configuration execute table_name class_name
|
|
25
|
+
].freeze
|
|
22
26
|
|
|
23
27
|
attr_writer(*WRITER_METHODS)
|
|
24
28
|
attr_reader(*READER_METHODS)
|
|
@@ -59,4 +63,9 @@ module PgRls
|
|
|
59
63
|
end
|
|
60
64
|
end
|
|
61
65
|
end
|
|
66
|
+
mattr_accessor :table_name
|
|
67
|
+
@@table_name = 'companies'
|
|
68
|
+
|
|
69
|
+
mattr_accessor :class_name
|
|
70
|
+
@@class_name = 'Company'
|
|
62
71
|
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
|
|
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
|
+
date: 2021-10-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -77,9 +77,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
77
77
|
version: 3.0.0
|
|
78
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
82
|
+
version: '0'
|
|
83
83
|
requirements: []
|
|
84
84
|
rubygems_version: 3.2.27
|
|
85
85
|
signing_key:
|