bullet_train-roles 1.2.26 → 1.3.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/Gemfile.lock +1 -1
- data/README.md +68 -7
- data/bullet_train-roles.gemspec +1 -1
- data/lib/bullet_train/roles/version.rb +1 -1
- data/lib/models/role.rb +8 -2
- data/lib/roles/support.rb +14 -0
- 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: 3f8c33aae9d0e533cc182a9d259bc4ac2ee4b112adbc9459d11fcefcb42dd887
|
4
|
+
data.tar.gz: 88657dc68c22e4a9772e4609707e31f551249c078d940f1865b3b84f0fda11d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d74e06824a7f9888c93cba13d52e2412cb0b5a99025c8182038850f1e64205412fd60b2712e35f595958ffcf164a420749494db8eecf6422d19f686913543b5
|
7
|
+
data.tar.gz: 84a7524e8de44d2d34a5cd547d44da44081d052f168110c344a40188446a151bdd6c2e888bd32a170d5a8282a2cfaec1c63ca5a5c2c91c3361b1db937227519d
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -58,7 +58,7 @@ The provided `Role` model is backed by a Yaml configuration in `config/models/ro
|
|
58
58
|
|
59
59
|
To help explain this configuration and its options, we'll provide the following hypothetical example:
|
60
60
|
|
61
|
-
```
|
61
|
+
```yaml
|
62
62
|
default:
|
63
63
|
models:
|
64
64
|
Project: read
|
@@ -92,6 +92,8 @@ Here's a breakdown of the structure of the configuration file:
|
|
92
92
|
- `manageable_roles` provides a list of roles that can be assigned to other users by members that have the role being defined.
|
93
93
|
- `includes` provides a list of other roles whose permissions should also be made available to members with the role being defined.
|
94
94
|
- `manage`, `read`, etc. are all CanCanCan-defined actions that can be granted.
|
95
|
+
- `crud` is a special value that we substitute for the 4 CRUD actions - create, read, update and destroy.
|
96
|
+
This is instead of `manage` which covers all actions - 4 CRUD actions _and_ any extra actions the controller may respond to
|
95
97
|
|
96
98
|
The following things are true given the example configuration above:
|
97
99
|
|
@@ -111,7 +113,7 @@ The following things are true given the example configuration above:
|
|
111
113
|
|
112
114
|
You can also grant more granular permissions by supplying a list of the specific actions per resource, like so:
|
113
115
|
|
114
|
-
```
|
116
|
+
```yaml
|
115
117
|
editor:
|
116
118
|
models:
|
117
119
|
project:
|
@@ -123,7 +125,7 @@ editor:
|
|
123
125
|
|
124
126
|
All of these definitions are interpreted and translated into CanCanCan directives when we invoke the following Bullet Train helper in `app/models/ability.rb`:
|
125
127
|
|
126
|
-
```
|
128
|
+
```ruby
|
127
129
|
permit user, through: :memberships, parent: :team
|
128
130
|
```
|
129
131
|
|
@@ -136,7 +138,7 @@ In the example above:
|
|
136
138
|
|
137
139
|
To illustrate the flexibility of this approach, consider that you may want to grant non-administrative team members different permissions for different `Project` objects on a `Team`. In that case, `permit` actually allows us to re-use the same role definitions to assign permissions that are scoped by a specific resource, like this:
|
138
140
|
|
139
|
-
```
|
141
|
+
```ruby
|
140
142
|
permit user, through: :projects_collaborators, parent: :project
|
141
143
|
```
|
142
144
|
|
@@ -149,7 +151,7 @@ In some situations, you don't want all roles to be available to all Grant Models
|
|
149
151
|
|
150
152
|
By default all Grant Models will show all roles as options. If you want to limit the roles available to a model, use the `roles_only` class method:
|
151
153
|
|
152
|
-
```
|
154
|
+
```ruby
|
153
155
|
class Membership < ApplicationRecord
|
154
156
|
include Roles::Support
|
155
157
|
roles_only :admin, :editor, :reader # Add this line to restrict the Membership model to only these roles
|
@@ -158,7 +160,7 @@ end
|
|
158
160
|
|
159
161
|
To access the array of all roles available for a particular model, use the `assignable_roles` class method. For example, in your Membership form, you probably _only_ want to show the assignable_roles as options. Your view could look like this:
|
160
162
|
|
161
|
-
```
|
163
|
+
```erb
|
162
164
|
<% Membership.assignable_roles.each do |role| %>
|
163
165
|
<% if role.manageable_by?(current_membership.roles) %>
|
164
166
|
<!-- View component for showing a role option. Probably a checkbox -->
|
@@ -166,13 +168,72 @@ To access the array of all roles available for a particular model, use the `assi
|
|
166
168
|
<% end %>
|
167
169
|
```
|
168
170
|
|
171
|
+
## Checking user permissions
|
172
|
+
|
173
|
+
Generally the CanCanCan helper method (`account_load_and_authorize_resource`) at the top of each controller will handle checking user permissions and will only load resources appropriate for the current user.
|
174
|
+
|
175
|
+
However, you may also want to check if a user can perform a specific action. For example, in a view you may want to only show the edit button if the current user has permissions to edit the object. For this, you can use regular CanCanCan helpers. For example:
|
176
|
+
|
177
|
+
```
|
178
|
+
<%= link_to "Edit", [:account, @document] if can? :edit, @document %>
|
179
|
+
```
|
180
|
+
|
181
|
+
Sometimes, you might want to check for the presence of a specific role. We provide a helper to check for the admin role:
|
182
|
+
```
|
183
|
+
@membership.admin?
|
184
|
+
```
|
185
|
+
|
186
|
+
For all other roles, you can check for their presence like this:
|
187
|
+
|
188
|
+
```
|
189
|
+
@membership.roles.include?(Role.find("developer"))
|
190
|
+
```
|
191
|
+
|
192
|
+
However, when you do that, you're only checking the roles that have been directly assigned to that membership.
|
193
|
+
|
194
|
+
Imagine a scenario like this:
|
195
|
+
```
|
196
|
+
# roles.yml
|
197
|
+
admin:
|
198
|
+
includes:
|
199
|
+
- editor
|
200
|
+
- billing
|
201
|
+
|
202
|
+
# somewhere else in your app:
|
203
|
+
@membership.roles << Role.admin
|
204
|
+
@membership.roles.include?(Role.find("editor"))
|
205
|
+
=> false
|
206
|
+
```
|
207
|
+
|
208
|
+
While that's technically correct that the user doesn't have the editor role, we probably want that to return true if we're checking what the user can and can't do. For this situation, we really want to check if the user can perform a role rather than if they've had that role assigned to them.
|
209
|
+
|
210
|
+
```
|
211
|
+
# roles.yml
|
212
|
+
|
213
|
+
admin:
|
214
|
+
includes:
|
215
|
+
- editor
|
216
|
+
- billing
|
217
|
+
|
218
|
+
# somewhere else in your app:
|
219
|
+
|
220
|
+
@membership.roles << Role.admin
|
221
|
+
@membership.roles.can_perform_role?(Role.find("editor"))
|
222
|
+
=> true
|
223
|
+
|
224
|
+
# You can also pass the role key as a symbol for a more concise syntax
|
225
|
+
@membership.roles.can_perform_role?(:editor)
|
226
|
+
=> true
|
227
|
+
```
|
228
|
+
|
169
229
|
|
170
230
|
## Debugging
|
231
|
+
|
171
232
|
If you want to see what CanCanCan directives are being created by your permit calls, you can add the `debug: true` option to your `permit` statement in `app/models/ability.rb`.
|
172
233
|
|
173
234
|
Likewise, to see what abilities are being added for a certain user, you can run the following on the Rails console:
|
174
235
|
|
175
|
-
```
|
236
|
+
```ruby
|
176
237
|
user = User.first
|
177
238
|
Ability.new(user).permit user, through: :projects_collaborators, parent: :project, debug: true
|
178
239
|
```
|
data/bullet_train-roles.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
|
11
11
|
spec.summary = "Yaml-backed ApplicationHash for CanCan Roles"
|
12
12
|
spec.description = "Yaml-backed ApplicationHash for CanCan Roles"
|
13
|
-
spec.homepage = "https://github.com/bullet-train-co/bullet_train-roles"
|
13
|
+
spec.homepage = "https://github.com/bullet-train-co/bullet_train-core/tree/main/bullet_train-roles"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
16
16
|
|
data/lib/models/role.rb
CHANGED
@@ -19,9 +19,15 @@ class Role < ActiveYaml::Base
|
|
19
19
|
find_by_key("default")
|
20
20
|
end
|
21
21
|
|
22
|
+
# Allow us to use either symbols or strings when searching
|
23
|
+
def self.find_by_key(key)
|
24
|
+
super(key.to_s)
|
25
|
+
end
|
26
|
+
|
22
27
|
def self.includes(role_or_key)
|
23
|
-
role_key = role_or_key.is_a?(Role) ? role_or_key.key : role_or_key
|
28
|
+
role_key = role_or_key.is_a?(Role) ? role_or_key.key : role_or_key.to_s
|
24
29
|
role = Role.find_by_key(role_key)
|
30
|
+
return [] if role.nil?
|
25
31
|
return Role.all.select(&:assignable?) if role.default?
|
26
32
|
result = []
|
27
33
|
all.each do |role|
|
@@ -35,7 +41,7 @@ class Role < ActiveYaml::Base
|
|
35
41
|
end
|
36
42
|
|
37
43
|
def self.find(key)
|
38
|
-
all.find { |role| role.key == key }
|
44
|
+
all.find { |role| role.key == key.to_s }
|
39
45
|
end
|
40
46
|
|
41
47
|
# We don't want to ever use the automatically generated ids from ActiveYaml. These are created based on the order of objects in the yml file
|
data/lib/roles/support.rb
CHANGED
@@ -70,6 +70,20 @@ module Roles
|
|
70
70
|
Role::Collection.new(self, (self.class.default_roles + roles_without_defaults).compact.uniq)
|
71
71
|
end
|
72
72
|
|
73
|
+
# Tests if the user can perform a given role
|
74
|
+
# They can have the role assigned directly, or the role can be included in another role they have
|
75
|
+
def can_perform_role?(role_or_key)
|
76
|
+
role_key = role_or_key.is_a?(Role) ? role_or_key.key : role_or_key
|
77
|
+
role = Role.find_by_key(role_key)
|
78
|
+
return true if roles.include?(role)
|
79
|
+
# Check all the roles that this role is included into
|
80
|
+
Role.includes(role_key).each do |included_in_role|
|
81
|
+
return true if roles.include?(included_in_role)
|
82
|
+
return true if can_perform_role?(included_in_role)
|
83
|
+
end
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
73
87
|
def roles=(roles)
|
74
88
|
update(role_ids: roles.map(&:key))
|
75
89
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train-roles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Prabin Poudel
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-08-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: byebug
|
@@ -195,11 +195,11 @@ files:
|
|
195
195
|
- lib/roles/permit.rb
|
196
196
|
- lib/roles/support.rb
|
197
197
|
- lib/roles/user.rb
|
198
|
-
homepage: https://github.com/bullet-train-co/bullet_train-roles
|
198
|
+
homepage: https://github.com/bullet-train-co/bullet_train-core/tree/main/bullet_train-roles
|
199
199
|
licenses:
|
200
200
|
- MIT
|
201
201
|
metadata:
|
202
|
-
homepage_uri: https://github.com/bullet-train-co/bullet_train-roles
|
202
|
+
homepage_uri: https://github.com/bullet-train-co/bullet_train-core/tree/main/bullet_train-roles
|
203
203
|
source_code_uri: https://github.com/bullet-train-co/bullet_train-roles
|
204
204
|
changelog_uri: https://github.com/bullet-train-co/bullet_train-roles/blob/main/CHANGELOG.md
|
205
205
|
post_install_message:
|