pundit_roles 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/README.md +69 -41
- data/lib/pundit_roles/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73b78e648f853870e204510432f843c7a003b32f
|
4
|
+
data.tar.gz: 5ca295739ef6482eeceffc70b2d49726bb672fcd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d37558263e616455f8fd07e155fa7529ff1e0a262c38978b6a4cc04a85f2dd91f42a17f68c8bfcda0012f3594ec2226393b644176ee81c79590103481436e53
|
7
|
+
data.tar.gz: '084bd79f07ce70c8d583dc8c460b2fd6e22940854886dcf2970633c220be539ac98902c630db5575a1e71e981759d285ac6d68d4f1f5598af4ed828c5e337fee'
|
data/CHANGELOG.md
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
- Roles can no longer be inherited from the superclass.
|
9
9
|
- Test conditions for the roles are now guessed from the name of the role,
|
10
10
|
instead of being declared explicitly with the `authorize_with` option.
|
11
|
-
- Policy instance variable
|
11
|
+
- Policy instance variable `@record` renamed `@resource`
|
12
12
|
|
13
13
|
## 0.5.0 (2017-11-08)
|
14
14
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# PunditRoles
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/pundit_roles.svg)](https://
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/pundit_roles.svg)](https://rubygems.org/gems/pundit_roles)
|
4
4
|
[![Build Status](https://travis-ci.org/StairwayB/pundit_roles.svg?branch=master)](https://travis-ci.org/StairwayB/pundit_roles)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/github/StairwayB/pundit_roles/badge.svg?branch=master)](https://coveralls.io/github/StairwayB/pundit_roles?branch=master)
|
6
6
|
[![Maintainability](https://api.codeclimate.com/v1/badges/030ffce3612160c8e7f0/maintainability)](https://codeclimate.com/github/StairwayB/pundit_roles/maintainability)
|
@@ -12,7 +12,7 @@ helpers for convenience.
|
|
12
12
|
|
13
13
|
If you are already using Pundit, this should not conflict with any of Pundit's existing functionality.
|
14
14
|
You may use Pundit's features as well as the features from this gem interchangeably. There are
|
15
|
-
some caveats however, see the [Porting over from Pundit](#
|
15
|
+
some caveats however, see the [Porting over from Pundit](#porting-over-from-pundit).
|
16
16
|
|
17
17
|
Please note that this gem is not affiliated with Pundit or it's creators, but it very much
|
18
18
|
appreciates the work that they did with their great authorization system.
|
@@ -43,8 +43,8 @@ end
|
|
43
43
|
|
44
44
|
PunditRoles operates around the notion of _**roles**_. Each role needs to be defined at the Policy level
|
45
45
|
and provided with a conditional method that determines whether the `@user`(the `current_user` in the context of a Policy)
|
46
|
-
falls into this role. Additionally, each role can have a set of
|
47
|
-
|
46
|
+
falls into this role. Additionally, each role can have a set of options defined for it(like _attributes_,
|
47
|
+
_associations_ and _scope_). A basic example for a UserPolicy would be:
|
48
48
|
```ruby
|
49
49
|
class UserPolicy < ApplicationPolicy
|
50
50
|
role :regular_user,
|
@@ -53,45 +53,36 @@ class UserPolicy < ApplicationPolicy
|
|
53
53
|
},
|
54
54
|
associations: {
|
55
55
|
show: %i(posts followers following)
|
56
|
-
}
|
56
|
+
},
|
57
|
+
scope: lambda{resource.regular_user_scope}
|
57
58
|
|
58
|
-
role :correct_user,
|
59
|
+
role :correct_user,
|
59
60
|
attributes: {
|
60
|
-
show: %i(email phone_number confirmed_at updated_at
|
61
|
+
show: %i(email phone_number confirmed_at updated_at),
|
61
62
|
update: %i(username email password password_confirmation current_password name avatar)
|
62
63
|
},
|
63
64
|
associations: {
|
64
65
|
show: %i(settings),
|
65
66
|
save: %i(settings)
|
66
67
|
}
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
* Please note, that there were a couple of breaking change since `0.2.1`. View the
|
74
|
-
[changelog](https://github.com/StairwayB/pundit_roles/blob/master/CHANGELOG.md) for additional details.
|
75
|
-
|
76
|
-
And then in you query method, you simply say:
|
77
|
-
```ruby
|
78
|
-
def show?
|
79
|
-
%i(user correct_user)
|
80
|
-
end
|
68
|
+
|
69
|
+
# in the query methods, you define the roles which are allowed for the particular action
|
70
|
+
def show?
|
71
|
+
%i(regular_user correct_user)
|
72
|
+
end
|
81
73
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
Or you may use the `allow` helper method:
|
87
|
-
```ruby
|
88
|
-
def show?
|
89
|
-
allow :user, :correct_user
|
74
|
+
# or with the allow helper method:
|
75
|
+
def update?
|
76
|
+
allow :correct_user, :some_other_role
|
77
|
+
end
|
90
78
|
end
|
91
79
|
```
|
92
80
|
|
93
|
-
|
94
|
-
|
81
|
+
* This assumes that there are two methods defined in the UserPolicy called `regular_user?` and
|
82
|
+
`correct_user?`. More on that in the [Defining roles](#defining-roles) section.
|
83
|
+
* How scopes work can be found in the [Scopes](#scopes) section.
|
84
|
+
|
85
|
+
Then in your controller you call the `authorize!` method and pass it's return value to a variable:
|
95
86
|
```ruby
|
96
87
|
class UserController < ApplicationController
|
97
88
|
def show
|
@@ -102,8 +93,13 @@ class UserController < ApplicationController
|
|
102
93
|
end
|
103
94
|
```
|
104
95
|
|
96
|
+
* Please note, that there were a couple of breaking change since `0.2.1`. View the
|
97
|
+
[changelog](https://github.com/StairwayB/pundit_roles/blob/master/CHANGELOG.md) for additional details.
|
98
|
+
|
105
99
|
The `authorize!` method will return a hash of permitted attributes and associations for the corresponding action that the
|
106
|
-
user has access to. What you do with that is your business.
|
100
|
+
user has access to. What you do with that is your business. You may pass this hash to a serializer to limit what attributes
|
101
|
+
are returned, or use it to sanitize create and update parameters(see the [Strong params](#strong-params) section).
|
102
|
+
Accessors for each segment look like this:
|
107
103
|
```ruby
|
108
104
|
permitted[:attributes][:show] # ex. returns => [:username, :name, :avatar, :is_confirmed, :created_at]
|
109
105
|
permitted[:attributes][:create] # ex. returns => [:username, :email, :password, :password_confirmation]
|
@@ -117,7 +113,8 @@ The hash also contains the roles that the user has fulfilled:
|
|
117
113
|
permitted[:roles] # ex. returns => [:regular_user, :correct_user]
|
118
114
|
```
|
119
115
|
|
120
|
-
If the user does not fall into any roles permitted by a query, the `authorize
|
116
|
+
If the user does not fall into any roles permitted by a query, the `authorize!` method will raise
|
117
|
+
`Pundit::NotAuthorizedError`
|
121
118
|
|
122
119
|
### Defining roles
|
123
120
|
|
@@ -135,11 +132,20 @@ role :correct_user,
|
|
135
132
|
attributes: {show: [:name]},
|
136
133
|
associations: {show: [:posts]}
|
137
134
|
|
135
|
+
role :admin_user
|
136
|
+
attributes: {show: [:name]},
|
137
|
+
associations: {show: [:posts]},
|
138
|
+
scope: lambda{resource.admin_scope}
|
139
|
+
|
138
140
|
private
|
139
141
|
|
140
142
|
def correct_user?
|
141
143
|
@user.id == @resource.id
|
142
144
|
end
|
145
|
+
|
146
|
+
def admin_user?
|
147
|
+
@user.admin?
|
148
|
+
end
|
143
149
|
```
|
144
150
|
|
145
151
|
One thing to watch out for is that roles are not inherited, because each is unique to the model in question.
|
@@ -147,7 +153,7 @@ But since the name of the role is just the conditional method for the role,
|
|
147
153
|
without the '?' question mark, it is encouraged to inherit from an `ApplicationPolicy`,
|
148
154
|
and define common `role` conditionals there.
|
149
155
|
|
150
|
-
* see [Declaring attributes and associations](#
|
156
|
+
* see [Declaring attributes and associations](#declaring-attributes-and-associations) for how to declare
|
151
157
|
attributes and associations.
|
152
158
|
|
153
159
|
### Users with multiple roles
|
@@ -236,6 +242,7 @@ role :guest,
|
|
236
242
|
},
|
237
243
|
associations: {},
|
238
244
|
scope: lambda{resource.where(visible_publicly: true)}
|
245
|
+
|
239
246
|
role :regular_user,
|
240
247
|
attributes: {
|
241
248
|
show: %i(username name avatar)
|
@@ -269,9 +276,10 @@ end
|
|
269
276
|
|
270
277
|
#### Important: Scope declaration order
|
271
278
|
|
272
|
-
While attributes and associations for roles are merged, scopes are **not**! This means that whenever you wish to authorize a
|
273
|
-
you must take care in what order you define the roles. PunditRoles will go over the allowed roles in a query
|
274
|
-
order in which they were defined, and when it finds a role that the user fulfills,
|
279
|
+
While attributes and associations for roles are merged, scopes are **not**! This means that whenever you wish to authorize a
|
280
|
+
list of records,you must take care in what order you define the roles. PunditRoles will go over the allowed roles in a query
|
281
|
+
method in the order in which they were defined, and when it finds a role that the user fulfills,
|
282
|
+
it will return the scope for that role.
|
275
283
|
|
276
284
|
Take this example, where there are two roles permitted for an `index` action: `regular_user` and `:admin_user`:
|
277
285
|
```ruby
|
@@ -296,8 +304,8 @@ end
|
|
296
304
|
|
297
305
|
Whenever an admin tries to access the `index` action, PunditRoles will first check if the admin is a `regular_user`,
|
298
306
|
which will be true, since admin is in fact logged in. Therefore, it will return the scope defined for `regular_user`,
|
299
|
-
instead of the scope defined for `admin_user`. This is not the desired behaviour. In order to avoid this, the `index?`
|
300
|
-
needs to look like this:
|
307
|
+
instead of the scope defined for `admin_user`. This is not the desired behaviour. In order to avoid this, the `index?`
|
308
|
+
method needs to look like this:
|
301
309
|
```ruby
|
302
310
|
def index?
|
303
311
|
allow :admin_user, :regular_user
|
@@ -311,17 +319,37 @@ meaning that there is no way that a user can fulfill more than one of these role
|
|
311
319
|
does not matter. The guest role can be declared wherever, since PunditRoles will always evaluate whether the user is a
|
312
320
|
`guest` first.
|
313
321
|
|
322
|
+
### Strong params
|
323
|
+
PunditRoles makes it easy to handle role-based strong params. Simply pass the `[:create]`, `[:update]` or `[:save]`
|
324
|
+
attribute of the `[:attributes]` attribute of the hash returned by the `authorize!` method to the params sanitizer
|
325
|
+
(that's a mouthful).
|
326
|
+
```ruby
|
327
|
+
def create
|
328
|
+
permitted = authorize! User
|
329
|
+
@user = User.new(create_params(permitted[:attributes][:create]))
|
330
|
+
if @user.save!
|
331
|
+
render jsonapi: @user, fields: {users: permitted[:attributes][:show]}
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
private
|
336
|
+
|
337
|
+
def create_params(permitted_params)
|
338
|
+
params.require(:users).permit(permitted_params)
|
339
|
+
end
|
340
|
+
```
|
341
|
+
|
314
342
|
### Declaring attributes and associations
|
315
343
|
|
316
344
|
* Attributes and associations in this heading are referred to collectively as _options_
|
317
345
|
|
318
|
-
|
346
|
+
#### Explicit declaration of options
|
319
347
|
|
320
348
|
Options are declared with the `attributes` and `associations` options of the role method.
|
321
349
|
|
322
350
|
Valid options for both `:attributes` and `:associations` are `:show`,`:create`,`:update` and `:save` or the implicit options.
|
323
351
|
|
324
|
-
|
352
|
+
#### Implicit declaration of options
|
325
353
|
|
326
354
|
PunditRoles provides a set of helpers to be able to implicitly declare the options of a role.
|
327
355
|
|
data/lib/pundit_roles/version.rb
CHANGED