rabarber 6.0.0 → 6.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/CHANGELOG.md +22 -0
- data/README.md +15 -11
- data/lib/generators/rabarber/templates/create_rabarber_roles.rb.erb +5 -0
- data/lib/rabarber/core/cache.rb +5 -2
- data/lib/rabarber/models/concerns/roleable.rb +8 -4
- data/lib/rabarber/models/role.rb +18 -10
- data/lib/rabarber/railtie.rb +5 -0
- data/lib/rabarber/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cb92ea0f4a25ee7dd730aae35b07d16230434393882cd0833d853117e7887e9
|
|
4
|
+
data.tar.gz: 3056af62a93df97b88f708dc725e0b54c92cfc198aad225ba80262fcfd36a31a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e599ea0709127eeed62dd0aae019f9dee5a73843e08671089e1a84b16e13a2db4ad8f908080b51f3a5a8d2fa82d9a7f21efed638dd6e1054f5c80fdb8b5f423
|
|
7
|
+
data.tar.gz: 0b2548c277de1beb990d9ce0321b0989d7358c521e3cb0d20994cf389ea931feb288dc670d7e886c6a1ccff29dc4d7bdd7c1a07885f0ad327f7b94e3cf8d6f82
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
## v6.0.1
|
|
2
|
+
|
|
3
|
+
### Bugs:
|
|
4
|
+
|
|
5
|
+
- Fixed role management methods raising `NameError` when the configured user model is not named `User`
|
|
6
|
+
- Fixed a race condition where outdated roles could remain cached after being changed
|
|
7
|
+
- Fixed role creation and renaming raising `ActiveRecord::RecordNotUnique` instead of returning `false` when called concurrently
|
|
8
|
+
- Fixed uniqueness of global and class context roles not being enforced at the database level
|
|
9
|
+
|
|
10
|
+
This release is fully backward compatible: existing applications continue to work as before without any changes. The new indexes only apply to new applications installing Rabarber. To get the same database-level protection in an existing application, run the following optional migration if your database supports partial indexes:
|
|
11
|
+
|
|
12
|
+
```rb
|
|
13
|
+
add_index :rabarber_roles, :name, unique: true, where: "context_type IS NULL AND context_id IS NULL"
|
|
14
|
+
add_index :rabarber_roles, [:name, :context_type], unique: true, where: "context_type IS NOT NULL AND context_id IS NULL"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
On databases without partial index support, such as MySQL, uniqueness of global and class context roles remains, for now, enforced at the application level only.
|
|
18
|
+
|
|
19
|
+
### Misc:
|
|
20
|
+
|
|
21
|
+
- `Rabarber.prune` now clears the role cache
|
|
22
|
+
|
|
1
23
|
## v6.0.0
|
|
2
24
|
|
|
3
25
|
### Breaking:
|
data/README.md
CHANGED
|
@@ -218,7 +218,7 @@ class TicketsController < ApplicationController
|
|
|
218
218
|
end
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
Authorization rules are additive -
|
|
221
|
+
Authorization rules are additive - rules defined multiple times combine, and controller-wide rules are inherited by subclasses:
|
|
222
222
|
|
|
223
223
|
```rb
|
|
224
224
|
class BaseController < ApplicationController
|
|
@@ -459,27 +459,31 @@ Use conditional rendering based on roles:
|
|
|
459
459
|
<% end %>
|
|
460
460
|
```
|
|
461
461
|
|
|
462
|
+
Like authorization, these helpers require an authenticated user. In views that can be rendered for both authenticated and unauthenticated visitors, wrap them in your authentication check.
|
|
463
|
+
|
|
462
464
|
## Getting Help and Contributing
|
|
463
465
|
|
|
464
466
|
### Getting Help
|
|
467
|
+
|
|
465
468
|
Have a question or need assistance? Open a discussion in the [discussions section](https://github.com/enjaku4/rabarber/discussions) for:
|
|
469
|
+
|
|
466
470
|
- Usage questions
|
|
467
471
|
- Implementation guidance
|
|
468
|
-
-
|
|
472
|
+
- Open-ended ideas or suggestions
|
|
473
|
+
|
|
474
|
+
### Issues
|
|
475
|
+
|
|
476
|
+
[Issues](https://github.com/enjaku4/rabarber/issues) track bugs, planned features, and other work. When reporting a bug, please include:
|
|
469
477
|
|
|
470
|
-
### Reporting Issues
|
|
471
|
-
Found a bug? Please [create an issue](https://github.com/enjaku4/rabarber/issues) with:
|
|
472
478
|
- A clear description of the problem
|
|
473
479
|
- Steps to reproduce the issue
|
|
474
|
-
- Your environment details (Rails
|
|
480
|
+
- Your environment details (Rails and Ruby versions, OS, etc.)
|
|
475
481
|
|
|
476
482
|
### Contributing Code
|
|
477
|
-
Ready to contribute? You can:
|
|
478
|
-
- Fix bugs by submitting pull requests
|
|
479
|
-
- Improve documentation
|
|
480
|
-
- Add new features (please discuss first in the [discussions section](https://github.com/enjaku4/rabarber/discussions))
|
|
481
483
|
|
|
482
|
-
|
|
484
|
+
Any open issue is free to pick up or discuss. Check the [project board](https://github.com/users/enjaku4/projects/10) or [issues tab](https://github.com/enjaku4/rabarber/issues).
|
|
485
|
+
|
|
486
|
+
Before contributing, please read the [contributing guidelines](https://github.com/enjaku4/rabarber/blob/main/CONTRIBUTING.md).
|
|
483
487
|
|
|
484
488
|
## License
|
|
485
489
|
|
|
@@ -491,7 +495,7 @@ Everyone interacting in the Rabarber project is expected to follow the [code of
|
|
|
491
495
|
|
|
492
496
|
## Old Versions
|
|
493
497
|
|
|
494
|
-
Only the latest major version is
|
|
498
|
+
Only the latest major version is actively maintained. READMEs for older versions are available here for reference:
|
|
495
499
|
|
|
496
500
|
[v5.x.x](https://github.com/enjaku4/rabarber/blob/12a23858e974f5cc0a4ebddfc18bdf84171dd554/README.md) | [v4.x.x](https://github.com/enjaku4/rabarber/blob/9353e70281971154d5acd70693620197a132c543/README.md) | [v3.x.x](https://github.com/enjaku4/rabarber/blob/3bb273de7e342004abc7ef07fa4d0a9a3ce3e249/README.md)
|
|
497
501
|
| [v2.x.x](https://github.com/enjaku4/rabarber/blob/875b357ea949404ddc3645ad66eddea7ed4e2ee4/README.md) | [v1.x.x](https://github.com/enjaku4/rabarber/blob/b81428429404e197d70317b763e7b2a21e02c296/README.md)
|
|
@@ -10,6 +10,11 @@ class CreateRabarberRoles < ActiveRecord::Migration[<%= ActiveRecord::Migration.
|
|
|
10
10
|
|
|
11
11
|
add_index :rabarber_roles, [:name, :context_type, :context_id], unique: true
|
|
12
12
|
|
|
13
|
+
if connection.supports_partial_index?
|
|
14
|
+
add_index :rabarber_roles, :name, unique: true, where: "context_type IS NULL AND context_id IS NULL"
|
|
15
|
+
add_index :rabarber_roles, [:name, :context_type], unique: true, where: "context_type IS NOT NULL AND context_id IS NULL"
|
|
16
|
+
end
|
|
17
|
+
|
|
13
18
|
create_table :rabarber_roles_roleables, id: false do |t|
|
|
14
19
|
t.belongs_to :role, null: false, index: true, foreign_key: { to_table: :rabarber_roles }<%= ", type: :uuid" if options[:uuid] %>
|
|
15
20
|
t.belongs_to :roleable, null: false, index: true, foreign_key: { to_table: <%= table_name.to_sym.inspect %> }<%= ", type: :uuid" if options[:uuid] %>
|
data/lib/rabarber/core/cache.rb
CHANGED
|
@@ -15,9 +15,12 @@ module Rabarber
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def delete(*pairs)
|
|
18
|
-
return unless enabled?
|
|
18
|
+
return unless enabled? && pairs.any?
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
keys = pairs.map { |roleable_id, scope| prepare_key(roleable_id, scope) }
|
|
21
|
+
|
|
22
|
+
Rails.cache.delete_multi(keys)
|
|
23
|
+
ActiveRecord.after_all_transactions_commit { Rails.cache.delete_multi(keys) } if ActiveRecord::Base.connection.transaction_open?
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def clear
|
|
@@ -50,7 +50,7 @@ module Rabarber
|
|
|
50
50
|
def has_role?(*role_names, context: nil)
|
|
51
51
|
processed_context = process_context(context)
|
|
52
52
|
processed_roles = process_role_names(role_names)
|
|
53
|
-
roles(context: processed_context).
|
|
53
|
+
roles(context: processed_context).intersect?(processed_roles)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def assign_roles(*role_names, context: nil, create_new: true)
|
|
@@ -64,8 +64,12 @@ module Rabarber
|
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
if roles_to_assign.any?
|
|
67
|
+
begin
|
|
68
|
+
rabarber_roles << roles_to_assign
|
|
69
|
+
rescue ActiveRecord::RecordNotUnique
|
|
70
|
+
rabarber_roles.reset
|
|
71
|
+
end
|
|
67
72
|
delete_roleable_cache(contexts: [processed_context])
|
|
68
|
-
rabarber_roles << roles_to_assign
|
|
69
73
|
end
|
|
70
74
|
|
|
71
75
|
roles(context: processed_context)
|
|
@@ -80,8 +84,8 @@ module Rabarber
|
|
|
80
84
|
)
|
|
81
85
|
|
|
82
86
|
if roles_to_revoke.any?
|
|
83
|
-
delete_roleable_cache(contexts: [processed_context])
|
|
84
87
|
self.rabarber_roles -= roles_to_revoke
|
|
88
|
+
delete_roleable_cache(contexts: [processed_context])
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
roles(context: processed_context)
|
|
@@ -103,7 +107,7 @@ module Rabarber
|
|
|
103
107
|
|
|
104
108
|
def create_new_roles(role_names, context:)
|
|
105
109
|
new_roles = role_names - Rabarber.roles(context:)
|
|
106
|
-
new_roles.each { |role_name| Rabarber::Role.
|
|
110
|
+
new_roles.each { |role_name| Rabarber::Role.register(role_name, context:) }
|
|
107
111
|
end
|
|
108
112
|
|
|
109
113
|
def delete_roleable_cache(contexts:)
|
data/lib/rabarber/models/role.rb
CHANGED
|
@@ -6,10 +6,6 @@ module Rabarber
|
|
|
6
6
|
|
|
7
7
|
belongs_to :context, polymorphic: true, optional: true
|
|
8
8
|
|
|
9
|
-
has_and_belongs_to_many :roleables, class_name: Rabarber::Configuration.user_model_name,
|
|
10
|
-
association_foreign_key: "roleable_id",
|
|
11
|
-
join_table: "rabarber_roles_roleables"
|
|
12
|
-
|
|
13
9
|
class << self
|
|
14
10
|
def list(context: nil)
|
|
15
11
|
where(process_context(context)).pluck(:name).map(&:to_sym)
|
|
@@ -32,6 +28,8 @@ module Rabarber
|
|
|
32
28
|
return false if exists?(name:, **processed_context)
|
|
33
29
|
|
|
34
30
|
!!create!(name:, **processed_context)
|
|
31
|
+
rescue ActiveRecord::RecordNotUnique
|
|
32
|
+
false
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
def amend(old_name, new_name, context: nil, force: false)
|
|
@@ -44,9 +42,13 @@ module Rabarber
|
|
|
44
42
|
|
|
45
43
|
return false if exists?(name:, **processed_context) || role.roleables.exists? && !force
|
|
46
44
|
|
|
47
|
-
delete_roleables_cache(role, context: processed_context)
|
|
48
|
-
|
|
49
45
|
role.update!(name:)
|
|
46
|
+
|
|
47
|
+
delete_roleables_cache(role.roleables.pluck(:id), context: processed_context)
|
|
48
|
+
|
|
49
|
+
true
|
|
50
|
+
rescue ActiveRecord::RecordNotUnique
|
|
51
|
+
false
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
def drop(name, context: nil, force: false)
|
|
@@ -57,9 +59,13 @@ module Rabarber
|
|
|
57
59
|
|
|
58
60
|
return false if role.roleables.exists? && !force
|
|
59
61
|
|
|
60
|
-
|
|
62
|
+
roleable_ids = role.roleables.pluck(:id)
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
role.destroy!
|
|
65
|
+
|
|
66
|
+
delete_roleables_cache(roleable_ids, context: processed_context)
|
|
67
|
+
|
|
68
|
+
true
|
|
63
69
|
end
|
|
64
70
|
|
|
65
71
|
def prune
|
|
@@ -79,12 +85,14 @@ module Rabarber
|
|
|
79
85
|
)
|
|
80
86
|
where(id: orphaned_roles).delete_all
|
|
81
87
|
end
|
|
88
|
+
|
|
89
|
+
Rabarber::Core::Cache.clear
|
|
82
90
|
end
|
|
83
91
|
|
|
84
92
|
private
|
|
85
93
|
|
|
86
|
-
def delete_roleables_cache(
|
|
87
|
-
Rabarber::Core::Cache.delete(*
|
|
94
|
+
def delete_roleables_cache(roleable_ids, context:)
|
|
95
|
+
Rabarber::Core::Cache.delete(*roleable_ids.flat_map { [[_1, context], [_1, :all]] })
|
|
88
96
|
end
|
|
89
97
|
|
|
90
98
|
def process_role_name(name)
|
data/lib/rabarber/railtie.rb
CHANGED
|
@@ -28,6 +28,11 @@ module Rabarber
|
|
|
28
28
|
|
|
29
29
|
user_model = Rabarber::Configuration.user_model
|
|
30
30
|
user_model.include Rabarber::Roleable unless user_model < Rabarber::Roleable
|
|
31
|
+
|
|
32
|
+
Rabarber::Role.send(:remove_const, :HABTM_Roleables) if Rabarber::Role.const_defined?(:HABTM_Roleables, false)
|
|
33
|
+
Rabarber::Role.has_and_belongs_to_many :roleables, class_name: Rabarber::Configuration.user_model_name,
|
|
34
|
+
association_foreign_key: "roleable_id",
|
|
35
|
+
join_table: "rabarber_roles_roleables"
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
|
data/lib/rabarber/version.rb
CHANGED
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: 6.0.
|
|
4
|
+
version: 6.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- enjaku4
|
|
8
8
|
- trafium
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
- !ruby/object:Gem::Version
|
|
99
99
|
version: '0'
|
|
100
100
|
requirements: []
|
|
101
|
-
rubygems_version: 4.0.
|
|
101
|
+
rubygems_version: 4.0.15
|
|
102
102
|
specification_version: 4
|
|
103
103
|
summary: Simple role-based authorization library for Ruby on Rails
|
|
104
104
|
test_files: []
|