bullet_train-roles 1.2.27 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67e80c7b2b3f717fb4affde5bff3e9c59c3329a81abbe62c54daeafa308808f8
4
- data.tar.gz: 70d81346b71498838199ef64852ee36bde7f7f4e7c0a596d16d1963f3fb81da3
3
+ metadata.gz: 3f8c33aae9d0e533cc182a9d259bc4ac2ee4b112adbc9459d11fcefcb42dd887
4
+ data.tar.gz: 88657dc68c22e4a9772e4609707e31f551249c078d940f1865b3b84f0fda11d9
5
5
  SHA512:
6
- metadata.gz: 289be842c5db14645a96cb9a4c2e68909ea759108be354ca68eee41e9ae20bfeb1f1f0a2000ce346ba632883c75866a7839cd8e3b12ca869e4a3084d8223783c
7
- data.tar.gz: e63b1c370e263aabb71e1279dd41fd64fd27bfa272e22376556adfec9c3d1cf57913964631b447bedf20833ee554d51c995fa51072524f53e988c3e509344888
6
+ metadata.gz: 2d74e06824a7f9888c93cba13d52e2412cb0b5a99025c8182038850f1e64205412fd60b2712e35f595958ffcf164a420749494db8eecf6422d19f686913543b5
7
+ data.tar.gz: 84a7524e8de44d2d34a5cd547d44da44081d052f168110c344a40188446a151bdd6c2e888bd32a170d5a8282a2cfaec1c63ca5a5c2c91c3361b1db937227519d
data/Gemfile.lock CHANGED
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: .
11
11
  specs:
12
- bullet_train-roles (1.2.27)
12
+ bullet_train-roles (1.3.0)
13
13
  active_hash
14
14
  activesupport
15
15
  cancancan
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
  ```
@@ -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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Roles
4
- VERSION = "1.2.27"
4
+ VERSION = "1.3.0"
5
5
  end
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.2.27
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-07-27 00:00:00.000000000 Z
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:
@@ -217,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
217
  - !ruby/object:Gem::Version
218
218
  version: '0'
219
219
  requirements: []
220
- rubygems_version: 3.4.10
220
+ rubygems_version: 3.3.7
221
221
  signing_key:
222
222
  specification_version: 4
223
223
  summary: Yaml-backed ApplicationHash for CanCan Roles