miau 1.0.3 → 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.gitignore +7 -4
  4. data/.ruby-version +1 -1
  5. data/Gemfile +5 -3
  6. data/Gemfile.lock +190 -18
  7. data/LICENSE +1 -1
  8. data/README.md +35 -17
  9. data/Rakefile +4 -6
  10. data/gemfiles/rails_6.1.gemfile +3 -2
  11. data/gemfiles/rails_7.0.gemfile +3 -2
  12. data/gemfiles/rails_7.1.gemfile +3 -2
  13. data/lib/miau/application_policy.rb +3 -2
  14. data/lib/miau/error.rb +3 -0
  15. data/lib/miau/run.rb +48 -0
  16. data/lib/miau/storage.rb +18 -52
  17. data/lib/miau/version.rb +4 -1
  18. data/lib/miau.rb +28 -19
  19. data/miau.gemspec +6 -9
  20. data/test/authorization_test.rb +28 -0
  21. data/test/benchmark_test.rb +34 -0
  22. data/test/controller_test.rb +58 -0
  23. data/test/controllers/orders_controller_test.rb +47 -0
  24. data/test/internal/app/controllers/application_controller.rb +7 -0
  25. data/test/internal/app/controllers/orders_controller.rb +61 -0
  26. data/test/internal/app/controllers/posts_controller.rb +10 -0
  27. data/test/internal/app/models/application_record.rb +3 -0
  28. data/test/internal/app/models/order.rb +2 -0
  29. data/test/internal/app/models/post.rb +2 -0
  30. data/test/internal/app/policies/orders_policy.rb +16 -0
  31. data/test/internal/app/policies/posts_policy.rb +18 -0
  32. data/test/internal/app/views/orders/new.html.erb +5 -0
  33. data/test/internal/config/database.yml +3 -0
  34. data/test/internal/config/routes.rb +3 -0
  35. data/test/internal/db/migrate/20141016161801_create_orders.rb +10 -0
  36. data/test/internal/db/schema.rb +8 -0
  37. data/test/miau_test.rb +46 -0
  38. data/test/run_test.rb +69 -0
  39. data/test/storage_test.rb +51 -0
  40. data/test/test_helper.rb +17 -0
  41. metadata +33 -14
  42. data/gemfiles/rails_6.1.gemfile.lock +0 -224
  43. data/gemfiles/rails_7.0.gemfile.lock +0 -256
  44. data/gemfiles/rails_7.1.gemfile.lock +0 -254
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '008262a0054143f56caffceb6dfa57f195963ff6b98cc07aa6452778f5ad87b5'
4
- data.tar.gz: 1eca9f4196b9569d0515b9c14da47182fecdd1c05b6bbc388b1f16226bb3ee36
3
+ metadata.gz: 4ff4fcf400151bdd20347e5bc2cd8f215a11e8ea6b519840c6032ed3ac18a57b
4
+ data.tar.gz: bc678ee4c5c2029d66a5f9d7970ae81e0eb334bb4a493cde94f3445f5d1a9e25
5
5
  SHA512:
6
- metadata.gz: 62497618e0cb83822bb448d9d6a7fbeac80943163284677033dc1e8b555b42440434ff3f16dec7ed16f1b3b1db629815bd42530cf0de1ea457b2eb2ec6cecc96
7
- data.tar.gz: f2d0a731b6a61448790ab745332e2d6f4bf9225fbb9aa947a7fa4438f15bb0a1818df4cbec818c5546ced6b166825a8ecabb35b5fdc060482faee7fae097d18e
6
+ metadata.gz: a2f4c5d1a4b5947fe6d5ff836291909d5428de7e0745d7e50654327637b173c573646446c4846ca62789b1f590e13fe43f057fa82eac7a03c85faf7483115014
7
+ data.tar.gz: f87d22f71705710792a13a2490d71a632a3c55fd0f40bd7cf5e342d58b58c6066777e23dab777af0a0e674103182dec768caf04a73d9f6db58a35ed5453f2e9a
@@ -8,7 +8,7 @@ jobs:
8
8
  strategy:
9
9
  fail-fast: false
10
10
  matrix:
11
- ruby_version: ["2.7", "3.0", "3.2", head]
11
+ ruby_version: ["3.0", 3.2, 3.3]
12
12
  gemfile:
13
13
  - Gemfile
14
14
  - gemfiles/Gemfile.rails-7.1
data/.gitignore CHANGED
@@ -1,7 +1,10 @@
1
1
  /.bundle/
2
- /Gemfile.lock
2
+ /tmp/
3
3
  /coverage/
4
- .watchr
4
+ /.watchr
5
5
 
6
- /doc/
7
- /tmp/
6
+ *.gem
7
+ *.log
8
+ *.lock
9
+
10
+ **/db/test.sqlite*
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.2.2
1
+ ruby-3.3.0
data/Gemfile CHANGED
@@ -1,10 +1,12 @@
1
1
  source "https://rubygems.org"
2
-
3
2
  gemspec
4
3
 
4
+ gem "rails"
5
+
5
6
  group :test do
7
+ gem "benchmark-ips"
6
8
  gem "observr"
7
- gem "standard", require: false
9
+ gem "ricecream"
8
10
  gem "simplecov", require: false
9
- gem "benchmark-ips"
11
+ gem "standard", require: false
10
12
  end
data/Gemfile.lock CHANGED
@@ -1,12 +1,75 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- miau (1.0.3)
5
- activesupport
4
+ miau (1.1.6)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
9
8
  specs:
9
+ actioncable (7.1.2)
10
+ actionpack (= 7.1.2)
11
+ activesupport (= 7.1.2)
12
+ nio4r (~> 2.0)
13
+ websocket-driver (>= 0.6.1)
14
+ zeitwerk (~> 2.6)
15
+ actionmailbox (7.1.2)
16
+ actionpack (= 7.1.2)
17
+ activejob (= 7.1.2)
18
+ activerecord (= 7.1.2)
19
+ activestorage (= 7.1.2)
20
+ activesupport (= 7.1.2)
21
+ mail (>= 2.7.1)
22
+ net-imap
23
+ net-pop
24
+ net-smtp
25
+ actionmailer (7.1.2)
26
+ actionpack (= 7.1.2)
27
+ actionview (= 7.1.2)
28
+ activejob (= 7.1.2)
29
+ activesupport (= 7.1.2)
30
+ mail (~> 2.5, >= 2.5.4)
31
+ net-imap
32
+ net-pop
33
+ net-smtp
34
+ rails-dom-testing (~> 2.2)
35
+ actionpack (7.1.2)
36
+ actionview (= 7.1.2)
37
+ activesupport (= 7.1.2)
38
+ nokogiri (>= 1.8.5)
39
+ racc
40
+ rack (>= 2.2.4)
41
+ rack-session (>= 1.0.1)
42
+ rack-test (>= 0.6.3)
43
+ rails-dom-testing (~> 2.2)
44
+ rails-html-sanitizer (~> 1.6)
45
+ actiontext (7.1.2)
46
+ actionpack (= 7.1.2)
47
+ activerecord (= 7.1.2)
48
+ activestorage (= 7.1.2)
49
+ activesupport (= 7.1.2)
50
+ globalid (>= 0.6.0)
51
+ nokogiri (>= 1.8.5)
52
+ actionview (7.1.2)
53
+ activesupport (= 7.1.2)
54
+ builder (~> 3.1)
55
+ erubi (~> 1.11)
56
+ rails-dom-testing (~> 2.2)
57
+ rails-html-sanitizer (~> 1.6)
58
+ activejob (7.1.2)
59
+ activesupport (= 7.1.2)
60
+ globalid (>= 0.3.6)
61
+ activemodel (7.1.2)
62
+ activesupport (= 7.1.2)
63
+ activerecord (7.1.2)
64
+ activemodel (= 7.1.2)
65
+ activesupport (= 7.1.2)
66
+ timeout (>= 0.4.0)
67
+ activestorage (7.1.2)
68
+ actionpack (= 7.1.2)
69
+ activejob (= 7.1.2)
70
+ activerecord (= 7.1.2)
71
+ activesupport (= 7.1.2)
72
+ marcel (~> 1.0)
10
73
  activesupport (7.1.2)
11
74
  base64
12
75
  bigdecimal
@@ -25,30 +88,119 @@ GEM
25
88
  base64 (0.2.0)
26
89
  benchmark-ips (2.13.0)
27
90
  bigdecimal (3.1.5)
91
+ builder (3.2.4)
92
+ combustion (1.3.7)
93
+ activesupport (>= 3.0.0)
94
+ railties (>= 3.0.0)
95
+ thor (>= 0.14.6)
28
96
  concurrent-ruby (1.2.2)
29
97
  connection_pool (2.4.1)
98
+ crass (1.0.6)
99
+ date (3.3.4)
30
100
  docile (1.4.0)
31
101
  drb (2.2.0)
32
102
  ruby2_keywords
103
+ erubi (1.12.0)
104
+ globalid (1.2.1)
105
+ activesupport (>= 6.1)
33
106
  i18n (1.14.1)
34
107
  concurrent-ruby (~> 1.0)
108
+ io-console (0.7.1)
109
+ irb (1.11.1)
110
+ rdoc
111
+ reline (>= 0.4.2)
35
112
  json (2.7.1)
36
113
  language_server-protocol (3.17.0.3)
37
114
  lint_roller (1.1.0)
38
- minitest (5.20.0)
115
+ loofah (2.22.0)
116
+ crass (~> 1.0.2)
117
+ nokogiri (>= 1.12.0)
118
+ mail (2.8.1)
119
+ mini_mime (>= 0.1.1)
120
+ net-imap
121
+ net-pop
122
+ net-smtp
123
+ marcel (1.0.2)
124
+ mini_mime (1.1.5)
125
+ minitest (5.21.1)
39
126
  mutex_m (0.2.0)
127
+ net-imap (0.4.9.1)
128
+ date
129
+ net-protocol
130
+ net-pop (0.1.2)
131
+ net-protocol
132
+ net-protocol (0.2.2)
133
+ timeout
134
+ net-smtp (0.4.0.1)
135
+ net-protocol
136
+ nio4r (2.7.0)
137
+ nokogiri (1.16.0-aarch64-linux)
138
+ racc (~> 1.4)
139
+ nokogiri (1.16.0-arm-linux)
140
+ racc (~> 1.4)
141
+ nokogiri (1.16.0-arm64-darwin)
142
+ racc (~> 1.4)
143
+ nokogiri (1.16.0-x86-linux)
144
+ racc (~> 1.4)
145
+ nokogiri (1.16.0-x86_64-darwin)
146
+ racc (~> 1.4)
147
+ nokogiri (1.16.0-x86_64-linux)
148
+ racc (~> 1.4)
40
149
  observr (1.0.5)
41
- parallel (1.23.0)
42
- parser (3.2.2.4)
150
+ parallel (1.24.0)
151
+ parser (3.3.0.3)
43
152
  ast (~> 2.4.1)
44
153
  racc
154
+ psych (5.1.2)
155
+ stringio
45
156
  racc (1.7.3)
157
+ rack (3.0.8)
158
+ rack-session (2.0.0)
159
+ rack (>= 3.0.0)
160
+ rack-test (2.1.0)
161
+ rack (>= 1.3)
162
+ rackup (2.1.0)
163
+ rack (>= 3)
164
+ webrick (~> 1.8)
165
+ rails (7.1.2)
166
+ actioncable (= 7.1.2)
167
+ actionmailbox (= 7.1.2)
168
+ actionmailer (= 7.1.2)
169
+ actionpack (= 7.1.2)
170
+ actiontext (= 7.1.2)
171
+ actionview (= 7.1.2)
172
+ activejob (= 7.1.2)
173
+ activemodel (= 7.1.2)
174
+ activerecord (= 7.1.2)
175
+ activestorage (= 7.1.2)
176
+ activesupport (= 7.1.2)
177
+ bundler (>= 1.15.0)
178
+ railties (= 7.1.2)
179
+ rails-dom-testing (2.2.0)
180
+ activesupport (>= 5.0.0)
181
+ minitest
182
+ nokogiri (>= 1.6)
183
+ rails-html-sanitizer (1.6.0)
184
+ loofah (~> 2.21)
185
+ nokogiri (~> 1.14)
186
+ railties (7.1.2)
187
+ actionpack (= 7.1.2)
188
+ activesupport (= 7.1.2)
189
+ irb
190
+ rackup (>= 1.0.0)
191
+ rake (>= 12.2)
192
+ thor (~> 1.0, >= 1.2.2)
193
+ zeitwerk (~> 2.6)
46
194
  rainbow (3.1.1)
47
195
  rake (13.1.0)
48
- regexp_parser (2.8.3)
196
+ rdoc (6.6.2)
197
+ psych (>= 4.0.0)
198
+ regexp_parser (2.9.0)
199
+ reline (0.4.2)
200
+ io-console (~> 0.5)
49
201
  rexml (3.2.6)
50
202
  ricecream (0.2.1)
51
- rubocop (1.57.2)
203
+ rubocop (1.59.0)
52
204
  json (~> 2.3)
53
205
  language_server-protocol (>= 3.17.0)
54
206
  parallel (~> 1.10)
@@ -56,14 +208,14 @@ GEM
56
208
  rainbow (>= 2.2.2, < 4.0)
57
209
  regexp_parser (>= 1.8, < 3.0)
58
210
  rexml (>= 3.2.5, < 4.0)
59
- rubocop-ast (>= 1.28.1, < 2.0)
211
+ rubocop-ast (>= 1.30.0, < 2.0)
60
212
  ruby-progressbar (~> 1.7)
61
213
  unicode-display_width (>= 2.4.0, < 3.0)
62
214
  rubocop-ast (1.30.0)
63
215
  parser (>= 3.2.1.0)
64
- rubocop-performance (1.19.1)
65
- rubocop (>= 1.7.0, < 2.0)
66
- rubocop-ast (>= 0.4.0)
216
+ rubocop-performance (1.20.2)
217
+ rubocop (>= 1.48.1, < 2.0)
218
+ rubocop-ast (>= 1.30.0, < 2.0)
67
219
  ruby-progressbar (1.13.0)
68
220
  ruby2_keywords (0.0.5)
69
221
  simplecov (0.22.0)
@@ -72,36 +224,56 @@ GEM
72
224
  simplecov_json_formatter (~> 0.1)
73
225
  simplecov-html (0.12.3)
74
226
  simplecov_json_formatter (0.1.4)
75
- standard (1.32.1)
227
+ sqlite3 (1.7.0-aarch64-linux)
228
+ sqlite3 (1.7.0-arm-linux)
229
+ sqlite3 (1.7.0-arm64-darwin)
230
+ sqlite3 (1.7.0-x86-linux)
231
+ sqlite3 (1.7.0-x86_64-darwin)
232
+ sqlite3 (1.7.0-x86_64-linux)
233
+ standard (1.33.0)
76
234
  language_server-protocol (~> 3.17.0.2)
77
235
  lint_roller (~> 1.0)
78
- rubocop (~> 1.57.2)
236
+ rubocop (~> 1.59.0)
79
237
  standard-custom (~> 1.0.0)
80
- standard-performance (~> 1.2)
238
+ standard-performance (~> 1.3)
81
239
  standard-custom (1.0.2)
82
240
  lint_roller (~> 1.0)
83
241
  rubocop (~> 1.50)
84
- standard-performance (1.2.1)
242
+ standard-performance (1.3.1)
85
243
  lint_roller (~> 1.1)
86
- rubocop-performance (~> 1.19.1)
244
+ rubocop-performance (~> 1.20.2)
245
+ stringio (3.1.0)
87
246
  thor (1.3.0)
247
+ timeout (0.4.1)
88
248
  tzinfo (2.0.6)
89
249
  concurrent-ruby (~> 1.0)
90
250
  unicode-display_width (2.5.0)
251
+ webrick (1.8.1)
252
+ websocket-driver (0.7.6)
253
+ websocket-extensions (>= 0.1.0)
254
+ websocket-extensions (0.1.5)
255
+ zeitwerk (2.6.12)
91
256
 
92
257
  PLATFORMS
258
+ aarch64-linux
259
+ arm-linux
260
+ arm64-darwin
261
+ x86-linux
262
+ x86_64-darwin
93
263
  x86_64-linux
94
264
 
95
265
  DEPENDENCIES
96
266
  appraisal
97
267
  benchmark-ips
268
+ combustion
98
269
  miau!
99
270
  minitest
100
271
  observr
101
- rake
272
+ rails
102
273
  ricecream
103
274
  simplecov
275
+ sqlite3
104
276
  standard
105
277
 
106
278
  BUNDLED WITH
107
- 2.4.22
279
+ 2.5.3
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2021-2023 Dittmar Krall (www.matiq.com)
3
+ Copyright (c) 2021-2024 Dittmar Krall (www.matiq.com)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- Miau
2
- ====
1
+ # Miau
2
+
3
3
  [![Gem Version](https://badge.fury.io/rb/miau.png)](http://badge.fury.io/rb/miau)
4
4
  [![GEM Downloads](https://img.shields.io/gem/dt/miau?color=168AFE&logo=ruby&logoColor=FE1616)](https://rubygems.org/gems/miau)
5
5
 
@@ -44,13 +44,12 @@ end
44
44
  ```ruby
45
45
  # app/policies/application_policy.rb # app/policies/posts_policy.rb
46
46
  class ApplicationPolicy class PostsPolicy < ApplicationPolicy
47
- attr_reader :user, :resource ...
47
+ attr_reader :user, :resource, :action ...
48
48
  def update
49
- def initalize(user, resource) user.admin? && resource.published?
50
- @user = user end
51
- @resource = resource ...
52
- end end
53
- end
49
+ ... user.admin? && resource.published?
50
+ end end
51
+ ...
52
+ end
54
53
  ```
55
54
 
56
55
  "authorize!" will raise an exception (which can be handled by "rescue")
@@ -60,14 +59,15 @@ in case a policy returns "false" or isn't available.
60
59
 
61
60
  "app/policies/application_policy.rb" is included in the gem.
62
61
 
63
- Internals
64
- ---------
62
+ ## Internals
65
63
 
66
64
  At the bottom line based on a "policy" and an "action"
67
65
  a corresponding policy method is called.
68
66
 
69
67
  The policy method has access to the "user" and the "resource".
70
68
 
69
+ The "controller" policy method has access to the "user" and the "action".
70
+
71
71
  "user" is set by the default method "miau_user" (can be overwritten) as:
72
72
 
73
73
  ```ruby
@@ -93,8 +93,7 @@ A full blown sample :
93
93
  authorize! article, policy: :posts, action: :show
94
94
  ```
95
95
 
96
- Usage (more elaborated)
97
- -----------------------
96
+ ## Usage (more elaborated)
98
97
 
99
98
  ```ruby
100
99
  # app/models/application_controller.rb
@@ -127,8 +126,27 @@ Rescue's may be inserted previously in the exception chain.
127
126
 
128
127
  "verify_authorized" checks that an "authorize!" has been called.
129
128
 
130
- DRYing
131
- ------
129
+ ## Authorize Controller
130
+
131
+ Sometimes a whole controller can be authorized,
132
+ e.g. all actions requires admin priviledges.
133
+
134
+ The corresponding authorization is triggered by
135
+ a "before_action :authorize_controller!".
136
+ The corresponding policy is
137
+ defined by (e.g):
138
+
139
+ ```ruby
140
+ class PostsPolicy < ApplicationPolicy
141
+ ...
142
+ def controller
143
+ user.is_admin?
144
+ end
145
+ ...
146
+ end
147
+ ```
148
+
149
+ ## DRYing
132
150
 
133
151
  ```ruby
134
152
  # app/policies/posts_policy.rb --> # app/policies/posts_policy.rb
@@ -148,8 +166,8 @@ DRYing
148
166
  end
149
167
  ```
150
168
 
151
- PORO
152
- ----
169
+ ## PORO
170
+
153
171
  Miau is a small gem, it just provides a few helpers.
154
172
  All of the policy classes are just plain Ruby classes,
155
173
  allowing DRY, encapsulation, aliasing and inheritance.
@@ -159,5 +177,5 @@ Just the embedding in Rails required some specific knowledge.
159
177
 
160
178
  ## Miscellaneous
161
179
 
162
- Copyright (c) 2021-2023 Dittmar Krall (www.matiq.com),
180
+ Copyright (c) 2021-2024 Dittmar Krall (www.matiq.com),
163
181
  released under the [MIT license](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,12 +1,10 @@
1
- require "rubygems"
2
- require "bundler/gem_tasks"
3
1
  require "rake/testtask"
4
2
 
5
- desc "Run all tests"
3
+ desc "Run the tests."
6
4
  Rake::TestTask.new do |t|
7
- t.libs.push "test"
8
- t.pattern = "test/*_test.rb"
5
+ t.libs << "test"
6
+ t.pattern = "test/**/*_test.rb"
7
+ t.verbose = false
9
8
  end
10
9
 
11
- desc "Default: run unit tests."
12
10
  task default: :test
@@ -6,10 +6,11 @@ gem "rails", "~> 6.1"
6
6
  gem "dryer-config", "~> 6.0"
7
7
 
8
8
  group :test do
9
+ gem "benchmark-ips"
9
10
  gem "observr"
10
- gem "standard", require: false
11
+ gem "ricecream"
11
12
  gem "simplecov", require: false
12
- gem "benchmark-ips"
13
+ gem "standard", require: false
13
14
  end
14
15
 
15
16
  gemspec path: "../"
@@ -6,10 +6,11 @@ gem "rails", "~> 7.0"
6
6
  gem "dryer-config", "~> 7.0"
7
7
 
8
8
  group :test do
9
+ gem "benchmark-ips"
9
10
  gem "observr"
10
- gem "standard", require: false
11
+ gem "ricecream"
11
12
  gem "simplecov", require: false
12
- gem "benchmark-ips"
13
+ gem "standard", require: false
13
14
  end
14
15
 
15
16
  gemspec path: "../"
@@ -5,10 +5,11 @@ source "https://rubygems.org"
5
5
  gem "rails", "~> 7.1"
6
6
 
7
7
  group :test do
8
+ gem "benchmark-ips"
8
9
  gem "observr"
9
- gem "standard", require: false
10
+ gem "ricecream"
10
11
  gem "simplecov", require: false
11
- gem "benchmark-ips"
12
+ gem "standard", require: false
12
13
  end
13
14
 
14
15
  gemspec path: "../"
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ApplicationPolicy
4
- attr_accessor :user, :resource
4
+ attr_accessor :user, :resource, :action
5
5
 
6
6
  def self.miau(actions, meth = nil, &block)
7
+ kls = name.underscore[0..-8] # remove "_policy"
7
8
  [actions].flatten.each { |action|
8
- Miau::PolicyStorage.instance.add(self, action, meth)
9
+ Miau::PolicyStorage.instance.add_policy(kls, action, meth)
9
10
  }
10
11
  end
11
12
  end
data/lib/miau/error.rb CHANGED
@@ -11,4 +11,7 @@ module Miau
11
11
 
12
12
  class AuthorizationNotPerformedError < Error
13
13
  end
14
+
15
+ class OverwriteError < Error
16
+ end
14
17
  end
data/lib/miau/run.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+ require "yaml"
5
+
6
+ module Miau
7
+ class PolicyRun
8
+ include Singleton
9
+
10
+ # return method[s]
11
+ # klass and action are symbols
12
+ # Priority:
13
+ # - method of <klass>Policy
14
+ # - method of <klass>Policy specified by "miau action, method"
15
+ # - method of ApplicationPolicy (independent of klass)
16
+ # - method of ApplicationPolicy specified by "miau action, method"
17
+ # - nil
18
+ # returns method_name[s]
19
+
20
+ def find_methods(policy, klass, action)
21
+ return action if policy.respond_to?(action)
22
+
23
+ hsh = PolicyStorage.instance.policies[klass]
24
+ return nil unless hsh
25
+
26
+ hsh[action]
27
+ end
28
+
29
+ def runs(policy, actions)
30
+ [actions].flatten.each { |action|
31
+ raise_undef(policy, action) unless policy&.respond_to?(action)
32
+
33
+ return false unless policy.send(action)
34
+ }
35
+ true
36
+ end
37
+
38
+ def raise_undef(policy, action)
39
+ msg = "NotDefined policy <#{policy}> action <#{action}>"
40
+ raise NotDefinedError, msg
41
+ end
42
+
43
+ def raise_authorize(controller, action)
44
+ msg = "NotAuthorized controller <#{controller}> action <#{action}>"
45
+ raise NotAuthorizedError, msg
46
+ end
47
+ end
48
+ end
data/lib/miau/storage.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "singleton"
4
+ require "yaml"
4
5
 
5
6
  module Miau
6
7
  class PolicyStorage
@@ -17,7 +18,7 @@ module Miau
17
18
  # }
18
19
  # }
19
20
  attr_reader :policies
20
- attr_reader :instances # { posts: PostsPolicy.new }
21
+ attr_reader :instances # e.g. { posts: PostsPolicy.new }
21
22
 
22
23
  def initialize
23
24
  reset
@@ -28,70 +29,35 @@ module Miau
28
29
  @instances = {}
29
30
  end
30
31
 
31
- def add(klass, action, meth)
32
- kls = klass.name.underscore[0..-8] # remove "_policy"
32
+ def add_policy(kls, action, meth)
33
33
  kls = kls.to_sym
34
+ action = action.to_sym
34
35
  @policies[kls] ||= {}
35
- @instances[kls] ||= klass.new
36
- @policies[kls][action.to_sym] = meth.to_sym
37
- end
38
-
39
- # return instance of policy (may be nil) and the method
40
- # klass and action are symbols
41
- # Priority:
42
- # - method of <klass>Policy
43
- # - method of <klass>Policy specified by "miau action, method"
44
- # - method of ApplicationPolicy (independent of klass)
45
- # - method of ApplicationPolicy specified by "miau action, method"
46
- # - nil
47
-
48
- # returns policy: [instance, method]
49
- def find_policy(klass, action)
50
- kls = instance_of(klass)
51
- act = policy_method(klass, action)
52
- return [kls, act] if kls.respond_to?(act)
53
-
54
- klass = :application
55
- kls = instance_of(klass)
56
- act = policy_method(klass, action)
57
- [kls, act] if kls.respond_to?(act)
58
- end
59
-
60
- def run(klass, action, user, resource)
61
- arr = find_policy(klass, action)
62
- unless arr
63
- msg = "class <#{klass}> action <#{action}>"
64
- raise Miau::NotDefinedError, msg
36
+ if @policies[kls][action]
37
+ raise OverwriteError, "Can't overwrite policy(#{kls}, #{action})"
65
38
  end
66
39
 
67
- policy, meth = arr
68
- policy.user = user
69
- policy.resource = resource
70
- policy.send(meth)
71
- end
72
-
73
- def to_yaml
74
- "# === @policies ===\n" + YAML.dump(@policies) +
75
- "# === @instances ===\n" + YAML.dump(@instances)
40
+ if meth.is_a?(Array)
41
+ meths = [meth].flatten.collect(&:to_sym)
42
+ @policies[kls][action] = meths
43
+ else
44
+ @policies[kls][action] = meth.to_sym
45
+ end
76
46
  end
77
47
 
78
- private
79
-
80
- def instance_of(klass)
48
+ def find_or_create_policy(klass)
81
49
  res = @instances[klass]
82
- return res if res
50
+ return res unless res.nil?
83
51
 
84
52
  name = "#{klass.to_s.camelcase}Policy"
85
53
  return nil unless Object.const_defined?(name)
86
54
 
87
- @instances[klass] = name.constantize.new
55
+ instances[klass] = name.constantize.new
88
56
  end
89
57
 
90
- def policy_method(klass, action)
91
- act = @policies[klass]
92
- return action unless act
93
-
94
- act[action] || action
58
+ def to_yaml
59
+ "# === @policies ===\n" + YAML.dump(@policies) +
60
+ "# === @instances ===\n" + YAML.dump(@instances)
95
61
  end
96
62
  end
97
63
  end