rabarber 4.1.3 → 5.0.0
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/CHANGELOG.md +39 -3
- data/README.md +105 -77
- data/lib/rabarber/configuration.rb +14 -10
- data/lib/rabarber/controllers/concerns/authorization.rb +10 -10
- data/lib/rabarber/core/cache.rb +6 -6
- data/lib/rabarber/core/integrity_checker.rb +44 -0
- data/lib/rabarber/core/permissions.rb +5 -0
- data/lib/rabarber/core/roleable.rb +10 -3
- data/lib/rabarber/core/rule.rb +6 -4
- data/lib/rabarber/helpers/helpers.rb +4 -4
- data/lib/rabarber/helpers/migration_helpers.rb +29 -0
- data/lib/rabarber/input/ar_model.rb +23 -0
- data/lib/rabarber/models/concerns/has_roles.rb +0 -23
- data/lib/rabarber/models/role.rb +21 -29
- data/lib/rabarber/railtie.rb +26 -1
- data/lib/rabarber/version.rb +1 -1
- data/lib/rabarber.rb +4 -6
- data/rabarber.gemspec +3 -4
- metadata +13 -19
- data/lib/rabarber/audit/events/base.rb +0 -49
- data/lib/rabarber/audit/events/roles_assigned.rb +0 -31
- data/lib/rabarber/audit/events/roles_revoked.rb +0 -31
- data/lib/rabarber/audit/events/unauthorized_attempt.rb +0 -27
- data/lib/rabarber/audit/logger.rb +0 -23
- data/lib/rabarber/core/null_roleable.rb +0 -23
- data/lib/rabarber/core/permissions_integrity_checker.rb +0 -36
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabarber
|
4
|
+
module Core
|
5
|
+
module IntegrityChecker
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def run!
|
9
|
+
check_for_missing_class_context
|
10
|
+
prune_missing_instance_context
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def check_for_missing_class_context
|
16
|
+
Rabarber::Role.where.not(context_type: nil).distinct.pluck(:context_type).each do |context_class|
|
17
|
+
context_class.constantize
|
18
|
+
rescue NameError => e
|
19
|
+
raise Rabarber::Error, "Context not found: class #{e.name} may have been renamed or deleted"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def prune_missing_instance_context
|
24
|
+
ids = Rabarber::Role.where.not(context_id: nil).includes(:context).filter_map do |role|
|
25
|
+
role.context
|
26
|
+
nil
|
27
|
+
rescue ActiveRecord::RecordNotFound
|
28
|
+
role.id
|
29
|
+
end
|
30
|
+
|
31
|
+
return if ids.empty?
|
32
|
+
|
33
|
+
ActiveRecord::Base.transaction do
|
34
|
+
ActiveRecord::Base.connection.execute(
|
35
|
+
ActiveRecord::Base.sanitize_sql(
|
36
|
+
["DELETE FROM rabarber_roles_roleables WHERE role_id IN (?)", ids]
|
37
|
+
)
|
38
|
+
)
|
39
|
+
Rabarber::Role.where(id: ids).delete_all
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,12 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "null_roleable"
|
4
|
-
|
5
3
|
module Rabarber
|
6
4
|
module Core
|
7
5
|
module Roleable
|
8
6
|
def roleable
|
9
|
-
send(Rabarber::Configuration.instance.current_user_method)
|
7
|
+
current_roleable = send(Rabarber::Configuration.instance.current_user_method)
|
8
|
+
|
9
|
+
unless current_roleable.is_a?(Rabarber::Configuration.instance.user_model)
|
10
|
+
raise(
|
11
|
+
Rabarber::Error,
|
12
|
+
"Expected `#{Rabarber::Configuration.instance.current_user_method}` to return an instance of #{Rabarber::Configuration.instance.user_model_name}, but got #{current_roleable.inspect}"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
current_roleable
|
10
17
|
end
|
11
18
|
|
12
19
|
def roleable_roles(context: nil)
|
data/lib/rabarber/core/rule.rb
CHANGED
@@ -5,11 +5,15 @@ module Rabarber
|
|
5
5
|
class Rule
|
6
6
|
attr_reader :roles, :context, :dynamic_rule, :negated_dynamic_rule
|
7
7
|
|
8
|
+
DEFAULT_DYNAMIC_RULE = -> { true }.freeze
|
9
|
+
DEFAULT_NEGATED_DYNAMIC_RULE = -> { false }.freeze
|
10
|
+
private_constant :DEFAULT_DYNAMIC_RULE, :DEFAULT_NEGATED_DYNAMIC_RULE
|
11
|
+
|
8
12
|
def initialize(roles, context, dynamic_rule, negated_dynamic_rule)
|
9
13
|
@roles = Array(roles)
|
10
14
|
@context = context
|
11
|
-
@dynamic_rule = dynamic_rule ||
|
12
|
-
@negated_dynamic_rule = negated_dynamic_rule ||
|
15
|
+
@dynamic_rule = dynamic_rule || DEFAULT_DYNAMIC_RULE
|
16
|
+
@negated_dynamic_rule = negated_dynamic_rule || DEFAULT_NEGATED_DYNAMIC_RULE
|
13
17
|
end
|
14
18
|
|
15
19
|
def verify_access(roleable, controller_instance)
|
@@ -17,8 +21,6 @@ module Rabarber
|
|
17
21
|
end
|
18
22
|
|
19
23
|
def roles_permitted?(roleable, controller_instance)
|
20
|
-
return false if Rabarber::Configuration.instance.must_have_roles && roleable.all_roles.empty?
|
21
|
-
|
22
24
|
roles.empty? || roleable.has_role?(*roles, context: resolve_context(controller_instance))
|
23
25
|
end
|
24
26
|
|
@@ -4,12 +4,12 @@ module Rabarber
|
|
4
4
|
module Helpers
|
5
5
|
include Rabarber::Core::Roleable
|
6
6
|
|
7
|
-
def visible_to(*roles, context: nil, &
|
8
|
-
capture(&
|
7
|
+
def visible_to(*roles, context: nil, &)
|
8
|
+
capture(&) if roleable.has_role?(*roles, context:)
|
9
9
|
end
|
10
10
|
|
11
|
-
def hidden_from(*roles, context: nil, &
|
12
|
-
capture(&
|
11
|
+
def hidden_from(*roles, context: nil, &)
|
12
|
+
capture(&) unless roleable.has_role?(*roles, context:)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabarber
|
4
|
+
module MigrationHelpers
|
5
|
+
def migrate_authorization_context!(old_context, new_context)
|
6
|
+
roles = Rabarber::Role.where(context_type: old_context.to_s)
|
7
|
+
|
8
|
+
raise Rabarber::InvalidArgumentError, "No roles exist in context #{old_context.inspect}" unless roles.exists?
|
9
|
+
raise Rabarber::InvalidArgumentError, "Cannot migrate context to #{new_context.inspect}: class does not exist" unless new_context.to_s.safe_constantize
|
10
|
+
|
11
|
+
roles.update_all(context_type: new_context.to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete_authorization_context!(context)
|
15
|
+
roles = Rabarber::Role.where(context_type: context.to_s)
|
16
|
+
|
17
|
+
raise Rabarber::InvalidArgumentError, "No roles exist in context #{context.inspect}" unless roles.exists?
|
18
|
+
|
19
|
+
ActiveRecord::Base.transaction do
|
20
|
+
ActiveRecord::Base.connection.execute(
|
21
|
+
ActiveRecord::Base.sanitize_sql(
|
22
|
+
["DELETE FROM rabarber_roles_roleables WHERE role_id IN (?)", roles.pluck(:id)]
|
23
|
+
)
|
24
|
+
)
|
25
|
+
roles.delete_all
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabarber
|
4
|
+
module Input
|
5
|
+
class ArModel < Rabarber::Input::Base
|
6
|
+
def valid?
|
7
|
+
processed_value < ActiveRecord::Base
|
8
|
+
rescue NameError
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def processed_value
|
15
|
+
value.constantize
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_error_message
|
19
|
+
"Value must be an ActiveRecord model"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -42,13 +42,6 @@ module Rabarber
|
|
42
42
|
if roles_to_assign.any?
|
43
43
|
delete_roleable_cache(context: processed_context)
|
44
44
|
rabarber_roles << roles_to_assign
|
45
|
-
|
46
|
-
Rabarber::Audit::Events::RolesAssigned.trigger(
|
47
|
-
self,
|
48
|
-
roles_to_assign: roles_to_assign.names(context: processed_context),
|
49
|
-
current_roles: roles(context: processed_context),
|
50
|
-
context: processed_context
|
51
|
-
)
|
52
45
|
end
|
53
46
|
|
54
47
|
roles(context: processed_context)
|
@@ -65,27 +58,11 @@ module Rabarber
|
|
65
58
|
if roles_to_revoke.any?
|
66
59
|
delete_roleable_cache(context: processed_context)
|
67
60
|
self.rabarber_roles -= roles_to_revoke
|
68
|
-
|
69
|
-
Rabarber::Audit::Events::RolesRevoked.trigger(
|
70
|
-
self,
|
71
|
-
roles_to_revoke: roles_to_revoke.names(context: processed_context),
|
72
|
-
current_roles: roles(context: processed_context),
|
73
|
-
context: processed_context
|
74
|
-
)
|
75
61
|
end
|
76
62
|
|
77
63
|
roles(context: processed_context)
|
78
64
|
end
|
79
65
|
|
80
|
-
def log_identity
|
81
|
-
"#{model_name.human}##{roleable_id}"
|
82
|
-
end
|
83
|
-
|
84
|
-
def roleable_class
|
85
|
-
@@included.constantize
|
86
|
-
end
|
87
|
-
module_function :roleable_class
|
88
|
-
|
89
66
|
private
|
90
67
|
|
91
68
|
def create_new_roles(role_names, context:)
|
data/lib/rabarber/models/role.rb
CHANGED
@@ -11,7 +11,9 @@ module Rabarber
|
|
11
11
|
|
12
12
|
belongs_to :context, polymorphic: true, optional: true
|
13
13
|
|
14
|
-
|
14
|
+
has_and_belongs_to_many :roleables, class_name: Rabarber::Configuration.instance.user_model_name,
|
15
|
+
association_foreign_key: "roleable_id",
|
16
|
+
join_table: "rabarber_roles_roleables"
|
15
17
|
|
16
18
|
class << self
|
17
19
|
def names(context: nil)
|
@@ -19,11 +21,13 @@ module Rabarber
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def all_names
|
22
|
-
includes(:context).
|
23
|
-
|
24
|
-
|
24
|
+
includes(:context).each_with_object({}) do |role, hash|
|
25
|
+
(hash[role.context] ||= []) << role.name.to_sym
|
26
|
+
rescue ActiveRecord::RecordNotFound
|
27
|
+
next
|
28
|
+
end
|
25
29
|
rescue NameError => e
|
26
|
-
raise Rabarber::
|
30
|
+
raise Rabarber::NotFoundError, "Context not found: class #{e.name} may have been renamed or deleted"
|
27
31
|
end
|
28
32
|
|
29
33
|
def add(name, context: nil)
|
@@ -38,9 +42,12 @@ module Rabarber
|
|
38
42
|
def rename(old_name, new_name, context: nil, force: false)
|
39
43
|
processed_context = process_context(context)
|
40
44
|
role = find_by(name: process_role_name(old_name), **processed_context)
|
45
|
+
|
46
|
+
raise Rabarber::NotFoundError, "Role not found" unless role
|
47
|
+
|
41
48
|
name = process_role_name(new_name)
|
42
49
|
|
43
|
-
return false if
|
50
|
+
return false if exists?(name:, **processed_context) || role.roleables.exists? && !force
|
44
51
|
|
45
52
|
delete_roleables_cache(role, context: processed_context)
|
46
53
|
|
@@ -51,7 +58,9 @@ module Rabarber
|
|
51
58
|
processed_context = process_context(context)
|
52
59
|
role = find_by(name: process_role_name(name), **processed_context)
|
53
60
|
|
54
|
-
|
61
|
+
raise Rabarber::NotFoundError, "Role not found" unless role
|
62
|
+
|
63
|
+
return false if role.roleables.exists? && !force
|
55
64
|
|
56
65
|
delete_roleables_cache(role, context: processed_context)
|
57
66
|
|
@@ -59,23 +68,16 @@ module Rabarber
|
|
59
68
|
end
|
60
69
|
|
61
70
|
def assignees(name, context: nil)
|
62
|
-
|
63
|
-
|
64
|
-
)
|
71
|
+
find_by(name: process_role_name(name), **process_context(context))&.roleables ||
|
72
|
+
Rabarber::Configuration.instance.user_model.none
|
65
73
|
end
|
66
74
|
|
67
75
|
private
|
68
76
|
|
69
77
|
def delete_roleables_cache(role, context:)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def assigned_to_roleables(role)
|
74
|
-
ActiveRecord::Base.connection.select_values(
|
75
|
-
ActiveRecord::Base.sanitize_sql(
|
76
|
-
["SELECT roleable_id FROM rabarber_roles_roleables WHERE role_id = ?", role.id]
|
77
|
-
)
|
78
|
-
)
|
78
|
+
role.roleables.in_batches(of: 1000) do |batch|
|
79
|
+
Rabarber::Core::Cache.delete(*batch.pluck(:id).flat_map { [[_1, context], [_1, :all]] })
|
80
|
+
end
|
79
81
|
end
|
80
82
|
|
81
83
|
def process_role_name(name)
|
@@ -96,15 +98,5 @@ module Rabarber
|
|
96
98
|
|
97
99
|
record
|
98
100
|
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def delete_assignments
|
103
|
-
ActiveRecord::Base.connection.execute(
|
104
|
-
ActiveRecord::Base.sanitize_sql(
|
105
|
-
["DELETE FROM rabarber_roles_roleables WHERE role_id = ?", id]
|
106
|
-
)
|
107
|
-
)
|
108
|
-
end
|
109
101
|
end
|
110
102
|
end
|
data/lib/rabarber/railtie.rb
CHANGED
@@ -4,9 +4,34 @@ require "rails/railtie"
|
|
4
4
|
|
5
5
|
module Rabarber
|
6
6
|
class Railtie < Rails::Railtie
|
7
|
+
initializer "rabarber.to_prepare" do |app|
|
8
|
+
app.config.to_prepare do
|
9
|
+
unless app.config.eager_load
|
10
|
+
Rabarber::Core::Permissions.reset!
|
11
|
+
ApplicationController.class_eval do
|
12
|
+
before_action :check_integrity
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def check_integrity
|
17
|
+
Rabarber::Core::IntegrityChecker.run!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
user_model = Rabarber::Configuration.instance.user_model
|
22
|
+
user_model.include Rabarber::HasRoles unless user_model < Rabarber::HasRoles
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
initializer "rabarber.after_initialize" do |app|
|
8
27
|
app.config.after_initialize do
|
9
|
-
Rabarber::Core::
|
28
|
+
Rabarber::Core::IntegrityChecker.run! if app.config.eager_load
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
initializer "rabarber.extend_migration_helpers" do
|
33
|
+
ActiveSupport.on_load :active_record do
|
34
|
+
ActiveRecord::Migration.include Rabarber::MigrationHelpers
|
10
35
|
end
|
11
36
|
end
|
12
37
|
end
|
data/lib/rabarber/version.rb
CHANGED
data/lib/rabarber.rb
CHANGED
@@ -8,6 +8,7 @@ require "active_support"
|
|
8
8
|
|
9
9
|
require_relative "rabarber/input/base"
|
10
10
|
require_relative "rabarber/input/action"
|
11
|
+
require_relative "rabarber/input/ar_model"
|
11
12
|
require_relative "rabarber/input/authorization_context"
|
12
13
|
require_relative "rabarber/input/context"
|
13
14
|
require_relative "rabarber/input/dynamic_rule"
|
@@ -19,20 +20,16 @@ require_relative "rabarber/input/types/symbol"
|
|
19
20
|
|
20
21
|
require_relative "rabarber/core/cache"
|
21
22
|
|
22
|
-
require_relative "rabarber/audit/events/base"
|
23
|
-
require_relative "rabarber/audit/events/roles_assigned"
|
24
|
-
require_relative "rabarber/audit/events/roles_revoked"
|
25
|
-
require_relative "rabarber/audit/events/unauthorized_attempt"
|
26
|
-
|
27
23
|
require_relative "rabarber/core/roleable"
|
28
24
|
|
29
25
|
require_relative "rabarber/controllers/concerns/authorization"
|
30
26
|
require_relative "rabarber/helpers/helpers"
|
27
|
+
require_relative "rabarber/helpers/migration_helpers"
|
31
28
|
require_relative "rabarber/models/concerns/has_roles"
|
32
29
|
require_relative "rabarber/models/role"
|
33
30
|
|
34
31
|
require_relative "rabarber/core/permissions"
|
35
|
-
require_relative "rabarber/core/
|
32
|
+
require_relative "rabarber/core/integrity_checker"
|
36
33
|
|
37
34
|
require_relative "rabarber/railtie"
|
38
35
|
|
@@ -40,6 +37,7 @@ module Rabarber
|
|
40
37
|
class Error < StandardError; end
|
41
38
|
class ConfigurationError < Rabarber::Error; end
|
42
39
|
class InvalidArgumentError < Rabarber::Error; end
|
40
|
+
class NotFoundError < Rabarber::Error; end
|
43
41
|
|
44
42
|
def configure
|
45
43
|
yield(Rabarber::Configuration.instance)
|
data/rabarber.gemspec
CHANGED
@@ -6,15 +6,14 @@ Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "rabarber"
|
7
7
|
spec.version = Rabarber::VERSION
|
8
8
|
spec.authors = ["enjaku4", "trafium"]
|
9
|
-
spec.
|
10
|
-
spec.homepage = "https://github.com/enjaku4/rabarber"
|
9
|
+
spec.homepage = "https://github.com/brownboxdev/rabarber"
|
11
10
|
spec.metadata["homepage_uri"] = spec.homepage
|
12
11
|
spec.metadata["source_code_uri"] = spec.homepage
|
13
12
|
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
14
13
|
spec.metadata["rubygems_mfa_required"] = "true"
|
15
14
|
spec.summary = "Simple role-based authorization library for Ruby on Rails"
|
16
15
|
spec.license = "MIT"
|
17
|
-
spec.required_ruby_version = ">= 3.
|
16
|
+
spec.required_ruby_version = ">= 3.2", "< 3.5"
|
18
17
|
|
19
18
|
spec.files = [
|
20
19
|
"rabarber.gemspec", "README.md", "CHANGELOG.md", "LICENSE.txt"
|
@@ -22,5 +21,5 @@ Gem::Specification.new do |spec|
|
|
22
21
|
|
23
22
|
spec.require_paths = ["lib"]
|
24
23
|
|
25
|
-
spec.add_dependency "rails", ">= 7.
|
24
|
+
spec.add_dependency "rails", ">= 7.1", "< 8.1"
|
26
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabarber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- enjaku4
|
8
8
|
- trafium
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '7.
|
19
|
+
version: '7.1'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '8.1'
|
@@ -26,12 +26,10 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '7.
|
29
|
+
version: '7.1'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '8.1'
|
33
|
-
email:
|
34
|
-
- rabarber_gem@icloud.com
|
35
33
|
executables: []
|
36
34
|
extensions: []
|
37
35
|
extra_rdoc_files: []
|
@@ -42,22 +40,18 @@ files:
|
|
42
40
|
- lib/generators/rabarber/roles_generator.rb
|
43
41
|
- lib/generators/rabarber/templates/create_rabarber_roles.rb.erb
|
44
42
|
- lib/rabarber.rb
|
45
|
-
- lib/rabarber/audit/events/base.rb
|
46
|
-
- lib/rabarber/audit/events/roles_assigned.rb
|
47
|
-
- lib/rabarber/audit/events/roles_revoked.rb
|
48
|
-
- lib/rabarber/audit/events/unauthorized_attempt.rb
|
49
|
-
- lib/rabarber/audit/logger.rb
|
50
43
|
- lib/rabarber/configuration.rb
|
51
44
|
- lib/rabarber/controllers/concerns/authorization.rb
|
52
45
|
- lib/rabarber/core/access.rb
|
53
46
|
- lib/rabarber/core/cache.rb
|
54
|
-
- lib/rabarber/core/
|
47
|
+
- lib/rabarber/core/integrity_checker.rb
|
55
48
|
- lib/rabarber/core/permissions.rb
|
56
|
-
- lib/rabarber/core/permissions_integrity_checker.rb
|
57
49
|
- lib/rabarber/core/roleable.rb
|
58
50
|
- lib/rabarber/core/rule.rb
|
59
51
|
- lib/rabarber/helpers/helpers.rb
|
52
|
+
- lib/rabarber/helpers/migration_helpers.rb
|
60
53
|
- lib/rabarber/input/action.rb
|
54
|
+
- lib/rabarber/input/ar_model.rb
|
61
55
|
- lib/rabarber/input/authorization_context.rb
|
62
56
|
- lib/rabarber/input/base.rb
|
63
57
|
- lib/rabarber/input/context.rb
|
@@ -72,13 +66,13 @@ files:
|
|
72
66
|
- lib/rabarber/railtie.rb
|
73
67
|
- lib/rabarber/version.rb
|
74
68
|
- rabarber.gemspec
|
75
|
-
homepage: https://github.com/
|
69
|
+
homepage: https://github.com/brownboxdev/rabarber
|
76
70
|
licenses:
|
77
71
|
- MIT
|
78
72
|
metadata:
|
79
|
-
homepage_uri: https://github.com/
|
80
|
-
source_code_uri: https://github.com/
|
81
|
-
changelog_uri: https://github.com/
|
73
|
+
homepage_uri: https://github.com/brownboxdev/rabarber
|
74
|
+
source_code_uri: https://github.com/brownboxdev/rabarber
|
75
|
+
changelog_uri: https://github.com/brownboxdev/rabarber/blob/main/CHANGELOG.md
|
82
76
|
rubygems_mfa_required: 'true'
|
83
77
|
rdoc_options: []
|
84
78
|
require_paths:
|
@@ -87,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
81
|
requirements:
|
88
82
|
- - ">="
|
89
83
|
- !ruby/object:Gem::Version
|
90
|
-
version: '3.
|
84
|
+
version: '3.2'
|
91
85
|
- - "<"
|
92
86
|
- !ruby/object:Gem::Version
|
93
87
|
version: '3.5'
|
@@ -97,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
91
|
- !ruby/object:Gem::Version
|
98
92
|
version: '0'
|
99
93
|
requirements: []
|
100
|
-
rubygems_version: 3.6.
|
94
|
+
rubygems_version: 3.6.7
|
101
95
|
specification_version: 4
|
102
96
|
summary: Simple role-based authorization library for Ruby on Rails
|
103
97
|
test_files: []
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../logger"
|
4
|
-
|
5
|
-
module Rabarber
|
6
|
-
module Audit
|
7
|
-
module Events
|
8
|
-
class Base
|
9
|
-
attr_reader :roleable, :specifics
|
10
|
-
|
11
|
-
def self.trigger(roleable, specifics)
|
12
|
-
new(roleable, specifics).send(:log)
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def initialize(roleable, specifics)
|
18
|
-
@roleable = roleable
|
19
|
-
@specifics = specifics
|
20
|
-
end
|
21
|
-
|
22
|
-
def log
|
23
|
-
Rabarber::Audit::Logger.log(log_level, message)
|
24
|
-
end
|
25
|
-
|
26
|
-
def log_level
|
27
|
-
raise NotImplementedError
|
28
|
-
end
|
29
|
-
|
30
|
-
def message
|
31
|
-
raise NotImplementedError
|
32
|
-
end
|
33
|
-
|
34
|
-
def identity
|
35
|
-
roleable.log_identity
|
36
|
-
end
|
37
|
-
|
38
|
-
def human_context
|
39
|
-
case context
|
40
|
-
in { context_type: nil, context_id: nil } then "Global"
|
41
|
-
in { context_type:, context_id: nil } then context_type
|
42
|
-
in { context_type:, context_id: } then "#{context_type}##{context_id}"
|
43
|
-
else raise Rabarber::Error, "Unexpected context: #{context.inspect}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Rabarber
|
4
|
-
module Audit
|
5
|
-
module Events
|
6
|
-
class RolesAssigned < Base
|
7
|
-
private
|
8
|
-
|
9
|
-
def log_level
|
10
|
-
:info
|
11
|
-
end
|
12
|
-
|
13
|
-
def message
|
14
|
-
"[Role Assignment] #{identity} | context: #{human_context} | assigned: #{roles_to_assign} | current: #{current_roles}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def context
|
18
|
-
specifics.fetch(:context)
|
19
|
-
end
|
20
|
-
|
21
|
-
def roles_to_assign
|
22
|
-
specifics.fetch(:roles_to_assign)
|
23
|
-
end
|
24
|
-
|
25
|
-
def current_roles
|
26
|
-
specifics.fetch(:current_roles)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Rabarber
|
4
|
-
module Audit
|
5
|
-
module Events
|
6
|
-
class RolesRevoked < Base
|
7
|
-
private
|
8
|
-
|
9
|
-
def log_level
|
10
|
-
:info
|
11
|
-
end
|
12
|
-
|
13
|
-
def message
|
14
|
-
"[Role Revocation] #{identity} | context: #{human_context} | revoked: #{roles_to_revoke} | current: #{current_roles}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def context
|
18
|
-
specifics.fetch(:context)
|
19
|
-
end
|
20
|
-
|
21
|
-
def roles_to_revoke
|
22
|
-
specifics.fetch(:roles_to_revoke)
|
23
|
-
end
|
24
|
-
|
25
|
-
def current_roles
|
26
|
-
specifics.fetch(:current_roles)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Rabarber
|
4
|
-
module Audit
|
5
|
-
module Events
|
6
|
-
class UnauthorizedAttempt < Base
|
7
|
-
private
|
8
|
-
|
9
|
-
def log_level
|
10
|
-
:warn
|
11
|
-
end
|
12
|
-
|
13
|
-
def message
|
14
|
-
"[Unauthorized Attempt] #{identity} | request: #{request_method} #{path}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def path
|
18
|
-
specifics.fetch(:path)
|
19
|
-
end
|
20
|
-
|
21
|
-
def request_method
|
22
|
-
specifics.fetch(:request_method)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|