pundit_roles 0.1.2 → 0.2.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/.coveralls.yml +1 -0
- data/.travis.yml +4 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -2
- data/README.md +116 -131
- data/Rakefile +9 -2
- data/lib/pundit_roles/policy/base.rb +36 -45
- data/lib/pundit_roles/policy/policy_defaults.rb +52 -0
- data/lib/pundit_roles/policy/role/{base.rb → option_builder.rb} +44 -65
- data/lib/pundit_roles/policy/role.rb +32 -82
- data/lib/pundit_roles/pundit.rb +8 -6
- data/lib/pundit_roles/version.rb +1 -1
- data/lib/pundit_roles.rb +1 -0
- data/pundit_roles.gemspec +1 -0
- metadata +20 -4
- data/lib/pundit_roles/policy/policy_defaults/defaults.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37198b58ba83c3e0f973f544dcdc7d202159820d
|
4
|
+
data.tar.gz: febd757aadd6d847ce4fa5997ddc3d7ba8248cf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc8990e3c886ff9f425359896c99518813db8d7dc93c71503f25927cc6eb7d056a3c0c408943a726ebffef28949770fee765288ff29537d6405d3e20325b48db
|
7
|
+
data.tar.gz: e5b8efa011b23dfebd9f9bf324b4907e808d5a28626c0f04da8d3efffc34fd3d36d9b0e00372be7fc0d6f31098ff675ee1473df852eec29e2d2cff7645151d17
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# PunditRoles
|
2
|
+
|
3
|
+
## 0.2.0 (2017-10-30)
|
4
|
+
|
5
|
+
- Roles and permitted options are no longer separately declared with `role` and
|
6
|
+
`permitted_for` methods. Declaration of options has been consolidated into the
|
7
|
+
`role` method.
|
8
|
+
- Roles can no longer be inherited from the superclass.
|
9
|
+
- Test conditions for the roles are now guessed from the name of the role,
|
10
|
+
instead of being declared explicitly with the `authorize_with` option.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# PunditRoles
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/pundit_roles.svg)
|
4
|
+
[](https://travis-ci.org/StairwayB/pundit_roles)
|
5
|
+
[](https://coveralls.io/github/StairwayB/pundit_roles?branch=master)
|
6
|
+
[](https://codeclimate.com/github/StairwayB/pundit_roles/maintainability)
|
7
|
+
|
3
8
|
PunditRoles is a helper gem which works on top of [Pundit](https://github.com/elabs/pundit)
|
4
9
|
(if you are not familiar with Pundit, it is recommended you read it's documentation before continuing).
|
5
10
|
It allows you to extend Pundit's authorization system to include attributes and associations.
|
@@ -10,10 +15,9 @@ You may use Pundit's features as well as the features from this gem interchangea
|
|
10
15
|
Please note that this gem is not affiliated with Pundit or it's creators, but it very much
|
11
16
|
appreciates the work that they did with their great authorization system.
|
12
17
|
|
13
|
-
* **Important
|
14
|
-
|
15
|
-
|
16
|
-
to raise an issue.
|
18
|
+
* **Important**: This gem is **not** yet considered production ready.
|
19
|
+
|
20
|
+
* [**_Changelog_**](https://github.com/StairwayB/pundit_roles/blob/master/CHANGELOG.md)
|
17
21
|
|
18
22
|
## Installation
|
19
23
|
|
@@ -34,43 +38,40 @@ end
|
|
34
38
|
And inherit your ApplicationPolicy from Policy::Base
|
35
39
|
```ruby
|
36
40
|
class ApplicationPolicy < Policy::Base
|
37
|
-
# def show?
|
38
|
-
# [...]
|
39
|
-
# end
|
40
41
|
end
|
41
42
|
```
|
42
43
|
|
43
44
|
## Roles
|
44
45
|
|
45
46
|
PunditRoles operates around the notion of _**roles**_. Each role needs to be defined at the Policy level
|
46
|
-
and provided with a conditional method that determines whether the `@user`(`current_user` in the context of a Policy)
|
47
|
+
and provided with a conditional method that determines whether the `@user`(the `current_user` in the context of a Policy)
|
47
48
|
falls into this role. Additionally, each role can have a set of permitted
|
48
|
-
_**attributes**_ and _**associations**_(from here on collectively referred to as **
|
49
|
+
_**attributes**_ and _**associations**_(from here on collectively referred to as _**options**_)
|
49
50
|
defined for it. A basic example for a UserPolicy would be:
|
50
51
|
```ruby
|
51
|
-
role :
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
save: %i(settings)
|
69
|
-
}
|
52
|
+
role :regular_user,
|
53
|
+
attributes: {
|
54
|
+
show: %i(username name avatar is_confirmed created_at)
|
55
|
+
},
|
56
|
+
associations: {
|
57
|
+
show: %i(posts followers following)
|
58
|
+
}
|
59
|
+
|
60
|
+
role :correct_user,
|
61
|
+
attributes: {
|
62
|
+
show: %i(email phone_number confirmed_at updated_at sign_in_count),
|
63
|
+
update: %i(username email password password_confirmation current_password name avatar)
|
64
|
+
},
|
65
|
+
associations: {
|
66
|
+
show: %i(settings),
|
67
|
+
save: %i(settings)
|
68
|
+
}
|
70
69
|
```
|
71
70
|
|
72
|
-
This assumes that there are two methods defined in the UserPolicy called `
|
73
|
-
`correct_user?`.
|
71
|
+
This assumes that there are two methods defined in the UserPolicy called `regular_user?` and
|
72
|
+
`correct_user?`.
|
73
|
+
|
74
|
+
* Please note, that there was a breaking change since `0.1.2`. View the changelog for additional details.
|
74
75
|
|
75
76
|
And then in you query method, you simply say:
|
76
77
|
```ruby
|
@@ -104,124 +105,124 @@ end
|
|
104
105
|
The `authorize` method will return a hash of permitted attributes and associations for the corresponding action that the
|
105
106
|
user has access to. What you do with that is your business. Accessors for each segment look like this:
|
106
107
|
```ruby
|
107
|
-
permitted[:attributes][:show]
|
108
|
-
permitted[:attributes][:create]
|
108
|
+
permitted[:attributes][:show] # ex. returns => [:username, :name, :avatar, :is_confirmed, :created_at]
|
109
|
+
permitted[:attributes][:create] # ex. returns => [:username, :email, :password, :password_confirmation]
|
109
110
|
|
110
111
|
permitted[:associations][:show]
|
111
112
|
permitted[:associations][:update]
|
112
113
|
```
|
113
114
|
|
115
|
+
It hash also contains the roles that the user has fulfilled:
|
116
|
+
```ruby
|
117
|
+
permitted[:roles] # ex. returns => [:regular_user, :correct_user]
|
118
|
+
```
|
119
|
+
|
114
120
|
If the user does not fall into any roles permitted by a query, the `authorize` method will raise `Pundit::NotAuthorizedError`
|
115
121
|
|
116
122
|
### Defining roles
|
117
123
|
|
118
124
|
Roles are defined with the `role` method. It receives the name of the role as it's first argument and the
|
119
|
-
options for the role as it's second
|
120
|
-
|
121
|
-
|
125
|
+
options for the role as it's second(multiple `roles` can be defined at once, if you wish to do that,
|
126
|
+
but all of these will have identical options, so what's the point, really). Valid options for the role are:
|
127
|
+
`:attributes, :associations, :scope, :uses_db, :extend`.
|
122
128
|
|
123
|
-
Currently
|
129
|
+
Currently only attributes and associations are supported, scopes and db permissions will be coming Soon™.
|
124
130
|
|
125
131
|
```ruby
|
126
|
-
role :
|
132
|
+
role :regular_user,
|
133
|
+
attributes: {show: [:name]},
|
134
|
+
associations: {show: [:posts]}
|
127
135
|
|
128
|
-
def
|
136
|
+
def regular_user?
|
129
137
|
@user.present?
|
130
138
|
end
|
131
139
|
```
|
132
140
|
|
141
|
+
One thing to watch out for is that roles are not inherited, because each is unique to the model in question.
|
142
|
+
But since the name of the role is just the conditional method for the role,
|
143
|
+
without the '?' question mark, it is encouraged to inherit from an `ApplicationPolicy`,
|
144
|
+
and define common `role` conditional methods there.
|
145
|
+
|
133
146
|
### Users with multiple roles
|
134
147
|
|
135
148
|
You may have noticed that in the first example `correct_user` has fewer permitted options
|
136
|
-
defined than `
|
149
|
+
defined than `regular_user`. That is because PunditRoles does not treat roles as exclusionary.
|
137
150
|
Users may have a single role or they may have multiple roles, within the context of the model they are trying to access.
|
138
|
-
In the previous example, a `correct_user`, meaning a `
|
139
|
-
also a
|
151
|
+
In the previous example, a `correct_user`, meaning a `regular_user` trying to access it's own model, is naturally
|
152
|
+
also a `regular_user`, so it will have access to all options a `regular_user` has access to plus the
|
140
153
|
options that a `correct_user` has access to.
|
141
154
|
|
142
155
|
Take this example, to better illustrate what is happening:
|
143
156
|
|
144
157
|
```ruby
|
145
|
-
role :
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
attributes: {
|
160
|
-
show: %i(email is_admin)
|
161
|
-
}
|
158
|
+
role :regular_user,
|
159
|
+
attributes: {
|
160
|
+
show: %i(username name avatar)
|
161
|
+
}
|
162
|
+
|
163
|
+
role :correct_user,
|
164
|
+
attributes: {
|
165
|
+
show: %i(email phone_number)
|
166
|
+
}
|
167
|
+
|
168
|
+
role :admin_user,
|
169
|
+
attributes: {
|
170
|
+
show: %i(email is_admin)
|
171
|
+
}
|
162
172
|
```
|
163
173
|
|
164
|
-
Here, a user which fulfills the `
|
165
|
-
options of all three roles, meaning the `permitted[:attributes][:show]` would look like:
|
174
|
+
Here, a user which fulfills the `admin_user` condition trying to access it's own model, would receive the
|
175
|
+
options of all three roles, without any duplicates, meaning the `permitted[:attributes][:show]` would look like:
|
166
176
|
```ruby
|
167
177
|
[:username, :name, :avatar, :email, :phone_number, :is_admin]
|
168
178
|
```
|
169
|
-
Notice that there are no duplicates. This is because whenever a user tries to access an action,
|
170
|
-
PunditRoles will evaluate whether the user falls into the roles permitted to perform said action,
|
171
|
-
and if they do, it will uniquely merge the options hashes of all of these.
|
172
179
|
|
173
180
|
If the user is an `admin`, but is not a `correct_user`, it will not receive the `phone_number` attribute,
|
174
181
|
because that is unique to `correct_user` and vice versa.
|
175
182
|
|
176
183
|
At present, there is no way to prevent merging of roles. Such a feature may be coming in a future update.
|
177
184
|
|
178
|
-
###
|
179
|
-
|
180
|
-
One thing to watch out for is that roles are inherited but options are not.
|
181
|
-
This means that you may declare commonly used roles(whose validations are
|
182
|
-
independent of the `@record` of the Policy) in the ApplicationPolicy, and may reuse them
|
183
|
-
further down the line. You may also overwrite roles defined in a parent class(these will not affect those in the parent).
|
185
|
+
### The :guest role
|
184
186
|
|
185
|
-
|
186
|
-
in your Policy, otherwise the role will return an empty hash.
|
187
|
-
|
188
|
-
With that in mind, PunditRoles comes with a default `:guest` role, which simply checks if
|
187
|
+
PunditRoles comes with a default `:guest` role, which simply checks if
|
189
188
|
the user is nil. If you wish to permit guest users for a particular action, simply define the
|
190
189
|
options for it and allow it in your query method.
|
191
190
|
|
192
191
|
```ruby
|
193
192
|
class UserPolicy < ApplicationPolicy
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
193
|
+
|
194
|
+
role :guest,
|
195
|
+
attributes: {
|
196
|
+
show: %i(username first_name last_name avatar),
|
197
|
+
create: %i(username email password password_confirmation first_name last_name avatar)
|
198
|
+
},
|
199
|
+
associations: {}
|
200
200
|
|
201
201
|
def show?
|
202
|
-
allow :guest
|
202
|
+
allow :guest, :some, :other, :roles
|
203
203
|
end
|
204
204
|
|
205
205
|
def create?
|
206
|
-
allow :guest
|
206
|
+
allow :guest, :admin_user
|
207
207
|
end
|
208
208
|
|
209
209
|
end
|
210
210
|
```
|
211
211
|
|
212
|
-
|
212
|
+
**Important**
|
213
|
+
|
214
|
+
* The `:guest` role is exclusionary by default, meaning it cannot be merged
|
213
215
|
with other roles. It is also the first role that is evaluated, and if the user is a `:guest`, it will return the guest
|
214
|
-
attributes if `:guest` is allowed, or raise `
|
215
|
-
|
216
|
-
|
216
|
+
attributes if `:guest` is allowed, or raise `Pundit::NotAuthorizedError` if not.
|
217
|
+
|
218
|
+
* Do **not** use a custom role for `nil` or `undefined` `@user`, use `:guest`.
|
219
|
+
If you do, it will most likely lead to unwanted exceptions.
|
217
220
|
|
218
221
|
### Explicit declaration of options
|
219
222
|
|
220
|
-
Options are declared with the `
|
221
|
-
and the options as it's second.
|
223
|
+
Options are declared with the `attributes` and `associations` options of the role method.
|
222
224
|
|
223
|
-
Valid options for
|
224
|
-
Within these, valid options are `:show`,`:create`,`:update` and `:save` or the implicit options.
|
225
|
+
Valid options for both `:attributes` and `:associations` are `:show`,`:create`,`:update` and `:save` or the implicit options.
|
225
226
|
|
226
227
|
### Implicit declaration of options
|
227
228
|
|
@@ -239,46 +240,42 @@ attribute that is added to a model later down the line.
|
|
239
240
|
Will be able to view all non-restricted options.
|
240
241
|
|
241
242
|
```ruby
|
242
|
-
role :admin,
|
243
|
-
|
244
|
-
|
245
|
-
associations: :show_all
|
243
|
+
role :admin,
|
244
|
+
attributes: :show_all,
|
245
|
+
associations: :show_all
|
246
246
|
```
|
247
247
|
* **create_all, update_all, save_all**
|
248
248
|
|
249
249
|
Will be able to create, update or save all non-restricted attributes. These options also
|
250
250
|
imply that the role will be able to `show_all` options.
|
251
251
|
```ruby
|
252
|
-
role :admin,
|
253
|
-
|
254
|
-
|
255
|
-
associations: :update_all
|
252
|
+
role :admin,
|
253
|
+
attributes: :save_all,
|
254
|
+
associations: :update_all
|
256
255
|
```
|
257
256
|
|
258
257
|
* **all**
|
259
258
|
|
260
259
|
Declare on a per-action basis whether the role has access to all options.
|
261
260
|
```ruby
|
262
|
-
role :admin,
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
}
|
261
|
+
role :admin,
|
262
|
+
attributes: {
|
263
|
+
show: :all,
|
264
|
+
save: %i(name username email)
|
265
|
+
},
|
266
|
+
associations: {
|
267
|
+
show: :all
|
268
|
+
}
|
271
269
|
```
|
272
270
|
|
273
271
|
* **all_minus**
|
274
272
|
|
275
273
|
Can be used to allow all attributes, except those declared.
|
276
274
|
```ruby
|
277
|
-
role :admin,
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
}
|
275
|
+
role :admin,
|
276
|
+
attributes: {
|
277
|
+
show: [:all_minus, :password_digest]
|
278
|
+
}
|
282
279
|
```
|
283
280
|
The `:admin` role will now be able to view all attributes, except `password_digest`.
|
284
281
|
|
@@ -287,36 +284,24 @@ attribute that is added to a model later down the line.
|
|
287
284
|
PunditRoles allows you to define restricted options which will be removed when declaring
|
288
285
|
implicitly. By default, only the `:id`, `:created_at`, `:updated_at` attributes are restricted
|
289
286
|
for `create`,`update` and `save` actions. You may overwrite this behaviour on a per-policy basis:
|
290
|
-
```ruby
|
291
|
-
private
|
292
287
|
|
293
|
-
|
294
|
-
|
295
|
-
end
|
288
|
+
```ruby
|
289
|
+
RESTRICTED_SHOW_ATTRIBUTES = [:attr_one, :attr_two]
|
296
290
|
```
|
297
|
-
Or if you want to add to it, instead of overwriting,
|
291
|
+
Or if you want to add to it, instead of overwriting(here,
|
292
|
+
the second `RESTRICTED_SHOW_ATTRIBUTES` resolves to the one declared on the parent):
|
298
293
|
```ruby
|
299
|
-
|
300
|
-
|
301
|
-
def restricted_create_attributes
|
302
|
-
super + [:attr_one, :attr_two]
|
303
|
-
end
|
294
|
+
RESTRICTED_SHOW_ATTRIBUTES = RESTRICTED_SHOW_ATTRIBUTES + [:attr_one, :attr_two]
|
304
295
|
```
|
305
296
|
|
306
|
-
There are 8 `
|
307
|
-
to either `
|
297
|
+
There are 8 `RESTRICTED_#{action}_#{option_type}` constants in total, where `option_type` refers
|
298
|
+
to either `ATTRIBUTES` or `ASSOCIATIONS` and `action` refers to `SHOW`, `CREATE`, `UPDATE` or `SAVE`.
|
308
299
|
|
309
300
|
## Planned updates
|
310
301
|
|
311
302
|
Support for Pundit's scope method should be added in the near future, along with authorizing associations,
|
312
|
-
generators, and rspec helpers.
|
313
|
-
ready.
|
314
|
-
|
315
|
-
## Development
|
316
|
-
|
317
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake 'spec'` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
303
|
+
generators, and possibly rspec helpers.
|
318
304
|
|
319
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
320
305
|
|
321
306
|
## Contributing
|
322
307
|
|
data/Rakefile
CHANGED
@@ -1,35 +1,26 @@
|
|
1
1
|
require_relative 'role'
|
2
|
-
require_relative 'policy_defaults
|
3
|
-
|
2
|
+
require_relative 'policy_defaults'
|
4
3
|
|
4
|
+
# Namespace for aesthetic reasons
|
5
5
|
module Policy
|
6
6
|
|
7
7
|
# Base policy class to be extended by all other policies, authorizes users based on roles they fall into,
|
8
8
|
# return a uniquely merged hash of permitted attributes and associations of each role the @user has.
|
9
9
|
#
|
10
|
-
# @
|
11
|
-
# @
|
10
|
+
# @attr_reader user [Object] the user that initiated the action
|
11
|
+
# @attr_reader record [Object] the object we're checking permissions of
|
12
12
|
class Base
|
13
13
|
extend Role
|
14
|
+
include PolicyDefaults
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
role :guest, authorize_with: :user_guest
|
18
|
-
|
19
|
-
attr_reader :user, :record
|
20
|
-
|
21
|
-
def initialize(user, record)
|
16
|
+
attr_reader :user, :resource
|
17
|
+
def initialize(user, resource)
|
22
18
|
@user = user
|
23
|
-
@
|
24
|
-
end
|
25
|
-
|
26
|
-
# Is here
|
27
|
-
def scope
|
28
|
-
Pundit.authorize_scope!(user, record.class, fields)
|
19
|
+
@resource = resource
|
29
20
|
end
|
30
21
|
|
31
|
-
# Retrieves the permitted roles for the current
|
32
|
-
# and return a hash of attributes and associations that the
|
22
|
+
# Retrieves the permitted roles for the current query, checks if user is one or more of these roles
|
23
|
+
# and return a hash of attributes and associations that the user has access to.
|
33
24
|
#
|
34
25
|
# @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`)
|
35
26
|
def resolve_query(query)
|
@@ -40,16 +31,11 @@ module Policy
|
|
40
31
|
|
41
32
|
permissions_hash = self.class.permissions_hash
|
42
33
|
|
43
|
-
# Always checks if
|
44
|
-
guest
|
45
|
-
if guest
|
46
|
-
|
47
|
-
return guest.permitted
|
48
|
-
else
|
49
|
-
return false
|
50
|
-
end
|
34
|
+
# Always checks if user is a guest, and return the appropriate permission if true
|
35
|
+
# the guest role cannot be merged with other roles
|
36
|
+
if guest?
|
37
|
+
return handle_guest_user(permitted_roles, permissions_hash)
|
51
38
|
end
|
52
|
-
|
53
39
|
current_roles = determine_current_roles(permitted_roles, permissions_hash)
|
54
40
|
|
55
41
|
unless current_roles.present?
|
@@ -57,8 +43,7 @@ module Policy
|
|
57
43
|
end
|
58
44
|
|
59
45
|
if current_roles.length == 1
|
60
|
-
current_roles.values[0]
|
61
|
-
return current_roles.values[0]
|
46
|
+
return current_roles.values[0].merge({roles: [current_roles.keys[0]]})
|
62
47
|
end
|
63
48
|
|
64
49
|
return unique_merge(current_roles)
|
@@ -66,6 +51,17 @@ module Policy
|
|
66
51
|
|
67
52
|
private
|
68
53
|
|
54
|
+
# Return the default :guest role if guest is present in @permitted_roles. Return false otherwise
|
55
|
+
#
|
56
|
+
# @param permitted_roles [Hash] roles returned by the query
|
57
|
+
# @param permissions_hash [Hash] unrefined hash of options defined by all permitted_for methods
|
58
|
+
def handle_guest_user(permitted_roles, permissions_hash)
|
59
|
+
if permitted_roles.include? :guest
|
60
|
+
return permissions_hash[:guest].merge({roles: [:guest]})
|
61
|
+
end
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
|
69
65
|
# Build a hash of the roles that the user fulfills and the roles' attributes and associations,
|
70
66
|
# based on the test_condition of the role.
|
71
67
|
#
|
@@ -75,20 +71,16 @@ module Policy
|
|
75
71
|
current_roles = {}
|
76
72
|
|
77
73
|
permitted_roles.each do |permitted_role|
|
78
|
-
if permitted_role == :guest
|
74
|
+
if permitted_role == :guest or permitted_role == :guest_user
|
79
75
|
next
|
80
76
|
end
|
81
77
|
|
82
78
|
begin
|
83
|
-
|
84
|
-
|
85
|
-
if current_role_obj.test_condition
|
86
|
-
current_roles[permitted_role] = current_role_obj.permitted
|
79
|
+
if send("#{permitted_role}?")
|
80
|
+
current_roles[permitted_role] = permissions_hash[permitted_role]
|
87
81
|
end
|
88
|
-
rescue NoMethodError =>e
|
89
|
-
raise NoMethodError, "
|
90
|
-
rescue NameError => e
|
91
|
-
raise NameError, "#{current_role[:role]} not defined => #{e.message} "
|
82
|
+
rescue NoMethodError => e
|
83
|
+
raise NoMethodError, "Undefined test condition, it must be defined as 'role?', where, role is :#{permitted_role}, => #{e.message}"
|
92
84
|
end
|
93
85
|
end
|
94
86
|
|
@@ -102,14 +94,8 @@ module Policy
|
|
102
94
|
merged_hash = {attributes: {}, associations: {}, roles: []}
|
103
95
|
|
104
96
|
roles.each do |role, option|
|
105
|
-
unless option.present?
|
106
|
-
next
|
107
|
-
end
|
108
97
|
merged_hash[:roles] << role
|
109
98
|
option.each do |type, actions|
|
110
|
-
unless actions.present?
|
111
|
-
next
|
112
|
-
end
|
113
99
|
actions.each do |key, value|
|
114
100
|
unless merged_hash[type][key]
|
115
101
|
merged_hash[type][key] = []
|
@@ -129,6 +115,11 @@ module Policy
|
|
129
115
|
return roles
|
130
116
|
end
|
131
117
|
|
118
|
+
# Default :guest role
|
119
|
+
def guest?
|
120
|
+
@user.nil?
|
121
|
+
end
|
122
|
+
|
132
123
|
# Scope class from Pundit, to be used for limiting scopes. Unchanged from Pundit,
|
133
124
|
# possible implementation forthcoming in a future update
|
134
125
|
class Scope
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Defaults for Policy::Base
|
2
|
+
module PolicyDefaults
|
3
|
+
# default index? method
|
4
|
+
def index?
|
5
|
+
false
|
6
|
+
end
|
7
|
+
|
8
|
+
# default show? method
|
9
|
+
def show?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
# default create? method
|
14
|
+
def create?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
# default update? method
|
19
|
+
def update?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
# default destroy? method
|
24
|
+
def destroy?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
# restricted attributes for show
|
29
|
+
RESTRICTED_SHOW_ATTRIBUTES = []
|
30
|
+
|
31
|
+
# restricted attributes for save
|
32
|
+
RESTRICTED_SAVE_ATTRIBUTES = [:id, :created_at, :updated_at]
|
33
|
+
|
34
|
+
# restricted attributes for create
|
35
|
+
RESTRICTED_CREATE_ATTRIBUTES = [:id, :created_at, :updated_at]
|
36
|
+
|
37
|
+
# restricted attributes for update
|
38
|
+
RESTRICTED_UPDATE_ATTRIBUTES = [:id, :created_at, :updated_at]
|
39
|
+
|
40
|
+
|
41
|
+
# restricted associations for show
|
42
|
+
RESTRICTED_SHOW_ASSOCIATIONS = []
|
43
|
+
|
44
|
+
# restricted associations for save
|
45
|
+
RESTRICTED_SAVE_ASSOCIATIONS = []
|
46
|
+
|
47
|
+
# restricted associations for create
|
48
|
+
RESTRICTED_CREATE_ASSOCIATIONS = []
|
49
|
+
|
50
|
+
# restricted associations for update
|
51
|
+
RESTRICTED_UPDATE_ASSOCIATIONS = []
|
52
|
+
end
|
@@ -1,59 +1,50 @@
|
|
1
1
|
module Role
|
2
|
-
#
|
3
|
-
# and creates a hash of attributes and associations from the options defined in permitted_for methods
|
2
|
+
# Helper class, which handles building of a role's #permissions_hash.
|
4
3
|
#
|
5
|
-
# @param
|
6
|
-
#
|
7
|
-
# @param
|
8
|
-
# @param
|
9
|
-
# @param permission_options [Hash] unrefined hash of options to be refined by the permitted method
|
10
|
-
class Base
|
11
|
-
|
12
|
-
# Class instance variable accessors
|
13
|
-
class << self
|
14
|
-
attr_accessor :authorize_with, :disable_merge
|
15
|
-
end
|
4
|
+
# @param policy [Class] the class used to store a reference to the policy which instantiated this
|
5
|
+
# @param attr_opts [Hash, :Symbol] the requested options for attributes to be refined by the permitted method
|
6
|
+
# @param assoc_opts [Hash, :Symbol] the requested options for associations to be refined by the permitted method
|
7
|
+
# @param scope [String] the scope for the role in String format
|
16
8
|
|
17
|
-
|
18
|
-
@disable_merge = nil
|
9
|
+
class OptionBuilder
|
19
10
|
|
20
11
|
attr_reader :policy
|
21
12
|
|
22
|
-
def initialize(policy,
|
13
|
+
def initialize(policy, attr_opts, assoc_opts, scope)
|
23
14
|
@policy = policy
|
24
|
-
@
|
15
|
+
@attr_opts = attr_opts
|
16
|
+
@assoc_opts = assoc_opts
|
17
|
+
@scope = scope
|
25
18
|
freeze
|
26
19
|
end
|
27
20
|
|
28
|
-
#
|
29
|
-
def
|
30
|
-
return
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def test_condition
|
35
|
-
@policy.send(authorize_with)
|
21
|
+
# Returns a refined hash of attributes and associations the current_user has access to
|
22
|
+
def permitted
|
23
|
+
return {
|
24
|
+
attributes: permitted_options(@attr_opts, 'attributes'),
|
25
|
+
associations: permitted_options(@assoc_opts, 'associations')
|
26
|
+
}
|
36
27
|
end
|
37
28
|
|
38
|
-
|
39
|
-
def permitted
|
40
|
-
if not @permission_options
|
41
|
-
permitted = {attributes: {},
|
42
|
-
associations: {}}
|
29
|
+
private
|
43
30
|
|
44
|
-
|
45
|
-
|
46
|
-
|
31
|
+
# Determines the the kind of method used to declare the option
|
32
|
+
#
|
33
|
+
# @param *opts [Hash] the hash of attributes or associations for the role
|
34
|
+
# @param type [String] the kind of option, can be 'attributes' or 'associations'
|
35
|
+
def permitted_options(opts, type)
|
36
|
+
if not opts
|
37
|
+
permitted = {}
|
38
|
+
|
39
|
+
elsif opts.is_a? Symbol
|
40
|
+
permitted = handle_default_options(opts, type)
|
47
41
|
else
|
48
|
-
permitted =
|
49
|
-
associations: init_options(@permission_options[:associations], 'associations')}
|
42
|
+
permitted = init_options(opts, type)
|
50
43
|
end
|
51
44
|
|
52
45
|
return permitted
|
53
46
|
end
|
54
47
|
|
55
|
-
private
|
56
|
-
|
57
48
|
# Build hash of options when options are explicitly declared as a Hash
|
58
49
|
#
|
59
50
|
# @param options [Hash] unrefined hash containing either attributes or associations
|
@@ -63,10 +54,6 @@ module Role
|
|
63
54
|
return {}
|
64
55
|
end
|
65
56
|
|
66
|
-
if options.is_a? Symbol
|
67
|
-
return handle_default_options(options, type)
|
68
|
-
end
|
69
|
-
|
70
57
|
raise ArgumentError, "Permitted #{type}, if declared, must be declared as a Hash or Symbol, expected something along the lines of
|
71
58
|
{show: [:id, :name], create: [:name], update: :all} or :all, got #{options}" unless options.is_a? Hash
|
72
59
|
|
@@ -79,6 +66,7 @@ module Role
|
|
79
66
|
next
|
80
67
|
end
|
81
68
|
|
69
|
+
# todo: This needs some rethinking
|
82
70
|
if value.is_a? Array
|
83
71
|
case value.first
|
84
72
|
when :all_minus
|
@@ -103,18 +91,17 @@ module Role
|
|
103
91
|
parsed_options = {}
|
104
92
|
case option
|
105
93
|
when :show_all
|
106
|
-
parsed_options[:show] =
|
94
|
+
parsed_options[:show] = get_all(type)
|
107
95
|
else
|
108
96
|
of_type = option.to_s.gsub('_all', '').to_sym
|
109
|
-
parsed_options[:show] =
|
110
|
-
parsed_options[of_type] =
|
97
|
+
parsed_options[:show] = get_all(type)
|
98
|
+
parsed_options[of_type] = get_all(type)
|
111
99
|
end
|
112
100
|
|
113
101
|
return remove_restricted(parsed_options, type)
|
114
102
|
end
|
115
103
|
|
116
|
-
# Remove restricted attributes declared in the
|
117
|
-
# ex: restricted_show_attributes
|
104
|
+
# Remove restricted attributes declared in the #policy RESTRICTED_#{key}_#{type} constants
|
118
105
|
#
|
119
106
|
# @param obj [Hash] refined hash containing either attributes or associations
|
120
107
|
# @param type [String] the type of option to be built, can be 'attributes' or 'associations'
|
@@ -122,36 +109,28 @@ module Role
|
|
122
109
|
permitted_obj_values = {}
|
123
110
|
|
124
111
|
obj.each do |key, value|
|
125
|
-
restricted = @policy
|
112
|
+
restricted = "#{@policy}::RESTRICTED_#{key.upcase}_#{type.upcase}".constantize
|
126
113
|
permitted_obj_values[key] = restricted.present? ? value - restricted : value
|
127
114
|
end
|
128
115
|
|
129
116
|
return permitted_obj_values
|
130
117
|
end
|
131
118
|
|
132
|
-
# Returns all attributes of a record or scope defined in the
|
119
|
+
# Returns all attributes of a record or scope defined in the #policy
|
133
120
|
def get_all_attributes
|
134
|
-
|
135
|
-
@policy.record.class.column_names.map(&:to_sym)
|
136
|
-
rescue NoMethodError
|
137
|
-
begin
|
138
|
-
@policy.scope.column_names.map(&:to_sym)
|
139
|
-
rescue NoMethodError
|
140
|
-
raise NoMethodError, "#{@policy} does not have a record or scope defined(or scope is not an ActiveRecord::Association), this is a problem."
|
141
|
-
end
|
142
|
-
end
|
121
|
+
@policy.to_s.gsub('Policy', '').constantize.column_names.map(&:to_sym)
|
143
122
|
end
|
144
123
|
|
145
|
-
# Returns all associations of a record or scope defined in the
|
124
|
+
# Returns all associations of a record or scope defined in the #policy
|
146
125
|
def get_all_associations
|
126
|
+
@policy.to_s.gsub('Policy', '').constantize.reflect_on_all_associations.map(&:name)
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_all(type)
|
147
130
|
begin
|
148
|
-
|
149
|
-
rescue
|
150
|
-
|
151
|
-
@policy.scope.reflect_on_all_associations.map(&:name)
|
152
|
-
rescue NoMethodError
|
153
|
-
raise NoMethodError, "#{@policy} does not have a record or scope defined(or scope is not an ActiveRecord::Association), this is a problem."
|
154
|
-
end
|
131
|
+
send("get_all_#{type}")
|
132
|
+
rescue NameError => e
|
133
|
+
raise ArgumentError, "#{@policy} does not have a corresponding model: #{@policy.to_s.gsub('Policy', '')}, implicit declarations are not allowed => #{e.message}"
|
155
134
|
end
|
156
135
|
end
|
157
136
|
|
@@ -1,99 +1,49 @@
|
|
1
|
-
require_relative 'role/
|
1
|
+
require_relative 'role/option_builder'
|
2
2
|
|
3
|
-
#
|
4
|
-
# as dynamically generated classes and permitted options for those roles as class instance variables on the @policy.
|
5
|
-
#
|
6
|
-
# @param permission_hash [Hash] hash containing the unrefined attributes and association options
|
7
|
-
# @param scope_hash [Hash] unused as of yet
|
3
|
+
# Extended by Policy::Base. Defines the methods necessary for declaring roles.
|
8
4
|
module Role
|
9
|
-
attr_accessor :permissions_hash, :scope_hash
|
10
|
-
@permissions_hash = {}
|
11
|
-
@scope_hash = {}
|
12
5
|
|
13
|
-
|
14
|
-
# to create the role
|
15
|
-
#
|
16
|
-
# @param role [Symbol, String] the role name
|
17
|
-
# @param opts [Hash] options for the role
|
18
|
-
def role(role, opts)
|
19
|
-
options = opts.slice(*_role_default_keys)
|
20
|
-
|
21
|
-
raise ArgumentError, 'You need to supply :authorize_with' unless options.slice(*_required_attributes).present?
|
22
|
-
|
23
|
-
unless role.is_a? Symbol or role.is_a? String
|
24
|
-
raise ArgumentError, "Expected Symbol or String for role, got #{role.class}"
|
25
|
-
end
|
26
|
-
|
27
|
-
create_role(role, self, options)
|
28
|
-
end
|
6
|
+
attr_accessor :permissions_hash
|
29
7
|
|
30
|
-
#
|
8
|
+
# Builds a new role by saving it into the #permissions_hash class instance variable
|
9
|
+
# Valid options are :attributes, :associations, :scope, :uses_db, :extend
|
31
10
|
#
|
32
|
-
# @param
|
33
|
-
# @
|
34
|
-
# @
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
@authorize_with = "#{opts[:authorize_with]}?"
|
39
|
-
@disable_merge = opts[:disable_merge]
|
40
|
-
}
|
41
|
-
rescue NameError => e
|
42
|
-
raise ArgumentError, "Something went wrong, possible NameError with #{policy} or #{role} => #{e.message}"
|
43
|
-
end
|
44
|
-
end
|
11
|
+
# @param *opts [Array] the roles, and the options which define the roles
|
12
|
+
# @raise [ArgumentError] if the options are incorrectly defined, or no options are present
|
13
|
+
# @return [Hash] Returns the permissions hash or the record
|
14
|
+
def role(*opts)
|
15
|
+
user_opts = opts.extract_options!.dup
|
16
|
+
options = user_opts.slice(*_role_default_keys)
|
45
17
|
|
46
|
-
|
47
|
-
#
|
48
|
-
# @param role [Symbol, String] the name of the role to which the opts are associated
|
49
|
-
# @param opts [Hash] the hash of options
|
50
|
-
def permitted_for(role, opts)
|
51
|
-
options = opts.slice(*_permitted_for_keys)
|
18
|
+
raise ArgumentError, 'Please provide at least one role' unless opts.present?
|
52
19
|
|
53
20
|
@permissions_hash = {} if @permissions_hash.nil?
|
54
|
-
@permissions_hash[role] = options
|
55
|
-
end
|
56
|
-
|
57
|
-
# Helper method to declare attributes directly
|
58
|
-
#
|
59
|
-
# @param role [Symbol, String] the name of the role to which the opts are associated
|
60
|
-
# @param attr [Hash] the hash of attributes
|
61
|
-
def permitted_attr_for(role, attr)
|
62
|
-
options = attr.slice(*_permitted_opt_for_keys)
|
63
21
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
22
|
+
options.each do |key, value|
|
23
|
+
if value.present?
|
24
|
+
expected = _role_option_validations[key]
|
25
|
+
do_raise = true
|
26
|
+
expected.each do |type|
|
27
|
+
do_raise = false if value.is_a? type
|
28
|
+
end
|
29
|
+
raise ArgumentError, "Expected #{expected} for #{key}, got #{value.class}" if do_raise
|
30
|
+
end
|
31
|
+
end
|
74
32
|
|
75
|
-
|
76
|
-
|
33
|
+
opts.each do |role|
|
34
|
+
raise ArgumentError, "Expected Symbol for #{role}, got #{role.class}" unless role.is_a? Symbol
|
35
|
+
@permissions_hash[role] = OptionBuilder.new(self, options[:attributes], options[:associations], options[:scope]).permitted
|
36
|
+
end
|
77
37
|
end
|
78
38
|
|
79
|
-
#
|
39
|
+
# @api private
|
80
40
|
private def _role_default_keys
|
81
|
-
[:
|
82
|
-
end
|
83
|
-
|
84
|
-
# required options for role declaration
|
85
|
-
private def _required_attributes
|
86
|
-
[:authorize_with]
|
87
|
-
end
|
88
|
-
|
89
|
-
# permitted options for permitted_for declaration
|
90
|
-
private def _permitted_for_keys
|
91
|
-
[:attributes, :associations]
|
41
|
+
[:attributes, :associations, :scope, :uses_db, :extend]
|
92
42
|
end
|
93
43
|
|
94
|
-
#
|
95
|
-
private def
|
96
|
-
[:
|
44
|
+
# @api private
|
45
|
+
private def _role_option_validations
|
46
|
+
{attributes: [Hash, Symbol], associations: [Hash, Symbol], scope: [String], uses_db: [Symbol], extend: [Symbol]}
|
97
47
|
end
|
98
48
|
|
99
|
-
end
|
49
|
+
end
|
data/lib/pundit_roles/pundit.rb
CHANGED
@@ -1,34 +1,36 @@
|
|
1
|
+
# Contains the overwritten #authorize method
|
1
2
|
module PunditOverwrite
|
2
3
|
|
3
4
|
# Overwrite for Pundit's default authorization, to be able to use PunditRoles. Does not conflict with existing
|
4
5
|
# Pundit implementations
|
5
6
|
#
|
6
|
-
# @param
|
7
|
+
# @param resource [Object] the object we're checking permissions of
|
7
8
|
# @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`).
|
8
9
|
# If omitted then this defaults to the Rails controller action name.
|
9
10
|
# @raise [NotAuthorizedError] if the given query method returned false
|
10
|
-
# @return [Object]
|
11
|
-
def authorize(
|
11
|
+
# @return [Object, Hash] Returns the permissions hash or the record
|
12
|
+
def authorize(resource, query = nil)
|
12
13
|
query ||= params[:action].to_s + '?'
|
13
14
|
|
14
15
|
@_pundit_policy_authorized = true
|
15
16
|
|
16
|
-
policy = policy(
|
17
|
+
policy = policy(resource)
|
17
18
|
|
18
19
|
permitted_records = policy.resolve_query(query)
|
19
20
|
|
20
21
|
unless permitted_records
|
21
|
-
raise Pundit::NotAuthorizedError, query: query, record:
|
22
|
+
raise Pundit::NotAuthorizedError, query: query, record: resource, policy: policy
|
22
23
|
end
|
23
24
|
|
24
25
|
if permitted_records.is_a? TrueClass
|
25
|
-
return
|
26
|
+
return resource
|
26
27
|
end
|
27
28
|
|
28
29
|
return permitted_records
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
33
|
+
# Prepends the PunditOverwrite to Pundit, in order to overwrite the default Pundit #authorize method
|
32
34
|
module Pundit
|
33
35
|
prepend PunditOverwrite
|
34
36
|
end
|
data/lib/pundit_roles/version.rb
CHANGED
data/lib/pundit_roles.rb
CHANGED
data/pundit_roles.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pundit_roles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Balogh
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-10-
|
11
|
+
date: 2017-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pundit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.1.0
|
27
41
|
description: Extends Pundit with roles
|
28
42
|
email:
|
29
43
|
- danielferencbalogh@gmail.com
|
@@ -31,8 +45,10 @@ executables: []
|
|
31
45
|
extensions: []
|
32
46
|
extra_rdoc_files: []
|
33
47
|
files:
|
48
|
+
- ".coveralls.yml"
|
34
49
|
- ".gitignore"
|
35
50
|
- ".travis.yml"
|
51
|
+
- CHANGELOG.md
|
36
52
|
- Gemfile
|
37
53
|
- LICENSE.txt
|
38
54
|
- README.md
|
@@ -41,9 +57,9 @@ files:
|
|
41
57
|
- bin/setup
|
42
58
|
- lib/pundit_roles.rb
|
43
59
|
- lib/pundit_roles/policy/base.rb
|
44
|
-
- lib/pundit_roles/policy/policy_defaults
|
60
|
+
- lib/pundit_roles/policy/policy_defaults.rb
|
45
61
|
- lib/pundit_roles/policy/role.rb
|
46
|
-
- lib/pundit_roles/policy/role/
|
62
|
+
- lib/pundit_roles/policy/role/option_builder.rb
|
47
63
|
- lib/pundit_roles/pundit.rb
|
48
64
|
- lib/pundit_roles/version.rb
|
49
65
|
- pundit_roles.gemspec
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module PolicyDefaults
|
2
|
-
module Defaults
|
3
|
-
# default index? method
|
4
|
-
def index?
|
5
|
-
false
|
6
|
-
end
|
7
|
-
|
8
|
-
# default show? method
|
9
|
-
def show?
|
10
|
-
false
|
11
|
-
end
|
12
|
-
|
13
|
-
# default create? method
|
14
|
-
def create?
|
15
|
-
false
|
16
|
-
end
|
17
|
-
|
18
|
-
# default update? method
|
19
|
-
def update?
|
20
|
-
false
|
21
|
-
end
|
22
|
-
|
23
|
-
# default destroy? method
|
24
|
-
def destroy?
|
25
|
-
false
|
26
|
-
end
|
27
|
-
|
28
|
-
# default authorization method
|
29
|
-
def default_authorization?
|
30
|
-
return false
|
31
|
-
end
|
32
|
-
|
33
|
-
# @authorize_with method for :guest role
|
34
|
-
def user_guest?
|
35
|
-
@user.nil?
|
36
|
-
end
|
37
|
-
|
38
|
-
# restricted attributes for show
|
39
|
-
def restricted_show_attributes
|
40
|
-
[]
|
41
|
-
end
|
42
|
-
|
43
|
-
# restricted attributes for save
|
44
|
-
def restricted_save_attributes
|
45
|
-
[:id, :created_at, :updated_at]
|
46
|
-
end
|
47
|
-
|
48
|
-
# restricted attributes for create
|
49
|
-
def restricted_create_attributes
|
50
|
-
[:id, :created_at, :updated_at]
|
51
|
-
end
|
52
|
-
|
53
|
-
# restricted attributes for update
|
54
|
-
def restricted_update_attributes
|
55
|
-
[:id, :created_at, :updated_at]
|
56
|
-
end
|
57
|
-
|
58
|
-
# restricted associations for show
|
59
|
-
def restricted_show_associations
|
60
|
-
[]
|
61
|
-
end
|
62
|
-
|
63
|
-
# restricted associations for save
|
64
|
-
def restricted_save_associations
|
65
|
-
[]
|
66
|
-
end
|
67
|
-
|
68
|
-
# restricted associations for create
|
69
|
-
def restricted_create_associations
|
70
|
-
[]
|
71
|
-
end
|
72
|
-
|
73
|
-
# restricted associations for update
|
74
|
-
def restricted_update_associations
|
75
|
-
[]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|