consul 1.3.1 → 1.3.2
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/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
|
[](https://github.com/makandra/consul/actions) [](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.
|