granar 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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +53 -0
- data/Rakefile +8 -0
- data/app/assets/config/rbac_rls_manifest.js +2 -0
- data/app/assets/javascripts/rbac_rls/application.js +1 -0
- data/app/assets/stylesheets/rbac_rls/application.css.scss +16 -0
- data/app/controllers/concerns/connection_rls_user_concern.rb +31 -0
- data/app/controllers/rbac_rls/application_controller.rb +3 -0
- data/app/controllers/rbac_rls/groups_controller.rb +94 -0
- data/app/controllers/rbac_rls/home_controller.rb +5 -0
- data/app/controllers/rbac_rls/permissions_controller.rb +69 -0
- data/app/controllers/rbac_rls/roles_controller.rb +61 -0
- data/app/helpers/rbac_rls/application_helper.rb +4 -0
- data/app/helpers/rbac_rls/groups_helper.rb +4 -0
- data/app/helpers/rbac_rls/permissions_helper.rb +41 -0
- data/app/helpers/rbac_rls/roles_helper.rb +4 -0
- data/app/jobs/rbac_rls/application_job.rb +4 -0
- data/app/mailers/rbac_rls/application_mailer.rb +6 -0
- data/app/models/concerns/connection_rls_concern.rb +19 -0
- data/app/models/rbac_rls/application_record.rb +3 -0
- data/app/models/rbac_rls/group.rb +14 -0
- data/app/models/rbac_rls/group_permission.rb +20 -0
- data/app/models/rbac_rls/group_user.rb +7 -0
- data/app/models/rbac_rls/permission.rb +68 -0
- data/app/models/rbac_rls/role.rb +10 -0
- data/app/models/rbac_rls/role_permission.rb +6 -0
- data/app/models/rbac_rls/user_role.rb +7 -0
- data/app/views/layouts/rbac_rls/application.html.erb +55 -0
- data/app/views/rbac_rls/groups/_form.html.erb +97 -0
- data/app/views/rbac_rls/groups/_group.html.erb +12 -0
- data/app/views/rbac_rls/groups/_group_permission_fields.html.erb +18 -0
- data/app/views/rbac_rls/groups/_group_user_fields.html.erb +9 -0
- data/app/views/rbac_rls/groups/edit.html.erb +10 -0
- data/app/views/rbac_rls/groups/index.html.erb +14 -0
- data/app/views/rbac_rls/groups/new.html.erb +9 -0
- data/app/views/rbac_rls/groups/show.html.erb +10 -0
- data/app/views/rbac_rls/home/_link_to_home_page.html.erb +3 -0
- data/app/views/rbac_rls/home/index.html.erb +28 -0
- data/app/views/rbac_rls/permissions/_form.html.erb +78 -0
- data/app/views/rbac_rls/permissions/_permission.html.erb +54 -0
- data/app/views/rbac_rls/permissions/_role_permission_fields.html.erb +9 -0
- data/app/views/rbac_rls/permissions/edit.html.erb +7 -0
- data/app/views/rbac_rls/permissions/index.html.erb +18 -0
- data/app/views/rbac_rls/permissions/new.html.erb +9 -0
- data/app/views/rbac_rls/permissions/show.html.erb +10 -0
- data/app/views/rbac_rls/roles/_form.html.erb +42 -0
- data/app/views/rbac_rls/roles/_role.html.erb +2 -0
- data/app/views/rbac_rls/roles/_user_role_fields.html.erb +9 -0
- data/app/views/rbac_rls/roles/edit.html.erb +9 -0
- data/app/views/rbac_rls/roles/index.html.erb +19 -0
- data/app/views/rbac_rls/roles/new.html.erb +8 -0
- data/app/views/rbac_rls/roles/show.html.erb +12 -0
- data/config/assets.rb +12 -0
- data/config/importmap.rb +9 -0
- data/config/routes.rb +14 -0
- data/config/setup.rb +0 -0
- data/db/migrate/20220411125339_create_rbac_rls_roles.rb +9 -0
- data/db/migrate/20220411125613_create_rbac_rls_user_roles.rb +9 -0
- data/db/migrate/20220411133054_create_rbac_rls_permissions.rb +18 -0
- data/db/migrate/20220425212731_create_role_permissions.rb +9 -0
- data/db/migrate/20220912104712_create_rbac_rls_groups.rb +10 -0
- data/db/migrate/20220912104929_create_rbac_rls_group_permissions.rb +12 -0
- data/db/migrate/20220914004802_create_rbac_rls_group_users.rb +10 -0
- data/db/migrate/20220914004803_create_basic_permissions_for_application_acess.rb +18 -0
- data/lib/generators/generator_helpers.rb +8 -0
- data/lib/generators/rbac_rls/custom_migration_generator.rb +78 -0
- data/lib/generators/rbac_rls/group_permission_generator.rb +57 -0
- data/lib/generators/rbac_rls/templates/group_permission_migration.rb +83 -0
- data/lib/generators/rbac_rls/templates/rls_migration.rb +81 -0
- data/lib/generators/rbac_rls/templates/rls_migration.rb.erb +64 -0
- data/lib/generators/rbac_rls/templates/rls_migration2.rb.erb +80 -0
- data/lib/rbac_rls/engine.rb +21 -0
- data/lib/rbac_rls/version.rb +3 -0
- data/lib/rbac_rls.rb +6 -0
- data/lib/tasks/rbac_rls_tasks.rake +4 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9d9610309d089b766b027f7878b96c717d6e547d12d47d2bfb3080d4c9cc7756
|
4
|
+
data.tar.gz: 6559e4180d2fa0034db86a99a741f937f78428065b6136f4ae471af5a3de2b29
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7289f3498cacb45fe4d15f5693004ba6c19aec5b94eab6b0de97e6231b5d04602d559f471d200cfb21410626aa3bd1548678fc0284b55132a8ff3b41c269ab14
|
7
|
+
data.tar.gz: ad6a0f703c2656eace3ec75f9e377519185e71beb32958cf906250a789def33ba8ce61b34467d703e3d5f0cbd09059f0f4747e41b5753c9e37073c7bcb46aadf
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 FilipeBeserraMaia
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# RbacRls
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "rbac_rls"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install rbac_rls
|
22
|
+
```
|
23
|
+
And then add in your manifest.js:
|
24
|
+
```bash
|
25
|
+
//= link rbac_rls/application.css
|
26
|
+
//= link rbac_rls/application.js
|
27
|
+
```
|
28
|
+
And then add in your application_record.rb and application_controller.rb:
|
29
|
+
```bash
|
30
|
+
include ConnectionRls
|
31
|
+
include ConnectionRlsUser
|
32
|
+
```
|
33
|
+
|
34
|
+
And then run this command:
|
35
|
+
```bash
|
36
|
+
rake rbac_rls:install:migrations
|
37
|
+
```
|
38
|
+
|
39
|
+
And then run this command:
|
40
|
+
```bash
|
41
|
+
rake db:migrate
|
42
|
+
```
|
43
|
+
And then run this command:
|
44
|
+
```bash
|
45
|
+
yarn install
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
## Contributing
|
50
|
+
Contribution directions go here.
|
51
|
+
|
52
|
+
## License
|
53
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
// = require vanilla_nested
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
16
|
+
@import "bootstrap";
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ConnectionRlsUserConcern
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
around_action :with_user_id
|
6
|
+
rescue_from ::PG::InsufficientPrivilege, with: :rls_error
|
7
|
+
|
8
|
+
def with_user_id
|
9
|
+
if current_user.present?
|
10
|
+
ApplicationRecord.with_user_id(current_user.id) do
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
else
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def rls_error(exception)
|
19
|
+
respond_to do |format|
|
20
|
+
format.json { render json: { error: exception.message }.to_json, status: 500 }
|
21
|
+
format.html { redirect_to request.referrer, notice: exception.message }
|
22
|
+
format.js { render :nothing => true, :status => 404, notice: exception.message }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
class_methods do
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module RbacRls
|
2
|
+
class GroupsController < ApplicationController
|
3
|
+
include ConnectionRlsUserConcern
|
4
|
+
before_action :set_group, only: %i[ show edit update destroy ]
|
5
|
+
|
6
|
+
# GET /groups
|
7
|
+
def index
|
8
|
+
@groups = Group.all
|
9
|
+
end
|
10
|
+
|
11
|
+
# GET /groups/1
|
12
|
+
def show
|
13
|
+
end
|
14
|
+
|
15
|
+
# GET /groups/new
|
16
|
+
def new
|
17
|
+
@group = Group.new
|
18
|
+
@group.group_permissions.build()
|
19
|
+
end
|
20
|
+
|
21
|
+
# GET /groups/1/edit
|
22
|
+
def edit
|
23
|
+
end
|
24
|
+
|
25
|
+
# POST /groups
|
26
|
+
def create
|
27
|
+
@group = Group.new(group_params)
|
28
|
+
|
29
|
+
if @group.save
|
30
|
+
redirect_to @group, notice: "Group was successfully created."
|
31
|
+
else
|
32
|
+
render :new, status: :unprocessable_entity
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# PATCH/PUT /groups/1
|
37
|
+
def update
|
38
|
+
if @group.update(group_params)
|
39
|
+
redirect_to @group, notice: "Group was successfully updated."
|
40
|
+
else
|
41
|
+
render :edit, status: :unprocessable_entity
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# DELETE /groups/1
|
46
|
+
def destroy
|
47
|
+
@group.destroy
|
48
|
+
redirect_to groups_url, notice: "Group was successfully destroyed."
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_options_select
|
52
|
+
@permission = Permission.find_by(id: params[:permission_object_id])
|
53
|
+
|
54
|
+
if @permission.present?
|
55
|
+
attrs = @permission.table_name.singularize.camelize.constantize.new.attributes.keys
|
56
|
+
if params[:target_select].to_s.to_sym == :table_key_id
|
57
|
+
|
58
|
+
@collection = [attrs, attrs].transpose.to_h if params[:target_select].to_s.to_sym == :table_key_id
|
59
|
+
|
60
|
+
elsif params[:target_select].to_s.to_sym == :table_value_id
|
61
|
+
elements = @permission.table_name.singularize.camelize.constantize.all.map(¶ms[:permission_id].to_s.to_sym)
|
62
|
+
@collection = [elements, elements].transpose.to_h
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
render json: @collection.to_h.as_json
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# Use callbacks to share common setup or constraints between actions.
|
72
|
+
def set_group
|
73
|
+
@group = Group.find(params[:id])
|
74
|
+
end
|
75
|
+
|
76
|
+
# Only allow a list of trusted parameters through.
|
77
|
+
def group_params
|
78
|
+
params.require(:group).permit(:name, :comments, group_permissions_attributes: [:id,
|
79
|
+
:group_id,
|
80
|
+
:permission_id,
|
81
|
+
:table_key,
|
82
|
+
:table_value,
|
83
|
+
:_destroy],
|
84
|
+
group_users_attributes: [
|
85
|
+
:id,
|
86
|
+
:group_id,
|
87
|
+
:user_id,
|
88
|
+
:_destroy
|
89
|
+
]
|
90
|
+
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module RbacRls
|
2
|
+
class PermissionsController < RbacRls::ApplicationController
|
3
|
+
before_action :set_permission, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /permissions
|
6
|
+
def index
|
7
|
+
@permissions = Permission.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /permissions/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /permissions/new
|
15
|
+
def new
|
16
|
+
@permission = Permission.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /permissions/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /permissions
|
24
|
+
def create
|
25
|
+
@permission = Permission.new(permission_params)
|
26
|
+
|
27
|
+
if @permission.save
|
28
|
+
|
29
|
+
redirect_to @permission, notice: "Permission was successfully created."
|
30
|
+
else
|
31
|
+
render :new, status: :unprocessable_entity
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# PATCH/PUT /permissions/1
|
36
|
+
def update
|
37
|
+
if @permission.update(permission_params)
|
38
|
+
redirect_to @permission, notice: "Permission was successfully updated."
|
39
|
+
else
|
40
|
+
render :edit, status: :unprocessable_entity
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# DELETE /permissions/1
|
45
|
+
def destroy
|
46
|
+
@permission.destroy
|
47
|
+
redirect_to permissions_url, notice: "Permission was successfully destroyed."
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Use callbacks to share common setup or constraints between actions.
|
53
|
+
def set_permission
|
54
|
+
@permission = Permission.find(params[:id])
|
55
|
+
end
|
56
|
+
|
57
|
+
# Only allow a list of trusted parameters through.
|
58
|
+
def permission_params
|
59
|
+
params.require(:permission).permit(:name, :table_name, :read, :write, :change, :remove, :permission_id,
|
60
|
+
:owner_read, :owner_change, :owner_remove,
|
61
|
+
role_permissions_attributes: [:id,
|
62
|
+
:role_id,
|
63
|
+
:permission_id,
|
64
|
+
:_destroy]
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RbacRls
|
2
|
+
class RolesController < RbacRls::ApplicationController
|
3
|
+
before_action :set_role, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /roles
|
6
|
+
def index
|
7
|
+
@roles = Role.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /roles/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /roles/new
|
15
|
+
def new
|
16
|
+
@role = RbacRls::Role.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /roles/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /roles
|
24
|
+
def create
|
25
|
+
@role = Role.new(role_params)
|
26
|
+
|
27
|
+
if @role.save
|
28
|
+
redirect_to @role, notice: "Role was successfully created."
|
29
|
+
else
|
30
|
+
render :new, status: :unprocessable_entity
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# PATCH/PUT /roles/1
|
35
|
+
def update
|
36
|
+
if @role.update(role_params)
|
37
|
+
redirect_to @role, notice: "Role was successfully updated."
|
38
|
+
else
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /roles/1
|
44
|
+
def destroy
|
45
|
+
@role.destroy
|
46
|
+
redirect_to roles_url, notice: "Role was successfully destroyed."
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Use callbacks to share common setup or constraints between actions.
|
52
|
+
def set_role
|
53
|
+
@role = Role.find(params[:id])
|
54
|
+
end
|
55
|
+
|
56
|
+
# Only allow a list of trusted parameters through.
|
57
|
+
def role_params
|
58
|
+
params.require(:role).permit(:name, :comments, user_roles_attributes: [:id, :_destroy, :user_id])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RbacRls
|
2
|
+
module PermissionsHelper
|
3
|
+
|
4
|
+
def permission_options_for_select(form)
|
5
|
+
c = RbacRls::Permission.all
|
6
|
+
options_for_select(c.collect { |p| [p.name, p.id] }, form.object.permission_id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def table_selected_key_options_for_select(form)
|
10
|
+
return options_for_select({}, nil) if form.object.permission_id.nil?
|
11
|
+
c = RbacRls::GroupPermission.all
|
12
|
+
options_for_select(c.collect { |p| [p.table_key, p.table_key] }, form.object.table_key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def table_selected_value_options_for_select(form)
|
16
|
+
return options_for_select({}, nil) if form.object.permission_id.nil?
|
17
|
+
c = RbacRls::GroupPermission.all
|
18
|
+
options_for_select(c.collect { |p| [p.table_value, p.table_value] }, form.object.table_value)
|
19
|
+
end
|
20
|
+
|
21
|
+
def role_options_for_select(form)
|
22
|
+
c = RbacRls::Role.all
|
23
|
+
options_for_select(c.collect { |p| [p.name, p.id] }, form.object.role_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def permission_options_for_select(form)
|
27
|
+
c = RbacRls::Permission.all
|
28
|
+
options_for_select(c.collect { |p| [p.name, p.id] }, form.object.permission_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def user_options_for_select(form)
|
32
|
+
c = User.all
|
33
|
+
options_for_select(c.collect { |p| [p.email, p.id] }, form.object.user_id)
|
34
|
+
end
|
35
|
+
|
36
|
+
def table_name_options_for_select(form)
|
37
|
+
c = RbacRls::Permission.all_tables
|
38
|
+
options_for_select(c.collect { |t| [t, t] }, form.object.table_name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ConnectionRlsConcern
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
SET_USER_ID_SQL = 'SET rls.user_id = %s'.freeze
|
6
|
+
RESET_USER_ID_SQL = 'RESET rls.user_id'.freeze
|
7
|
+
end
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
def with_user_id(user_id, &block)
|
11
|
+
begin
|
12
|
+
connection.execute format(SET_USER_ID_SQL, connection.quote(user_id))
|
13
|
+
block.call
|
14
|
+
ensure
|
15
|
+
connection.execute RESET_USER_ID_SQL
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class RbacRls::Group < ApplicationRecord
|
2
|
+
|
3
|
+
self.table_name = :groups
|
4
|
+
has_many :group_permissions, :class_name => 'RbacRls::GroupPermission'
|
5
|
+
has_many :group_users, :class_name => 'RbacRls::GroupUser'
|
6
|
+
accepts_nested_attributes_for :group_permissions, reject_if: :all_blank, allow_destroy: true
|
7
|
+
accepts_nested_attributes_for :group_users, reject_if: :all_blank, allow_destroy: true
|
8
|
+
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RbacRls
|
2
|
+
class GroupPermission < ApplicationRecord
|
3
|
+
self.table_name = :group_permissions
|
4
|
+
belongs_to :permission
|
5
|
+
belongs_to :group
|
6
|
+
after_save :create_group_rls_policy
|
7
|
+
|
8
|
+
#rails generate rbac_rls:group_permission table_name description:table_key 'produto':table_value
|
9
|
+
def create_group_rls_policy
|
10
|
+
cmd = ""
|
11
|
+
if self.permission.table_name.present? and self.table_key.present? and self.table_value.present?
|
12
|
+
cmd = "rails generate rbac_rls:group_permission #{self.permission.table_name} '#{self.table_key}':table_key '#{self.table_value}':table_value"
|
13
|
+
end
|
14
|
+
if cmd.present?
|
15
|
+
system(cmd)
|
16
|
+
system('rake db:migrate RAILS_ENV=migrations')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class RbacRls::Permission < ApplicationRecord
|
2
|
+
|
3
|
+
self.table_name = :permissions
|
4
|
+
belongs_to :permission, :class_name => 'RbacRls::Permission', optional: true
|
5
|
+
has_many :role_permissions, :class_name => 'RbacRls::RolePermission'
|
6
|
+
accepts_nested_attributes_for :role_permissions, reject_if: :all_blank, allow_destroy: true
|
7
|
+
|
8
|
+
#validations
|
9
|
+
validate :validate_self_relationship, if: Proc.new { |obj| obj.permission.present? }
|
10
|
+
validates_uniqueness_of :name, message: "This permission already exists"
|
11
|
+
validates_presence_of :table_name
|
12
|
+
before_validation :set_permission_name
|
13
|
+
after_commit :create_rls_policy
|
14
|
+
|
15
|
+
def self.all_tables(schema = :public)
|
16
|
+
|
17
|
+
sql = "SELECT table_name FROM information_schema.tables #{where_schema(schema)} "
|
18
|
+
result = ActiveRecord::Base.connection.select_all(sql)
|
19
|
+
tables = result.map { |k| k['table_name'] }
|
20
|
+
tables
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.where_schema(schema_name = nil)
|
24
|
+
schema_name.present? ? "WHERE table_schema = '#{schema_name}'" : ''
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def validate_self_relationship
|
30
|
+
self.errors.add(:permission, "cannot add self relationship with the same record") if self.id == self.permission_id
|
31
|
+
end
|
32
|
+
|
33
|
+
#@example rails generate rbac_rls:custom_migration transictions insert:role update:role select:all delete:user
|
34
|
+
def create_rls_policy
|
35
|
+
type_policies = ->() do
|
36
|
+
cmd = ""
|
37
|
+
cmd += " select:role " if read.present?
|
38
|
+
cmd += " insert:role " if write.present?
|
39
|
+
cmd += " update:role " if change.present?
|
40
|
+
cmd += " delete:role " if remove.present?
|
41
|
+
cmd
|
42
|
+
end
|
43
|
+
type_options = -> () do
|
44
|
+
cmd = ""
|
45
|
+
cmd += " --permission_identifier #{self.id} " if self.id.present?
|
46
|
+
cmd
|
47
|
+
end
|
48
|
+
|
49
|
+
if (type_policies.===).present? and (type_options.===).present? &&
|
50
|
+
RbacRls::Permission.all.map(&:table_name).exclude?(table_name)
|
51
|
+
|
52
|
+
cmd = "rails generate rbac_rls:custom_migration #{table_name} #{type_policies.===} #{type_options.===}"
|
53
|
+
system(cmd)
|
54
|
+
system('rake db:migrate RAILS_ENV=migrations')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_permission_name
|
59
|
+
self.name = self.table_name.to_s if self.table_name.present?
|
60
|
+
self.name += "_rd" if self.read
|
61
|
+
self.name += "_wt" if self.write
|
62
|
+
self.name += "_cg" if self.change
|
63
|
+
self.name += "_rv" if self.remove
|
64
|
+
end
|
65
|
+
|
66
|
+
def has_role_permission?() end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class RbacRls::Role < ApplicationRecord
|
2
|
+
self.table_name = :roles
|
3
|
+
|
4
|
+
# has_many :permissions, :class_name => 'RbacRls::Permission'
|
5
|
+
|
6
|
+
has_many :user_roles, :class_name => 'RbacRls::UserRole'
|
7
|
+
accepts_nested_attributes_for :user_roles, reject_if: :all_blank, allow_destroy: true
|
8
|
+
|
9
|
+
end
|
10
|
+
|