consul 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +27 -25
- data/.ruby-version +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -1
- data/Gemfile.5-2.lock +1 -1
- data/Gemfile.6-1.lock +1 -1
- data/Gemfile.7-0.lock +1 -1
- data/Gemfile.7-1 +17 -0
- data/Gemfile.7-1.lock +167 -0
- data/Gemfile.lock +1 -1
- data/README.md +50 -95
- data/lib/consul/active_record.rb +3 -1
- data/lib/consul/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee6dc0b253298727f44d5dfb975ab428349401e005b960156090591d930bfcf1
|
4
|
+
data.tar.gz: aeab801a53fd4c287736fb6f17397c24507b214fa77d803f6c1e54aa4d8dce50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6480d378cb267f8bd0e018f1b5f47f3d815aad2b7d2a0477042564fb3fce5fab348b93f217957e278d7b299813960a8eeea0ca832a35ca1d23a87335d10dae1
|
7
|
+
data.tar.gz: 60b20e4cfc85b430502fd6ff28b2403a152710b7c1ee1c56fa1121c162a079db4b1b18a8ac71c6b87cf8f94abb6be8afee38f35d0170187ad264e4a78d019e0c
|
data/.github/workflows/test.yml
CHANGED
@@ -3,10 +3,10 @@ name: Tests
|
|
3
3
|
on:
|
4
4
|
push:
|
5
5
|
branches:
|
6
|
-
|
6
|
+
- master
|
7
7
|
pull_request:
|
8
8
|
branches:
|
9
|
-
|
9
|
+
- master
|
10
10
|
jobs:
|
11
11
|
test:
|
12
12
|
runs-on: ubuntu-20.04
|
@@ -14,29 +14,31 @@ jobs:
|
|
14
14
|
fail-fast: false
|
15
15
|
matrix:
|
16
16
|
include:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
17
|
+
- ruby: 2.5.3
|
18
|
+
gemfile: Gemfile.5-2
|
19
|
+
- ruby: 2.5.3
|
20
|
+
gemfile: Gemfile.6-1
|
21
|
+
- ruby: 2.7.3
|
22
|
+
gemfile: Gemfile.6-1
|
23
|
+
- ruby: 2.7.3
|
24
|
+
gemfile: Gemfile.7-0
|
25
|
+
- ruby: 3.2.0
|
26
|
+
gemfile: Gemfile.6-1
|
27
|
+
- ruby: 3.2.0
|
28
|
+
gemfile: Gemfile.7-0
|
29
|
+
- ruby: 3.3.4
|
30
|
+
gemfile: Gemfile.7-1
|
29
31
|
env:
|
30
32
|
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
31
33
|
steps:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
- uses: actions/checkout@v2
|
35
|
+
- name: Install ruby
|
36
|
+
uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: "${{ matrix.ruby }}"
|
39
|
+
- name: Bundle
|
40
|
+
run: |
|
41
|
+
gem install bundler:1.17.3
|
42
|
+
bundle install --no-deployment
|
43
|
+
- name: Run tests
|
44
|
+
run: bundle exec rspec
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.3.4
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,12 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
9
9
|
|
10
10
|
### Compatible changes
|
11
11
|
|
12
|
+
## 1.3.2 - 2023-08-27
|
13
|
+
|
14
|
+
### Compatible changes
|
15
|
+
|
16
|
+
- Hook into railties correctly
|
17
|
+
|
12
18
|
## 1.3.1 - 2023-02-28
|
13
19
|
|
14
20
|
### Compatible changes
|
data/Gemfile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Gemfile.7-
|
1
|
+
Gemfile.7-1
|
data/Gemfile.5-2.lock
CHANGED
data/Gemfile.6-1.lock
CHANGED
data/Gemfile.7-0.lock
CHANGED
data/Gemfile.7-1
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Runtime dependencies
|
4
|
+
gem 'railties', '>= 7.0.1'
|
5
|
+
gem 'assignable_values'
|
6
|
+
|
7
|
+
# Development dependencies
|
8
|
+
gem 'rspec'
|
9
|
+
gem 'rspec-rails'
|
10
|
+
gem 'rspec_candy'
|
11
|
+
gem 'shoulda-matchers'
|
12
|
+
gem 'sqlite3', "~> 1.7"
|
13
|
+
gem 'database_cleaner'
|
14
|
+
gem 'gemika', '>= 0.8.1'
|
15
|
+
|
16
|
+
# Gem under test
|
17
|
+
gem 'consul', :path => '.'
|
data/Gemfile.7-1.lock
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
consul (1.3.2)
|
5
|
+
activerecord (>= 3.2)
|
6
|
+
activesupport (>= 3.2)
|
7
|
+
edge_rider (>= 0.3.0)
|
8
|
+
memoized (>= 1.0.2)
|
9
|
+
railties (>= 3.2)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
actionpack (7.1.3.4)
|
15
|
+
actionview (= 7.1.3.4)
|
16
|
+
activesupport (= 7.1.3.4)
|
17
|
+
nokogiri (>= 1.8.5)
|
18
|
+
racc
|
19
|
+
rack (>= 2.2.4)
|
20
|
+
rack-session (>= 1.0.1)
|
21
|
+
rack-test (>= 0.6.3)
|
22
|
+
rails-dom-testing (~> 2.2)
|
23
|
+
rails-html-sanitizer (~> 1.6)
|
24
|
+
actionview (7.1.3.4)
|
25
|
+
activesupport (= 7.1.3.4)
|
26
|
+
builder (~> 3.1)
|
27
|
+
erubi (~> 1.11)
|
28
|
+
rails-dom-testing (~> 2.2)
|
29
|
+
rails-html-sanitizer (~> 1.6)
|
30
|
+
activemodel (7.1.3.4)
|
31
|
+
activesupport (= 7.1.3.4)
|
32
|
+
activerecord (7.1.3.4)
|
33
|
+
activemodel (= 7.1.3.4)
|
34
|
+
activesupport (= 7.1.3.4)
|
35
|
+
timeout (>= 0.4.0)
|
36
|
+
activesupport (7.1.3.4)
|
37
|
+
base64
|
38
|
+
bigdecimal
|
39
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
40
|
+
connection_pool (>= 2.2.5)
|
41
|
+
drb
|
42
|
+
i18n (>= 1.6, < 2)
|
43
|
+
minitest (>= 5.1)
|
44
|
+
mutex_m
|
45
|
+
tzinfo (~> 2.0)
|
46
|
+
assignable_values (1.0.0)
|
47
|
+
activerecord (>= 2.3)
|
48
|
+
base64 (0.2.0)
|
49
|
+
bigdecimal (3.1.8)
|
50
|
+
builder (3.3.0)
|
51
|
+
concurrent-ruby (1.3.3)
|
52
|
+
connection_pool (2.4.1)
|
53
|
+
crass (1.0.6)
|
54
|
+
database_cleaner (2.0.2)
|
55
|
+
database_cleaner-active_record (>= 2, < 3)
|
56
|
+
database_cleaner-active_record (2.2.0)
|
57
|
+
activerecord (>= 5.a)
|
58
|
+
database_cleaner-core (~> 2.0.0)
|
59
|
+
database_cleaner-core (2.0.1)
|
60
|
+
diff-lcs (1.5.1)
|
61
|
+
drb (2.2.1)
|
62
|
+
edge_rider (2.3.0)
|
63
|
+
activerecord (>= 3.2)
|
64
|
+
erubi (1.13.0)
|
65
|
+
gemika (0.8.3)
|
66
|
+
i18n (1.14.5)
|
67
|
+
concurrent-ruby (~> 1.0)
|
68
|
+
io-console (0.7.2)
|
69
|
+
irb (1.14.0)
|
70
|
+
rdoc (>= 4.0.0)
|
71
|
+
reline (>= 0.4.2)
|
72
|
+
loofah (2.22.0)
|
73
|
+
crass (~> 1.0.2)
|
74
|
+
nokogiri (>= 1.12.0)
|
75
|
+
memoized (1.1.1)
|
76
|
+
mini_portile2 (2.8.7)
|
77
|
+
minitest (5.24.1)
|
78
|
+
mutex_m (0.2.0)
|
79
|
+
nokogiri (1.16.6)
|
80
|
+
mini_portile2 (~> 2.8.2)
|
81
|
+
racc (~> 1.4)
|
82
|
+
psych (5.1.2)
|
83
|
+
stringio
|
84
|
+
racc (1.8.0)
|
85
|
+
rack (3.1.7)
|
86
|
+
rack-session (2.0.0)
|
87
|
+
rack (>= 3.0.0)
|
88
|
+
rack-test (2.1.0)
|
89
|
+
rack (>= 1.3)
|
90
|
+
rackup (2.1.0)
|
91
|
+
rack (>= 3)
|
92
|
+
webrick (~> 1.8)
|
93
|
+
rails-dom-testing (2.2.0)
|
94
|
+
activesupport (>= 5.0.0)
|
95
|
+
minitest
|
96
|
+
nokogiri (>= 1.6)
|
97
|
+
rails-html-sanitizer (1.6.0)
|
98
|
+
loofah (~> 2.21)
|
99
|
+
nokogiri (~> 1.14)
|
100
|
+
railties (7.1.3.4)
|
101
|
+
actionpack (= 7.1.3.4)
|
102
|
+
activesupport (= 7.1.3.4)
|
103
|
+
irb
|
104
|
+
rackup (>= 1.0.0)
|
105
|
+
rake (>= 12.2)
|
106
|
+
thor (~> 1.0, >= 1.2.2)
|
107
|
+
zeitwerk (~> 2.6)
|
108
|
+
rake (13.2.1)
|
109
|
+
rdoc (6.7.0)
|
110
|
+
psych (>= 4.0.0)
|
111
|
+
reline (0.5.9)
|
112
|
+
io-console (~> 0.5)
|
113
|
+
rspec (3.13.0)
|
114
|
+
rspec-core (~> 3.13.0)
|
115
|
+
rspec-expectations (~> 3.13.0)
|
116
|
+
rspec-mocks (~> 3.13.0)
|
117
|
+
rspec-core (3.13.0)
|
118
|
+
rspec-support (~> 3.13.0)
|
119
|
+
rspec-expectations (3.13.1)
|
120
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
121
|
+
rspec-support (~> 3.13.0)
|
122
|
+
rspec-mocks (3.13.1)
|
123
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
124
|
+
rspec-support (~> 3.13.0)
|
125
|
+
rspec-rails (6.1.3)
|
126
|
+
actionpack (>= 6.1)
|
127
|
+
activesupport (>= 6.1)
|
128
|
+
railties (>= 6.1)
|
129
|
+
rspec-core (~> 3.13)
|
130
|
+
rspec-expectations (~> 3.13)
|
131
|
+
rspec-mocks (~> 3.13)
|
132
|
+
rspec-support (~> 3.13)
|
133
|
+
rspec-support (3.13.1)
|
134
|
+
rspec_candy (0.5.1)
|
135
|
+
rspec
|
136
|
+
sneaky-save
|
137
|
+
shoulda-matchers (6.2.0)
|
138
|
+
activesupport (>= 5.2.0)
|
139
|
+
sneaky-save (0.1.3)
|
140
|
+
activerecord (>= 3.2.0)
|
141
|
+
sqlite3 (1.7.3)
|
142
|
+
mini_portile2 (~> 2.8.0)
|
143
|
+
stringio (3.1.1)
|
144
|
+
thor (1.3.1)
|
145
|
+
timeout (0.4.1)
|
146
|
+
tzinfo (2.0.6)
|
147
|
+
concurrent-ruby (~> 1.0)
|
148
|
+
webrick (1.8.1)
|
149
|
+
zeitwerk (2.6.16)
|
150
|
+
|
151
|
+
PLATFORMS
|
152
|
+
ruby
|
153
|
+
|
154
|
+
DEPENDENCIES
|
155
|
+
assignable_values
|
156
|
+
consul!
|
157
|
+
database_cleaner
|
158
|
+
gemika (>= 0.8.1)
|
159
|
+
railties (>= 7.0.1)
|
160
|
+
rspec
|
161
|
+
rspec-rails
|
162
|
+
rspec_candy
|
163
|
+
shoulda-matchers
|
164
|
+
sqlite3 (~> 1.7)
|
165
|
+
|
166
|
+
BUNDLED WITH
|
167
|
+
2.5.15
|
data/Gemfile.lock
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Gemfile.7-
|
1
|
+
Gemfile.7-1.lock
|
data/README.md
CHANGED
@@ -1,19 +1,15 @@
|
|
1
|
-
Consul — A next gen authorization solution
|
2
|
-
==========================================
|
1
|
+
# Consul — A next gen authorization solution
|
3
2
|
|
4
3
|
[![Tests](https://github.com/makandra/consul/workflows/Tests/badge.svg)](https://github.com/makandra/consul/actions) [![Code Climate](https://codeclimate.com/github/makandra/consul.png)](https://codeclimate.com/github/makandra/consul)
|
5
4
|
|
6
|
-
|
7
|
-
Consul is an authorization solution for Ruby on Rails where you describe *sets of accessible things* to control what a user can see or edit.
|
5
|
+
Consul is an authorization solution for Ruby on Rails where you describe _sets of accessible things_ to control what a user can see or edit.
|
8
6
|
|
9
7
|
We have used Consul in combination with [assignable_values](https://github.com/makandra/assignable_values) to solve a variety of authorization requirements ranging from boring to bizarre.
|
10
8
|
Also see our crash course video: [Solving bizare authorization requirements with Rails](http://bizarre-authorization.talks.makandra.com/).
|
11
9
|
|
12
|
-
Consul is tested with Rails 5.2, 6.1
|
13
|
-
|
10
|
+
Consul is tested with Rails 5.2, 6.1, 7.0, 7.1 on Ruby 2.5, 2.7, 3.2, 3.3 (only if supported, for each Ruby/Rails combination). If you need support for Rails 3.2, please use [v0.13.2](https://github.com/makandra/consul/tree/v0.13.2).
|
14
11
|
|
15
|
-
Describing access to your application
|
16
|
-
-------------------------------------
|
12
|
+
## Describing access to your application
|
17
13
|
|
18
14
|
You describe access to your application by putting a `Power` model into `app/models/power.rb`.
|
19
15
|
Inside your `Power` you can talk about what is accessible for the current user, e.g.
|
@@ -51,10 +47,8 @@ There are no restrictions on the name or constructor arguments of this class.
|
|
51
47
|
|
52
48
|
You can deposit all kinds of objects in your power. See the sections below for details.
|
53
49
|
|
54
|
-
|
55
50
|
### Scope powers (relations)
|
56
51
|
|
57
|
-
|
58
52
|
A typical use case in a Rails application is to restrict access to your ActiveRecord models. For example:
|
59
53
|
|
60
54
|
- Anonymous visitors may only see public posts
|
@@ -111,13 +105,10 @@ power.note!(Note.last) # => raises Consul::Powerless unless the given Note is in
|
|
111
105
|
|
112
106
|
See our crash course video [Solving bizare authorization requirements with Rails](http://bizarre-authorization.talks.makandra.com/) for many different use cases you can cover with this pattern.
|
113
107
|
|
114
|
-
|
115
|
-
|
116
108
|
### Defining different powers for different actions
|
117
109
|
|
118
110
|
If you have different access rights for e.g. viewing or updating posts, simply use different powers:
|
119
111
|
|
120
|
-
|
121
112
|
```rb
|
122
113
|
class Power
|
123
114
|
...
|
@@ -139,8 +130,6 @@ end
|
|
139
130
|
|
140
131
|
There is also a [shortcut to map different powers to RESTful controller actions](#protect-entry-into-controller-actions).
|
141
132
|
|
142
|
-
|
143
|
-
|
144
133
|
### Boolean powers
|
145
134
|
|
146
135
|
Boolean powers are useful to control access to stuff that doesn't live in the database:
|
@@ -164,7 +153,6 @@ power.dashboard? # => true
|
|
164
153
|
power.dashboard! # => raises Consul::Powerless unless Power#dashboard? returns true
|
165
154
|
```
|
166
155
|
|
167
|
-
|
168
156
|
### Powers that give no access at all
|
169
157
|
|
170
158
|
Note that there is a difference between having access to an empty list of records, and having no access at all.
|
@@ -194,8 +182,6 @@ power.user?(User.last) # => returns false
|
|
194
182
|
power.user!(User.last) # => raises Consul::Powerless
|
195
183
|
```
|
196
184
|
|
197
|
-
|
198
|
-
|
199
185
|
### Powers that only check a given object
|
200
186
|
|
201
187
|
Sometimes it is not convenient to define powers as a collection or scope (relation).
|
@@ -203,7 +189,6 @@ Sometimes you only want to store a method that checks whether a given object is
|
|
203
189
|
|
204
190
|
To do so, simply define a power that ends in a question mark:
|
205
191
|
|
206
|
-
|
207
192
|
```rb
|
208
193
|
class Power
|
209
194
|
...
|
@@ -223,7 +208,6 @@ power.updatable_post?(Post.last) # return true if the author of the post is @use
|
|
223
208
|
power.updatable_post!(Post.last) # raises Consul::Powerless unless the author of the post is @user
|
224
209
|
```
|
225
210
|
|
226
|
-
|
227
211
|
### Other types of powers
|
228
212
|
|
229
213
|
A power can return any type of object. For instance, you often want to return an array:
|
@@ -254,7 +238,6 @@ power.assignable_note_state?('published') # => returns false
|
|
254
238
|
power.assignable_note_state!('published') # => raises Consul::Powerless
|
255
239
|
```
|
256
240
|
|
257
|
-
|
258
241
|
### Defining multiple powers at once
|
259
242
|
|
260
243
|
You can define multiple powers at once by giving multiple power names:
|
@@ -270,7 +253,6 @@ class Power
|
|
270
253
|
end
|
271
254
|
```
|
272
255
|
|
273
|
-
|
274
256
|
### Powers that require context (arguments)
|
275
257
|
|
276
258
|
Sometimes it can be useful to define powers that require context. To do so, just take an argument in your `power` block:
|
@@ -294,7 +276,6 @@ note = ...
|
|
294
276
|
Power.current.client_note?(client, note)
|
295
277
|
```
|
296
278
|
|
297
|
-
|
298
279
|
### Optimizing record checks for scope powers
|
299
280
|
|
300
281
|
You can query a scope power for a given record, e.g.
|
@@ -337,9 +318,7 @@ end
|
|
337
318
|
|
338
319
|
This way you do not need to touch the database at all.
|
339
320
|
|
340
|
-
|
341
|
-
Role-based permissions
|
342
|
-
----------------------
|
321
|
+
## Role-based permissions
|
343
322
|
|
344
323
|
Consul has no built-in support for role-based permissions, but you can easily implement it yourself. Let's say your `User` model has a string column `role` which can be `"author"` or `"admin"`:
|
345
324
|
|
@@ -367,9 +346,7 @@ class Power
|
|
367
346
|
end
|
368
347
|
```
|
369
348
|
|
370
|
-
|
371
|
-
Controller integration
|
372
|
-
----------------------
|
349
|
+
## Controller integration
|
373
350
|
|
374
351
|
It is convenient to expose the power for the current request to the rest of the application. Consul will help you with that if you tell it how to instantiate a power for the current request:
|
375
352
|
|
@@ -398,7 +375,6 @@ class NotesController < ApplicationController
|
|
398
375
|
end
|
399
376
|
```
|
400
377
|
|
401
|
-
|
402
378
|
### Protect entry into controller actions
|
403
379
|
|
404
380
|
To make sure a power is given before every action in a controller:
|
@@ -409,7 +385,7 @@ class NotesController < ApplicationController
|
|
409
385
|
end
|
410
386
|
```
|
411
387
|
|
412
|
-
You can use `:except` and `:only` options like in
|
388
|
+
You can use `:except` and `:only` options like in before_actions.
|
413
389
|
|
414
390
|
You can also map different powers to different actions:
|
415
391
|
|
@@ -441,7 +417,6 @@ class NotesController < ApplicationController
|
|
441
417
|
end
|
442
418
|
```
|
443
419
|
|
444
|
-
|
445
420
|
And if your power [requires context](#powers-that-require-context-arguments) (is parametrized), you can give it using the `:context` method:
|
446
421
|
|
447
422
|
```rb
|
@@ -458,8 +433,6 @@ class ClientNotesController < ApplicationController
|
|
458
433
|
end
|
459
434
|
```
|
460
435
|
|
461
|
-
|
462
|
-
|
463
436
|
### Auto-mapping a power scope to a controller method
|
464
437
|
|
465
438
|
It is often convenient to map a power scope to a private controller method:
|
@@ -486,7 +459,7 @@ class NotesController < ApplicationController
|
|
486
459
|
power :notes, :as => :note_scope
|
487
460
|
|
488
461
|
# ...
|
489
|
-
|
462
|
+
|
490
463
|
def note_scope
|
491
464
|
super.where(trashed: false)
|
492
465
|
end
|
@@ -494,7 +467,6 @@ class NotesController < ApplicationController
|
|
494
467
|
end
|
495
468
|
```
|
496
469
|
|
497
|
-
|
498
470
|
### Multiple power-mappings for nested resources
|
499
471
|
|
500
472
|
When using [nested resources](http://guides.rubyonrails.org/routing.html#nested-resources) you probably want two power
|
@@ -564,7 +536,7 @@ class ApplicationController < ActionController::Base
|
|
564
536
|
end
|
565
537
|
```
|
566
538
|
|
567
|
-
Note that this check is satisfied by
|
539
|
+
Note that this check is satisfied by _any_ `.power` directive in the controller class or its ancestors, even if that `.power` directive has `:only` or `:except` options that do not apply to the current action.
|
568
540
|
|
569
541
|
Should you want to forego the power check (e.g. to remove authorization checks from an entirely public controller):
|
570
542
|
|
@@ -574,9 +546,7 @@ class ApiController < ApplicationController
|
|
574
546
|
end
|
575
547
|
```
|
576
548
|
|
577
|
-
|
578
|
-
Validating assignable values
|
579
|
-
----------------------------
|
549
|
+
## Validating assignable values
|
580
550
|
|
581
551
|
Sometimes a scope is not enough to express what a user can edit. You will often want to give a user write access to a record, but restrict the values she can assign to a given field.
|
582
552
|
|
@@ -647,8 +617,7 @@ The `authorize_values_for` macro comes with many useful options and details best
|
|
647
617
|
assignable_values_for :field, :through => lambda { Power.current }
|
648
618
|
```
|
649
619
|
|
650
|
-
Memoization
|
651
|
-
-----------
|
620
|
+
## Memoization
|
652
621
|
|
653
622
|
All power methods are [memoized](https://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem/) for performance reasons. Multiple calls to the same method will only call your block the first time, and return a cached result afterwards:
|
654
623
|
|
@@ -665,9 +634,7 @@ If you want to discard all cached results, call `#unmemoize_all`:
|
|
665
634
|
power.unmemoize_all
|
666
635
|
```
|
667
636
|
|
668
|
-
|
669
|
-
Dynamic power access
|
670
|
-
--------------------
|
637
|
+
## Dynamic power access
|
671
638
|
|
672
639
|
Consul gives you a way to dynamically access and query powers for a given name, model class or record.
|
673
640
|
A common use case for this are generic helper methods, e.g. a method to display an "edit" link for any given record
|
@@ -687,30 +654,27 @@ end
|
|
687
654
|
|
688
655
|
You can find a full list of available dynamic calls below:
|
689
656
|
|
690
|
-
| Dynamic call
|
691
|
-
|
692
|
-
| `Power.current.send(:notes)`
|
693
|
-
| `Power.current.include_power?(:notes)`
|
694
|
-
| `Power.current.include_power!(:notes)`
|
695
|
-
| `Power.current.include_object?(:notes, Note.last)`
|
696
|
-
| `Power.current.include_object!(:notes, Note.last)`
|
697
|
-
| `Power.current.for_model(Note)`
|
698
|
-
| `Power.current.for_model(:updatable, Note)`
|
699
|
-
| `Power.current.include_model?(Note)`
|
700
|
-
| `Power.current.include_model?(:updatable, Note)`
|
701
|
-
| `Power.current.include_model!(Note)`
|
702
|
-
| `Power.current.include_model!(:updatable, Note)`
|
703
|
-
| `Power.current.include_record?(Note.last)`
|
704
|
-
| `Power.current.include_record?(:updatable, Note.last)`
|
705
|
-
| `Power.current.include_record!(Note.last)`
|
706
|
-
| `Power.current.include_record!(:updatable, Note.last)`
|
707
|
-
| `Power.current.name_for_model(Note)`
|
708
|
-
| `Power.current.name_for_model(:updatable, Note)`
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
Querying a power that might be nil
|
713
|
-
----------------------------------
|
657
|
+
| Dynamic call | Equivalent |
|
658
|
+
| ------------------------------------------------------ | ------------------------------------------ |
|
659
|
+
| `Power.current.send(:notes)` | `Power.current.notes` |
|
660
|
+
| `Power.current.include_power?(:notes)` | `Power.current.notes?` |
|
661
|
+
| `Power.current.include_power!(:notes)` | `Power.current.notes!` |
|
662
|
+
| `Power.current.include_object?(:notes, Note.last)` | `Power.current.note?(Note.last)` |
|
663
|
+
| `Power.current.include_object!(:notes, Note.last)` | `Power.current.note!(Note.last)` |
|
664
|
+
| `Power.current.for_model(Note)` | `Power.current.notes` |
|
665
|
+
| `Power.current.for_model(:updatable, Note)` | `Power.current.updatable_notes` |
|
666
|
+
| `Power.current.include_model?(Note)` | `Power.current.notes?` |
|
667
|
+
| `Power.current.include_model?(:updatable, Note)` | `Power.current.updatable_notes?` |
|
668
|
+
| `Power.current.include_model!(Note)` | `Power.current.notes!` |
|
669
|
+
| `Power.current.include_model!(:updatable, Note)` | `Power.current.updatable_notes!` |
|
670
|
+
| `Power.current.include_record?(Note.last)` | `Power.current.note?(Note.last)` |
|
671
|
+
| `Power.current.include_record?(:updatable, Note.last)` | `Power.current.updatable_note?(Note.last)` |
|
672
|
+
| `Power.current.include_record!(Note.last)` | `Power.current.note!(Note.last)` |
|
673
|
+
| `Power.current.include_record!(:updatable, Note.last)` | `Power.current.updatable_note!(Note.last)` |
|
674
|
+
| `Power.current.name_for_model(Note)` | `:notes` |
|
675
|
+
| `Power.current.name_for_model(:updatable, Note)` | `:updatable_notes` |
|
676
|
+
|
677
|
+
## Querying a power that might be nil
|
714
678
|
|
715
679
|
You will often want to access `Power.current` from another model, to e.g. iterate through the list of accessible users:
|
716
680
|
|
@@ -760,23 +724,20 @@ end
|
|
760
724
|
|
761
725
|
There is a long selection of class methods that behave neutrally in case `Power.current` is `nil`:
|
762
726
|
|
763
|
-
| Call
|
764
|
-
|
765
|
-
| `Power.for_model(Note)`
|
766
|
-
| `Power.for_model(:updatable, Note)`
|
767
|
-
| `Power.include_model?(Note)`
|
768
|
-
| `Power.include_model?(:updatable, Note)`
|
769
|
-
| `Power.include_model!(Note)`
|
770
|
-
| `Power.include_model!(:updatable, Note)`
|
771
|
-
| `Power.include_record?(Note.last)`
|
772
|
-
| `Power.include_record?(:updatable, Note.last)`
|
773
|
-
| `Power.include_record!(Note.last)`
|
774
|
-
| `Power.include_record!(:updatable, Note.last)`
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
Testing
|
779
|
-
-------
|
727
|
+
| Call | Equivalent |
|
728
|
+
| ---------------------------------------------- | ------------------------------------------------------------------- |
|
729
|
+
| `Power.for_model(Note)` | `Power.current.present? ? Power.current.notes : Note` |
|
730
|
+
| `Power.for_model(:updatable, Note)` | `Power.current.present? ? Power.current.updatable_notes : Note` |
|
731
|
+
| `Power.include_model?(Note)` | `Power.current.present? ? Power.notes? : true` |
|
732
|
+
| `Power.include_model?(:updatable, Note)` | `Power.current.present? ? Power.updatable_notes? : true` |
|
733
|
+
| `Power.include_model!(Note)` | `Power.notes! if Power.current.present?` |
|
734
|
+
| `Power.include_model!(:updatable, Note)` | `Power.updatable_notes! if Power.current.present?` |
|
735
|
+
| `Power.include_record?(Note.last)` | `Power.current.present? ? Power.note?(Note.last) : true` |
|
736
|
+
| `Power.include_record?(:updatable, Note.last)` | `Power.current.present? ? Power.updatable_note?(Note.last?) : true` |
|
737
|
+
| `Power.include_record!(Note.last)` | `Power.note!(Note.last) if Power.current.present?` |
|
738
|
+
| `Power.include_record!(:updatable, Note.last)` | `Power.updatable_note!(Note.last) if Power.current.present?` |
|
739
|
+
|
740
|
+
## Testing
|
780
741
|
|
781
742
|
This section Some hints for testing authorization with Consul.
|
782
743
|
|
@@ -847,9 +808,7 @@ Power.without_power do
|
|
847
808
|
end
|
848
809
|
```
|
849
810
|
|
850
|
-
|
851
|
-
Installation
|
852
|
-
------------
|
811
|
+
## Installation
|
853
812
|
|
854
813
|
Add the following to your `Gemfile`:
|
855
814
|
|
@@ -859,9 +818,7 @@ gem 'consul'
|
|
859
818
|
|
860
819
|
Now run `bundle install` to lock the gem into your project.
|
861
820
|
|
862
|
-
|
863
|
-
Development
|
864
|
-
-----------
|
821
|
+
## Development
|
865
822
|
|
866
823
|
We currently develop using Ruby 2.5.3 (see `.ruby-version`) since that version works for current versions of ActiveRecord that we support. GitHub Actions will test additional Ruby versions (2.3.8, 2.4.5, and 3.0.1).
|
867
824
|
|
@@ -884,8 +841,6 @@ Note that we have configured GitHub Actions to automatically run tests in all su
|
|
884
841
|
|
885
842
|
I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](mailto:henning.koch@makandra.de).
|
886
843
|
|
887
|
-
|
888
|
-
Credits
|
889
|
-
-------
|
844
|
+
## Credits
|
890
845
|
|
891
846
|
Henning Koch from [makandra](http://makandra.com/)
|
data/lib/consul/active_record.rb
CHANGED
data/lib/consul/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: consul
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henning Koch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: memoized
|
@@ -97,6 +97,8 @@ files:
|
|
97
97
|
- Gemfile.6-1.lock
|
98
98
|
- Gemfile.7-0
|
99
99
|
- Gemfile.7-0.lock
|
100
|
+
- Gemfile.7-1
|
101
|
+
- Gemfile.7-1.lock
|
100
102
|
- Gemfile.lock
|
101
103
|
- LICENSE
|
102
104
|
- README.md
|
@@ -135,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
137
|
- !ruby/object:Gem::Version
|
136
138
|
version: '0'
|
137
139
|
requirements: []
|
138
|
-
rubygems_version: 3.
|
140
|
+
rubygems_version: 3.5.11
|
139
141
|
signing_key:
|
140
142
|
specification_version: 4
|
141
143
|
summary: A scope-based authorization solution for Ruby on Rails.
|