rails_ops 1.5.7 → 1.6.0.rc0
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/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/ruby.yml +10 -4
- data/Appraisals +13 -8
- data/CHANGELOG.md +80 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +19 -20
- data/LICENSE +1 -1
- data/README.md +25 -5
- data/Rakefile +0 -10
- data/VERSION +1 -1
- data/gemfiles/rails_6.0.gemfile +9 -0
- data/gemfiles/rails_6.1.gemfile +9 -0
- data/gemfiles/rails_7.0.gemfile +9 -0
- data/gemfiles/rails_7.1.gemfile +9 -0
- data/gemfiles/rails_7.2.gemfile +16 -0
- data/gemfiles/rails_8.0.gemfile +16 -0
- data/lib/rails_ops/exceptions.rb +1 -1
- data/lib/rails_ops/log_subscriber.rb +1 -1
- data/lib/rails_ops/mixins/param_authorization.rb +2 -0
- data/lib/rails_ops/operation/model/destroy.rb +5 -0
- data/lib/rails_ops/operation/model/load.rb +10 -6
- data/lib/rails_ops/operation/model/update.rb +27 -19
- data/lib/rails_ops/operation/model.rb +2 -3
- data/lib/rails_ops/profiler.rb +1 -1
- data/lib/rails_ops.rb +1 -0
- data/rails_ops.gemspec +5 -15
- data/test/dummy/config/application.rb +1 -0
- data/test/test_helper.rb +0 -1
- data/test/unit/rails_ops/mixins/param_authorization_test.rb +35 -0
- data/test/unit/rails_ops/operation/auth_test.rb +16 -0
- data/test/unit/rails_ops/operation/model/load_test.rb +2 -4
- data/test/unit/rails_ops/operation/model/update_test.rb +76 -3
- data/test/unit/rails_ops/operation/update_lazy_auth_test.rb +40 -7
- data/test/unit/rails_ops/operation_test.rb +12 -4
- metadata +13 -151
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc1e32fdbfeebc90a622cb5394dcf1d4d7b41e2d8286a45eadfec4db6f0894e8
|
4
|
+
data.tar.gz: 5fcf1149cb2b0a348a6ecdb81e7c874056aa26bac979b436c17144ee48d7094b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0f97ccdac3919747d2c952805fc0e605e357e27ad8c3500f3e0e384e8063683a8031f9f8271ac3b492e1f9dca2633b57cdfad2cf81ec231b70cbeae8e54c797
|
7
|
+
data.tar.gz: f6a1e8a2eafc54e21a89f1b30b6c5d931ee90c4f352d8eed1df9f17e5f921b4da7115b2cc1d3bac35beaf0ebddfdf1cadffaaa7cd7ac7e935efb7ffcb742582d
|
data/.github/workflows/ruby.yml
CHANGED
@@ -14,13 +14,13 @@ jobs:
|
|
14
14
|
matrix:
|
15
15
|
include:
|
16
16
|
- rails-version: '6.0'
|
17
|
-
ruby-version: '2.7.
|
17
|
+
ruby-version: '2.7.8'
|
18
18
|
- rails-version: '6.1'
|
19
|
-
ruby-version: '2.7.
|
19
|
+
ruby-version: '2.7.8'
|
20
20
|
- rails-version: '6.1'
|
21
21
|
ruby-version: '3.0.1'
|
22
22
|
- rails-version: '7.0'
|
23
|
-
ruby-version: '2.7.
|
23
|
+
ruby-version: '2.7.8'
|
24
24
|
- rails-version: '7.0'
|
25
25
|
ruby-version: '3.0.1'
|
26
26
|
- rails-version: '7.0'
|
@@ -28,7 +28,7 @@ jobs:
|
|
28
28
|
- rails-version: '7.0'
|
29
29
|
ruby-version: '3.2.0'
|
30
30
|
- rails-version: '7.1'
|
31
|
-
ruby-version: '2.7.
|
31
|
+
ruby-version: '2.7.8'
|
32
32
|
- rails-version: '7.1'
|
33
33
|
ruby-version: '3.0.1'
|
34
34
|
- rails-version: '7.1'
|
@@ -37,6 +37,12 @@ jobs:
|
|
37
37
|
ruby-version: '3.2.0'
|
38
38
|
- rails-version: '7.1'
|
39
39
|
ruby-version: '3.3.0'
|
40
|
+
- rails-version: '8.0'
|
41
|
+
ruby-version: '3.2.0'
|
42
|
+
- rails-version: '8.0'
|
43
|
+
ruby-version: '3.3.0'
|
44
|
+
- rails-version: '8.0'
|
45
|
+
ruby-version: '3.4.0'
|
40
46
|
name: Test against Ruby ${{ matrix.ruby-version }} / Rails ${{ matrix.rails-version }}
|
41
47
|
env:
|
42
48
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails-version }}.gemfile
|
data/Appraisals
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
appraise 'rails-8.0' do
|
2
|
+
gem 'rails', '~> 8.0.1'
|
3
|
+
gem 'sqlite3', '~> 2.1'
|
4
|
+
end
|
5
|
+
|
6
|
+
appraise 'rails-7.2' do
|
7
|
+
gem 'rails', '~> 7.2.1'
|
8
|
+
end
|
9
|
+
|
10
|
+
appraise 'rails-7.1' do
|
11
|
+
gem 'rails', '~> 7.1.0'
|
12
|
+
end
|
13
|
+
|
1
14
|
appraise 'rails-7.0' do
|
2
15
|
gem 'rails', '~> 7.0.1'
|
3
16
|
end
|
@@ -9,11 +22,3 @@ end
|
|
9
22
|
appraise 'rails-6.0' do
|
10
23
|
gem 'rails', '~> 6.0.4'
|
11
24
|
end
|
12
|
-
|
13
|
-
appraise 'rails-5.2' do
|
14
|
-
gem 'rails', '~> 5.2.6'
|
15
|
-
end
|
16
|
-
|
17
|
-
appraise 'rails-5.1' do
|
18
|
-
gem 'rails', '~> 5.1.7'
|
19
|
-
end
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,85 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.6.0.rc0 (2025-01-22)
|
4
|
+
|
5
|
+
* Adapt the way model authorization works for an additional layer of security:
|
6
|
+
|
7
|
+
* Update-Operations (operations inheriting from `RailsOps::Operation::Model::Update`)
|
8
|
+
now perform their model authorization immediately after the model is loaded (in `build_model`).
|
9
|
+
|
10
|
+
Previously, the authorization was only performed after the attributes have
|
11
|
+
already been assigned, never checking authorization against the "pristine"
|
12
|
+
model.
|
13
|
+
|
14
|
+
* Load-Operations (operations inheriting from
|
15
|
+
`RailsOps::Operation::Model::Load`) now always load their associated model
|
16
|
+
**directly on OP instantiation**. Previously, this was only the case if load
|
17
|
+
model authorization was enabled.
|
18
|
+
|
19
|
+
In addition, the method `model_authorization` has been renamed to
|
20
|
+
`load_model_authorization` in order to separate it from the method
|
21
|
+
`model_authorization` in `RailsOps::Operation::Model::Update`.
|
22
|
+
|
23
|
+
Internal reference: `#133622`.
|
24
|
+
|
25
|
+
### Migrating from earlier versions
|
26
|
+
|
27
|
+
Check that operations using model authorization still work as expected, especially
|
28
|
+
operations inheriting from `RailsOps::Operation::Model::Update` or from
|
29
|
+
`RailsOps::Operation::Model::Load`:
|
30
|
+
|
31
|
+
* For operations inheriting from `RailsOps::Operation::Model::Load`: Rename all
|
32
|
+
uses of `model_authorization` to `load_model_authorization`.
|
33
|
+
|
34
|
+
* For operations inheriting from `RailsOps::Operation::Model::Update`, you need
|
35
|
+
to make sure that running the model authorization on the "pristine" model (before
|
36
|
+
assigning the new attributes) is still applying your authorization logic in
|
37
|
+
the correct way (i.e. authorizing on the model *before* assigning the attributes
|
38
|
+
applies authorization correctly).
|
39
|
+
If you need to authorize the state *after* assigning the params to the model,
|
40
|
+
you'll need add that check manually in your operation.
|
41
|
+
|
42
|
+
|
43
|
+
One example of how this behaviour was changed: A user may only update
|
44
|
+
a `Group` object with a `color` of `'red'`:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class Ability
|
48
|
+
can :update, Group, color: 'red'
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
Before, this was the way RailsOps handled it:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
model = find_record(params[:id]) # => model = Group(color: 'blue')
|
56
|
+
model.assign_attributes(params) # params = { color: 'red' }
|
57
|
+
authorize! :update, model
|
58
|
+
```
|
59
|
+
|
60
|
+
This works, because RailsOps already assigned `'red'` to the `color` attribute of the model. This means
|
61
|
+
that the `authorize!` call will succeed, even though the original model in the database is not permissible
|
62
|
+
to be updated by the user.
|
63
|
+
|
64
|
+
Afterwards, the behaviour is as follows:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
model = find_record(params[:id]) # => model = Group(color: 'blue')
|
68
|
+
authorize! :update, model # => Fails with CanCan::AccessDenied, as the user may not update the group
|
69
|
+
# [...]
|
70
|
+
```
|
71
|
+
|
72
|
+
After applying these changes, carefully test your application, run unit tests etc.
|
73
|
+
to ensure all operations still behave as expected in regards to authorization.
|
74
|
+
|
75
|
+
## 1.5.8 (2024-09-11)
|
76
|
+
|
77
|
+
* Also allow single path segments as symbols instead of array for
|
78
|
+
`authorize_param`'s `path` argument. Before, paths that were not arrays would
|
79
|
+
lead to the param authorization being ignored silently.
|
80
|
+
|
81
|
+
Internal reference: `#128987`.
|
82
|
+
|
3
83
|
## 1.5.7 (2024-08-22)
|
4
84
|
|
5
85
|
* Fix compatibility issue with older versions of Rails introduced in version
|
data/Gemfile
CHANGED
@@ -2,3 +2,14 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in rails_ops.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
# Development dependencies should be specified in here
|
7
|
+
gem 'appraisal'
|
8
|
+
gem 'bundler'
|
9
|
+
gem 'cancancan'
|
10
|
+
gem 'pry'
|
11
|
+
gem 'rake'
|
12
|
+
gem 'rubocop', '1.70.0'
|
13
|
+
gem 'simplecov'
|
14
|
+
gem 'sprockets-rails'
|
15
|
+
gem 'sqlite3', '<2.0.0'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rails_ops (1.
|
4
|
+
rails_ops (1.6.0.rc0)
|
5
5
|
active_type (>= 1.3.0)
|
6
6
|
minitest
|
7
7
|
rails
|
@@ -97,7 +97,6 @@ GEM
|
|
97
97
|
builder (3.2.4)
|
98
98
|
cancancan (3.5.0)
|
99
99
|
coderay (1.1.3)
|
100
|
-
colorize (0.8.1)
|
101
100
|
concurrent-ruby (1.3.1)
|
102
101
|
connection_pool (2.4.1)
|
103
102
|
crass (1.0.6)
|
@@ -113,7 +112,8 @@ GEM
|
|
113
112
|
irb (1.11.2)
|
114
113
|
rdoc
|
115
114
|
reline (>= 0.4.2)
|
116
|
-
json (2.
|
115
|
+
json (2.9.1)
|
116
|
+
language_server-protocol (3.17.0.3)
|
117
117
|
loofah (2.22.0)
|
118
118
|
crass (~> 1.0.2)
|
119
119
|
nokogiri (>= 1.12.0)
|
@@ -141,9 +141,10 @@ GEM
|
|
141
141
|
racc (~> 1.4)
|
142
142
|
nokogiri (1.16.5-x86_64-linux)
|
143
143
|
racc (~> 1.4)
|
144
|
-
parallel (1.
|
145
|
-
parser (3.
|
144
|
+
parallel (1.26.3)
|
145
|
+
parser (3.3.7.0)
|
146
146
|
ast (~> 2.4.1)
|
147
|
+
racc
|
147
148
|
pry (0.14.2)
|
148
149
|
coderay (~> 1.1)
|
149
150
|
method_source (~> 1.0)
|
@@ -191,25 +192,23 @@ GEM
|
|
191
192
|
rake (13.1.0)
|
192
193
|
rdoc (6.6.3.1)
|
193
194
|
psych (>= 4.0.0)
|
194
|
-
regexp_parser (2.
|
195
|
+
regexp_parser (2.10.0)
|
195
196
|
reline (0.4.3)
|
196
197
|
io-console (~> 0.5)
|
197
198
|
request_store (1.5.1)
|
198
199
|
rack (>= 1.4)
|
199
|
-
|
200
|
-
strscan
|
201
|
-
rubocop (1.45.1)
|
200
|
+
rubocop (1.70.0)
|
202
201
|
json (~> 2.3)
|
202
|
+
language_server-protocol (>= 3.17.0)
|
203
203
|
parallel (~> 1.10)
|
204
|
-
parser (>= 3.
|
204
|
+
parser (>= 3.3.0.2)
|
205
205
|
rainbow (>= 2.2.2, < 4.0)
|
206
|
-
regexp_parser (>=
|
207
|
-
|
208
|
-
rubocop-ast (>= 1.24.1, < 2.0)
|
206
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
207
|
+
rubocop-ast (>= 1.36.2, < 2.0)
|
209
208
|
ruby-progressbar (~> 1.7)
|
210
|
-
unicode-display_width (>= 2.4.0, <
|
211
|
-
rubocop-ast (1.
|
212
|
-
parser (>= 3.
|
209
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
210
|
+
rubocop-ast (1.37.0)
|
211
|
+
parser (>= 3.3.1.0)
|
213
212
|
ruby-progressbar (1.13.0)
|
214
213
|
ruby2_keywords (0.0.4)
|
215
214
|
schemacop (3.0.22)
|
@@ -231,12 +230,13 @@ GEM
|
|
231
230
|
sqlite3 (1.6.2-x86_64-darwin)
|
232
231
|
sqlite3 (1.6.2-x86_64-linux)
|
233
232
|
stringio (3.1.0)
|
234
|
-
strscan (3.1.0)
|
235
233
|
thor (1.3.1)
|
236
234
|
timeout (0.4.1)
|
237
235
|
tzinfo (2.0.6)
|
238
236
|
concurrent-ruby (~> 1.0)
|
239
|
-
unicode-display_width (
|
237
|
+
unicode-display_width (3.1.4)
|
238
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
239
|
+
unicode-emoji (4.0.4)
|
240
240
|
webrick (1.8.1)
|
241
241
|
websocket-driver (0.7.6)
|
242
242
|
websocket-extensions (>= 0.1.0)
|
@@ -254,11 +254,10 @@ DEPENDENCIES
|
|
254
254
|
appraisal
|
255
255
|
bundler
|
256
256
|
cancancan
|
257
|
-
colorize
|
258
257
|
pry
|
259
258
|
rails_ops!
|
260
259
|
rake
|
261
|
-
rubocop (= 1.
|
260
|
+
rubocop (= 1.70.0)
|
262
261
|
simplecov
|
263
262
|
sprockets-rails
|
264
263
|
sqlite3 (< 2.0.0)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -28,12 +28,15 @@ Requirements & Installation
|
|
28
28
|
* Rails 6.1.x
|
29
29
|
* Rails 7.0.x
|
30
30
|
* Rails 7.1.x
|
31
|
+
* Rails 7.2.x
|
32
|
+
* Rails 8.0.x
|
31
33
|
- Additionally, the following Ruby versions are covered by our unit tests:
|
32
|
-
* 2.7.
|
34
|
+
* 2.7.8
|
33
35
|
* 3.0.1
|
34
36
|
* 3.1.0
|
35
37
|
* 3.2.0
|
36
38
|
* 3.3.0
|
39
|
+
* 3.4.0
|
37
40
|
- Please see the [unit test workflow](https://github.com/sitrox/rails_ops/actions/workflows/ruby.yml) for the combinations of the Rails & Ruby versions, as only compatible versions are tested with each other.
|
38
41
|
- Prior Rails and Ruby versions may be supported but they are not tested in the CI.
|
39
42
|
- Rails Ops' model operations require ActiveRecord but are database / adapter
|
@@ -1352,8 +1355,9 @@ authorization check based on this model.
|
|
1352
1355
|
|
1353
1356
|
While you can override this method to perform custom authorization, RailsOps
|
1354
1357
|
provides a base implementation. Using the class method
|
1355
|
-
`model_authorization_action
|
1356
|
-
|
1358
|
+
`model_authorization_action` (or `load_model_authorization` for operations
|
1359
|
+
inheriting from `RailsOps::Operation::Model::Load`), you can specify an action
|
1360
|
+
verb that is used for authorizing your model.
|
1357
1361
|
|
1358
1362
|
```ruby
|
1359
1363
|
class Operations::User::Load < RailsOps::Operation::Model::Load
|
@@ -1361,7 +1365,23 @@ class Operations::User::Load < RailsOps::Operation::Model::Load
|
|
1361
1365
|
|
1362
1366
|
# This automatically calls `authorize_model! :read` after operation
|
1363
1367
|
# instantiation.
|
1364
|
-
|
1368
|
+
load_model_authorization :read
|
1369
|
+
end
|
1370
|
+
```
|
1371
|
+
|
1372
|
+
Another example for an update operation:
|
1373
|
+
|
1374
|
+
```ruby
|
1375
|
+
class Operations::User::Update < RailsOps::Operation::Model::Update
|
1376
|
+
model User
|
1377
|
+
|
1378
|
+
# This automatically calls `authorize_model! :read` after operation
|
1379
|
+
# instantiation.
|
1380
|
+
load_model_authorization :read
|
1381
|
+
|
1382
|
+
# This automatically calls `authorize_model! :update` after operation
|
1383
|
+
# instantiation.
|
1384
|
+
model_authorization :update
|
1365
1385
|
end
|
1366
1386
|
```
|
1367
1387
|
|
@@ -1792,4 +1812,4 @@ Rails architecture.
|
|
1792
1812
|
|
1793
1813
|
## Copyright
|
1794
1814
|
|
1795
|
-
Copyright © 2017 -
|
1815
|
+
Copyright © 2017 - 2025 Sitrox. See `LICENSE` for further details.
|
data/Rakefile
CHANGED
@@ -16,16 +16,6 @@ task :gemspec do
|
|
16
16
|
spec.require_paths = ['lib']
|
17
17
|
spec.licenses = ['MIT']
|
18
18
|
|
19
|
-
spec.add_development_dependency 'appraisal'
|
20
|
-
spec.add_development_dependency 'bundler'
|
21
|
-
spec.add_development_dependency 'rake'
|
22
|
-
spec.add_development_dependency 'sqlite3', '<2.0.0'
|
23
|
-
spec.add_development_dependency 'cancancan'
|
24
|
-
spec.add_development_dependency 'pry'
|
25
|
-
spec.add_development_dependency 'colorize'
|
26
|
-
spec.add_development_dependency 'rubocop', '1.45.1'
|
27
|
-
spec.add_development_dependency 'sprockets-rails'
|
28
|
-
spec.add_development_dependency 'simplecov'
|
29
19
|
spec.add_dependency 'active_type', '>= 1.3.0'
|
30
20
|
spec.add_dependency 'minitest'
|
31
21
|
spec.add_dependency 'rails'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.6.0.rc0
|
data/gemfiles/rails_6.0.gemfile
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
+
gem 'appraisal'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'cancancan'
|
8
|
+
gem 'pry'
|
5
9
|
gem 'rails', '~> 6.0.4'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '1.70.0'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'sprockets-rails'
|
14
|
+
gem 'sqlite3', '<2.0.0'
|
6
15
|
|
7
16
|
gemspec path: '../'
|
data/gemfiles/rails_6.1.gemfile
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
+
gem 'appraisal'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'cancancan'
|
8
|
+
gem 'pry'
|
5
9
|
gem 'rails', '~> 6.1.4'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '1.70.0'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'sprockets-rails'
|
14
|
+
gem 'sqlite3', '<2.0.0'
|
6
15
|
|
7
16
|
gemspec path: '../'
|
data/gemfiles/rails_7.0.gemfile
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
+
gem 'appraisal'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'cancancan'
|
8
|
+
gem 'pry'
|
5
9
|
gem 'rails', '~> 7.0.1'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '1.70.0'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'sprockets-rails'
|
14
|
+
gem 'sqlite3', '<2.0.0'
|
6
15
|
|
7
16
|
gemspec path: '../'
|
data/gemfiles/rails_7.1.gemfile
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
+
gem 'appraisal'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'cancancan'
|
8
|
+
gem 'pry'
|
5
9
|
gem 'rails', '~> 7.1.0'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '1.70.0'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'sprockets-rails'
|
14
|
+
gem 'sqlite3', '<2.0.0'
|
6
15
|
|
7
16
|
gemspec path: '../'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
gem 'appraisal'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'cancancan'
|
8
|
+
gem 'pry'
|
9
|
+
gem 'rails', '~> 7.2.1'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '1.70.0'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'sprockets-rails'
|
14
|
+
gem 'sqlite3', '<2.0.0'
|
15
|
+
|
16
|
+
gemspec path: '../'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
gem 'appraisal'
|
6
|
+
gem 'bundler'
|
7
|
+
gem 'cancancan'
|
8
|
+
gem 'pry'
|
9
|
+
gem 'rails', '~> 8.0.1'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '1.70.0'
|
12
|
+
gem 'simplecov'
|
13
|
+
gem 'sprockets-rails'
|
14
|
+
gem 'sqlite3', '~> 2.1'
|
15
|
+
|
16
|
+
gemspec path: '../'
|
data/lib/rails_ops/exceptions.rb
CHANGED
@@ -29,6 +29,8 @@ module RailsOps::Mixins::ParamAuthorization
|
|
29
29
|
# authorization backend. The block receives no arguments and is executed
|
30
30
|
# in context of the operation instance.
|
31
31
|
def authorize_param(path, action = nil, *args, &block)
|
32
|
+
path = Array(path)
|
33
|
+
|
32
34
|
# Validate parameters
|
33
35
|
if block_given? && (action || args.any?)
|
34
36
|
fail ArgumentError,
|
@@ -4,7 +4,7 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
|
4
4
|
class_attribute :_lock_mode
|
5
5
|
|
6
6
|
policy :on_init do
|
7
|
-
|
7
|
+
model
|
8
8
|
end
|
9
9
|
|
10
10
|
# Gets or sets the action verb used for authorizing models on load.
|
@@ -18,10 +18,8 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
|
18
18
|
return _load_model_authorization_action
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
unless load_model_authorization_action.nil?
|
21
|
+
def load_model_authorization
|
22
|
+
if authorization_enabled? && load_model_authorization_action.present?
|
25
23
|
authorize_model! load_model_authorization_action, model
|
26
24
|
end
|
27
25
|
end
|
@@ -78,12 +76,18 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
|
78
76
|
relation = lock_relation(relation)
|
79
77
|
|
80
78
|
# Fetch (and possibly lock) model
|
81
|
-
|
79
|
+
model = relation.find_by!(model_id_field => params[model_id_field])
|
80
|
+
|
81
|
+
# Return model
|
82
|
+
return model
|
82
83
|
end
|
83
84
|
|
84
85
|
def build_model
|
85
86
|
@model = find_model
|
86
87
|
|
88
|
+
# Perform load model authorization
|
89
|
+
load_model_authorization
|
90
|
+
|
87
91
|
if @model.respond_to?(:parent_op=)
|
88
92
|
@model.parent_op = self
|
89
93
|
end
|
@@ -8,36 +8,44 @@ class RailsOps::Operation::Model::Update < RailsOps::Operation::Model::Load
|
|
8
8
|
true
|
9
9
|
end
|
10
10
|
|
11
|
-
policy :
|
12
|
-
if
|
13
|
-
|
11
|
+
policy :on_init do
|
12
|
+
if self.class._model_authorization_lazy && load_model_authorization_action.nil?
|
13
|
+
fail RailsOps::Exceptions::NoAuthorizationPerformed,
|
14
|
+
"Operation #{self.class.name} must specify a " \
|
15
|
+
'load_model_authorization_action because model ' \
|
16
|
+
'authorization is configured to be lazy.'
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if self.class._model_authorization_lazy
|
21
|
-
|
22
|
-
fail RailsOps::Exceptions::NoAuthorizationPerformed,
|
23
|
-
"Operation #{self.class.name} must specify a " \
|
24
|
-
'load_model_authorization_action because model ' \
|
25
|
-
'authorization is configured to be lazy.'
|
26
|
-
else
|
27
|
-
authorize_model! load_model_authorization_action, model
|
28
|
-
end
|
29
|
-
elsif !load_model_authorization_action.nil?
|
30
|
-
authorize_model_with_authorize_only! load_model_authorization_action, model
|
31
|
-
end
|
20
|
+
policy :before_perform do
|
21
|
+
# If the authorization is configured to be lazy, we need to call the authorization
|
22
|
+
# on the copy of the model that we made before assigning the new attributes.
|
23
|
+
authorize_model! model_authorization_action, @model_before_assigning_attributes if self.class._model_authorization_lazy
|
24
|
+
end
|
32
25
|
|
33
|
-
|
26
|
+
def model_authorization
|
27
|
+
if authorization_enabled? && model_authorization_action.present?
|
34
28
|
authorize_model! model_authorization_action, model
|
35
29
|
end
|
36
30
|
end
|
37
31
|
|
38
32
|
def build_model
|
33
|
+
# Load model via parent class
|
39
34
|
super
|
35
|
+
|
36
|
+
# Build nested model operations
|
40
37
|
build_nested_model_ops :update
|
38
|
+
|
39
|
+
# Perform update authorization BEFORE assigning attributes. If the authorization is lazy,
|
40
|
+
# we copy the model before assigning the attributes, such that we can call the authorization
|
41
|
+
# later on.
|
42
|
+
if self.class._model_authorization_lazy
|
43
|
+
@model_before_assigning_attributes = @model.dup
|
44
|
+
else
|
45
|
+
model_authorization
|
46
|
+
end
|
47
|
+
|
48
|
+
# Assign attributes
|
41
49
|
assign_attributes
|
42
50
|
end
|
43
51
|
|
@@ -169,9 +169,8 @@ class RailsOps::Operation::Model < RailsOps::Operation
|
|
169
169
|
|
170
170
|
protected
|
171
171
|
|
172
|
-
# Performs nested model operations and then saves the model.
|
173
|
-
#
|
174
|
-
# `model.save!` directly.
|
172
|
+
# Performs nested model operations and then saves the model. You should always
|
173
|
+
# call this method instead of invoking "model.save!" directly.
|
175
174
|
def save!
|
176
175
|
run_policies :before_nested_model_ops
|
177
176
|
perform_nested_model_ops!
|
data/lib/rails_ops/profiler.rb
CHANGED