rbac_rls 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +53 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/config/rbac_rls_manifest.js +2 -0
  6. data/app/assets/javascripts/rbac_rls/application.js +1 -0
  7. data/app/assets/stylesheets/rbac_rls/application.css.scss +16 -0
  8. data/app/controllers/concerns/connection_rls_user_concern.rb +31 -0
  9. data/app/controllers/rbac_rls/application_controller.rb +3 -0
  10. data/app/controllers/rbac_rls/groups_controller.rb +94 -0
  11. data/app/controllers/rbac_rls/home_controller.rb +5 -0
  12. data/app/controllers/rbac_rls/permissions_controller.rb +69 -0
  13. data/app/controllers/rbac_rls/roles_controller.rb +61 -0
  14. data/app/helpers/rbac_rls/application_helper.rb +4 -0
  15. data/app/helpers/rbac_rls/groups_helper.rb +4 -0
  16. data/app/helpers/rbac_rls/permissions_helper.rb +41 -0
  17. data/app/helpers/rbac_rls/roles_helper.rb +4 -0
  18. data/app/jobs/rbac_rls/application_job.rb +4 -0
  19. data/app/mailers/rbac_rls/application_mailer.rb +6 -0
  20. data/app/models/concerns/connection_rls_concern.rb +19 -0
  21. data/app/models/rbac_rls/application_record.rb +3 -0
  22. data/app/models/rbac_rls/group.rb +14 -0
  23. data/app/models/rbac_rls/group_permission.rb +20 -0
  24. data/app/models/rbac_rls/group_user.rb +7 -0
  25. data/app/models/rbac_rls/permission.rb +68 -0
  26. data/app/models/rbac_rls/role.rb +10 -0
  27. data/app/models/rbac_rls/role_permission.rb +6 -0
  28. data/app/models/rbac_rls/user_role.rb +7 -0
  29. data/app/views/layouts/rbac_rls/application.html.erb +55 -0
  30. data/app/views/rbac_rls/groups/_form.html.erb +97 -0
  31. data/app/views/rbac_rls/groups/_group.html.erb +12 -0
  32. data/app/views/rbac_rls/groups/_group_permission_fields.html.erb +18 -0
  33. data/app/views/rbac_rls/groups/_group_user_fields.html.erb +9 -0
  34. data/app/views/rbac_rls/groups/edit.html.erb +10 -0
  35. data/app/views/rbac_rls/groups/index.html.erb +14 -0
  36. data/app/views/rbac_rls/groups/new.html.erb +9 -0
  37. data/app/views/rbac_rls/groups/show.html.erb +10 -0
  38. data/app/views/rbac_rls/home/_link_to_home_page.html.erb +3 -0
  39. data/app/views/rbac_rls/home/index.html.erb +28 -0
  40. data/app/views/rbac_rls/permissions/_form.html.erb +78 -0
  41. data/app/views/rbac_rls/permissions/_permission.html.erb +54 -0
  42. data/app/views/rbac_rls/permissions/_role_permission_fields.html.erb +9 -0
  43. data/app/views/rbac_rls/permissions/edit.html.erb +7 -0
  44. data/app/views/rbac_rls/permissions/index.html.erb +18 -0
  45. data/app/views/rbac_rls/permissions/new.html.erb +9 -0
  46. data/app/views/rbac_rls/permissions/show.html.erb +10 -0
  47. data/app/views/rbac_rls/roles/_form.html.erb +42 -0
  48. data/app/views/rbac_rls/roles/_role.html.erb +2 -0
  49. data/app/views/rbac_rls/roles/_user_role_fields.html.erb +9 -0
  50. data/app/views/rbac_rls/roles/edit.html.erb +9 -0
  51. data/app/views/rbac_rls/roles/index.html.erb +19 -0
  52. data/app/views/rbac_rls/roles/new.html.erb +8 -0
  53. data/app/views/rbac_rls/roles/show.html.erb +12 -0
  54. data/config/assets.rb +12 -0
  55. data/config/importmap.rb +9 -0
  56. data/config/routes.rb +14 -0
  57. data/config/setup.rb +0 -0
  58. data/db/migrate/20220411125339_create_rbac_rls_roles.rb +9 -0
  59. data/db/migrate/20220411125613_create_rbac_rls_user_roles.rb +9 -0
  60. data/db/migrate/20220411133054_create_rbac_rls_permissions.rb +18 -0
  61. data/db/migrate/20220425212731_create_role_permissions.rb +9 -0
  62. data/db/migrate/20220912104712_create_rbac_rls_groups.rb +10 -0
  63. data/db/migrate/20220912104929_create_rbac_rls_group_permissions.rb +12 -0
  64. data/db/migrate/20220914004802_create_rbac_rls_group_users.rb +10 -0
  65. data/db/migrate/20220914004803_create_basic_permissions_for_application_acess.rb +18 -0
  66. data/lib/generators/generator_helpers.rb +8 -0
  67. data/lib/generators/rbac_rls/custom_migration_generator.rb +78 -0
  68. data/lib/generators/rbac_rls/group_permission_generator.rb +57 -0
  69. data/lib/generators/rbac_rls/templates/group_permission_migration.rb +83 -0
  70. data/lib/generators/rbac_rls/templates/rls_migration.rb +81 -0
  71. data/lib/generators/rbac_rls/templates/rls_migration.rb.erb +64 -0
  72. data/lib/generators/rbac_rls/templates/rls_migration2.rb.erb +80 -0
  73. data/lib/rbac_rls/engine.rb +21 -0
  74. data/lib/rbac_rls/version.rb +3 -0
  75. data/lib/rbac_rls.rb +6 -0
  76. data/lib/tasks/rbac_rls_tasks.rake +4 -0
  77. metadata +192 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3bc52fa4bdbbc44cf0d4b6ede8d4d142458a169baed9767a30c1f6549a827520
4
+ data.tar.gz: d289b6293db261f8643b702a70c0f8d9affd094385a898e299f1e7b7d6966c25
5
+ SHA512:
6
+ metadata.gz: 6a7d8a952d7bbb5af6eedee3338ffd0ff76e71384eb82a2c7e0010f58855519cccb653e6b28e5ec29358b0c4a5f700d9663dfe0a372097d1fb2040ea60a5ff9c
7
+ data.tar.gz: ae99e701a1bce22e40993385b0f0644a6c49f2aa8e496cf7ed57cd4808133eb8d3ffeb15f70768389728321ddcd741184716a992f35e45dd0cad3aad9fa8528f
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,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ // = link rbac_rls/application.js
2
+ //= link rbac_rls/application.css
@@ -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,3 @@
1
+ class RbacRls::ApplicationController < ActionController::Base
2
+
3
+ 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(&params[: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,5 @@
1
+ class RbacRls::HomeController < RbacRls::ApplicationController
2
+ def index
3
+
4
+ end
5
+ 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,4 @@
1
+ module RbacRls
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module RbacRls
2
+ module GroupsHelper
3
+ end
4
+ 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,4 @@
1
+ module RbacRls
2
+ module RolesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module RbacRls
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module RbacRls
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ 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,3 @@
1
+ class RbacRls::ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ 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,7 @@
1
+ module RbacRls
2
+ class GroupUser < ApplicationRecord
3
+ self.table_name = :group_users
4
+ belongs_to :user
5
+ belongs_to :group
6
+ end
7
+ 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
+
@@ -0,0 +1,6 @@
1
+ class RbacRls::RolePermission < ApplicationRecord
2
+ belongs_to :role
3
+ belongs_to :permission
4
+
5
+ self.table_name = :role_permissions
6
+ end
@@ -0,0 +1,7 @@
1
+ module RbacRls
2
+ class UserRole < ApplicationRecord
3
+ self.table_name = :user_roles
4
+ belongs_to :user
5
+ belongs_to :role
6
+ end
7
+ end