avo 2.17.0 → 2.17.1.pre.2.customauthorizationclients
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +29 -3
- data/app/controllers/avo/application_controller.rb +9 -17
- data/app/controllers/avo/associations_controller.rb +11 -0
- data/config/i18n-tasks.yml +159 -0
- data/config/master.key +1 -0
- data/lib/avo/configuration.rb +2 -0
- data/lib/avo/services/authorization_clients/pundit_client.rb +51 -0
- data/lib/avo/services/authorization_service.rb +46 -51
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +4 -0
- data/lib/generators/avo/templates/initializer/avo.tt +1 -0
- data/lib/generators/avo/templates/locales/avo.en.yml +107 -106
- data/lib/generators/avo/templates/locales/avo.fr.yml +107 -107
- data/lib/generators/avo/templates/locales/avo.nb.yml +111 -110
- data/lib/generators/avo/templates/locales/avo.nn.yml +111 -110
- data/lib/generators/avo/templates/locales/avo.pt-BR.yml +109 -84
- data/lib/generators/avo/templates/locales/avo.ro.yml +109 -81
- data/lib/generators/avo/templates/locales/avo.tr.yml +107 -107
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e76409a6dd8d5c3a89a467e4cbed5e46f0c292988fd60efa5a1c673be10e36a
|
4
|
+
data.tar.gz: '09bde2e9be219d3f9af5fb3256ee9ed60c77d86d587e8f9131c8d3e95d03ef29'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82ceba1946394ea1bea5cf4ef8283d75ddb40fdcfcfdd55ee19cad8aff34ed873698442dd846711134e6d961e288ca723cf8f9fab0aab122c0a49319e432ff05
|
7
|
+
data.tar.gz: 3829a9ec1348318c537aee5954463c41864ee710790a8a333c2f075102d205ec90e50e70f766051aa2e892c2d0d8609b0bedc299a502d557a0806e9c34107269
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (2.17.
|
4
|
+
avo (2.17.1.pre.2.customauthorizationclients)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
@@ -119,6 +119,13 @@ GEM
|
|
119
119
|
aws-sigv4 (1.5.1)
|
120
120
|
aws-eventstream (~> 1, >= 1.0.2)
|
121
121
|
bcrypt (3.1.18)
|
122
|
+
better_html (2.0.1)
|
123
|
+
actionview (>= 6.0)
|
124
|
+
activesupport (>= 6.0)
|
125
|
+
ast (~> 2.0)
|
126
|
+
erubi (~> 1.4)
|
127
|
+
parser (>= 2.4)
|
128
|
+
smart_properties
|
122
129
|
bindex (0.8.1)
|
123
130
|
bootsnap (1.13.0)
|
124
131
|
msgpack (~> 1.2)
|
@@ -189,6 +196,7 @@ GEM
|
|
189
196
|
groupdate (6.1.0)
|
190
197
|
activesupport (>= 5.2)
|
191
198
|
hashdiff (1.0.1)
|
199
|
+
highline (2.0.3)
|
192
200
|
hightop (0.3.0)
|
193
201
|
activesupport (>= 5.2)
|
194
202
|
hotwire-livereload (1.2.2)
|
@@ -200,6 +208,17 @@ GEM
|
|
200
208
|
multi_xml (>= 0.5.2)
|
201
209
|
i18n (1.12.0)
|
202
210
|
concurrent-ruby (~> 1.0)
|
211
|
+
i18n-tasks (1.0.12)
|
212
|
+
activesupport (>= 4.0.2)
|
213
|
+
ast (>= 2.1.0)
|
214
|
+
better_html (>= 1.0, < 3.0)
|
215
|
+
erubi
|
216
|
+
highline (>= 2.0.0)
|
217
|
+
i18n
|
218
|
+
parser (>= 2.2.3.0)
|
219
|
+
rails-i18n
|
220
|
+
rainbow (>= 2.2.2, < 4.0)
|
221
|
+
terminal-table (>= 1.5.1)
|
203
222
|
image_processing (1.12.2)
|
204
223
|
mini_magick (>= 4.9.5, < 5)
|
205
224
|
ruby-vips (>= 2.0.17, < 3)
|
@@ -289,6 +308,9 @@ GEM
|
|
289
308
|
nokogiri (>= 1.6)
|
290
309
|
rails-html-sanitizer (1.4.3)
|
291
310
|
loofah (~> 2.3)
|
311
|
+
rails-i18n (7.0.5)
|
312
|
+
i18n (>= 0.7, < 2)
|
313
|
+
railties (>= 6.0.0, < 8)
|
292
314
|
railties (6.1.6.1)
|
293
315
|
actionpack (= 6.1.6.1)
|
294
316
|
activesupport (= 6.1.6.1)
|
@@ -350,7 +372,7 @@ GEM
|
|
350
372
|
ruby-vips (2.1.4)
|
351
373
|
ffi (~> 1.12)
|
352
374
|
rubyzip (2.3.2)
|
353
|
-
selenium-webdriver (4.
|
375
|
+
selenium-webdriver (4.5.0)
|
354
376
|
childprocess (>= 0.5, < 5.0)
|
355
377
|
rexml (~> 3.2, >= 3.2.5)
|
356
378
|
rubyzip (>= 1.2.2, < 3.0)
|
@@ -365,6 +387,7 @@ GEM
|
|
365
387
|
simplecov-html (0.12.3)
|
366
388
|
simplecov_json_formatter (0.1.4)
|
367
389
|
sixarm_ruby_unaccent (1.2.0)
|
390
|
+
smart_properties (1.17.0)
|
368
391
|
spring (4.0.0)
|
369
392
|
spring-commands-rspec (1.0.4)
|
370
393
|
spring (>= 0.9.1)
|
@@ -378,6 +401,8 @@ GEM
|
|
378
401
|
standard (1.16.0)
|
379
402
|
rubocop (= 1.35.0)
|
380
403
|
rubocop-performance (= 1.14.3)
|
404
|
+
terminal-table (3.0.2)
|
405
|
+
unicode-display_width (>= 1.1.1, < 3)
|
381
406
|
test-prof (1.0.10)
|
382
407
|
thor (1.2.1)
|
383
408
|
timeout (0.3.0)
|
@@ -398,7 +423,7 @@ GEM
|
|
398
423
|
activemodel (>= 6.0.0)
|
399
424
|
bindex (>= 0.4.0)
|
400
425
|
railties (>= 6.0.0)
|
401
|
-
webdrivers (5.
|
426
|
+
webdrivers (5.2.0)
|
402
427
|
nokogiri (~> 1.6)
|
403
428
|
rubyzip (>= 1.3.0)
|
404
429
|
selenium-webdriver (~> 4.0)
|
@@ -452,6 +477,7 @@ DEPENDENCIES
|
|
452
477
|
hotwire-livereload (~> 1.1)
|
453
478
|
htmlbeautifier
|
454
479
|
httparty
|
480
|
+
i18n-tasks (~> 1.0.12)
|
455
481
|
image_processing (~> 1.12)
|
456
482
|
iso
|
457
483
|
jsbundling-rails
|
@@ -1,11 +1,5 @@
|
|
1
1
|
module Avo
|
2
2
|
class ApplicationController < ::ActionController::Base
|
3
|
-
if defined?(Pundit::Authorization)
|
4
|
-
include Pundit::Authorization
|
5
|
-
else
|
6
|
-
include Pundit
|
7
|
-
end
|
8
|
-
|
9
3
|
include Pagy::Backend
|
10
4
|
include Avo::ApplicationHelper
|
11
5
|
include Avo::UrlHelpers
|
@@ -24,7 +18,7 @@ module Avo
|
|
24
18
|
before_action :set_view
|
25
19
|
before_action :set_sidebar_open
|
26
20
|
|
27
|
-
rescue_from
|
21
|
+
rescue_from Avo::NotAuthorizedError, with: :render_unauthorized
|
28
22
|
rescue_from ActiveRecord::RecordInvalid, with: :exception_logger
|
29
23
|
|
30
24
|
helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path
|
@@ -257,18 +251,16 @@ module Avo
|
|
257
251
|
instance_eval(&Avo.configuration.authenticate)
|
258
252
|
end
|
259
253
|
|
260
|
-
def render_unauthorized(
|
261
|
-
|
262
|
-
flash.now[:notice] = t "avo.not_authorized"
|
263
|
-
|
264
|
-
redirect_url = if request.referrer.blank? || (request.referrer == request.url)
|
265
|
-
root_url
|
266
|
-
else
|
267
|
-
request.referrer
|
268
|
-
end
|
254
|
+
def render_unauthorized(_exception)
|
255
|
+
flash.now[:notice] = t "avo.not_authorized"
|
269
256
|
|
270
|
-
|
257
|
+
redirect_url = if request.referrer.blank? || (request.referrer == request.url)
|
258
|
+
root_url
|
259
|
+
else
|
260
|
+
request.referrer
|
271
261
|
end
|
262
|
+
|
263
|
+
redirect_to(redirect_url)
|
272
264
|
end
|
273
265
|
|
274
266
|
def set_authorization
|
@@ -5,6 +5,7 @@ module Avo
|
|
5
5
|
before_action :set_model, only: [:show, :index, :new, :create, :destroy, :order]
|
6
6
|
before_action :set_related_resource_name
|
7
7
|
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy, :order]
|
8
|
+
before_action :set_related_authorization
|
8
9
|
before_action :set_reflection_field
|
9
10
|
before_action :hydrate_related_resource, only: [:show, :index, :create, :destroy, :order]
|
10
11
|
before_action :set_related_model, only: [:show, :order]
|
@@ -152,5 +153,15 @@ module Avo
|
|
152
153
|
def authorize_detach_action
|
153
154
|
authorize_if_defined "detach_#{@field.id}?"
|
154
155
|
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def set_related_authorization
|
160
|
+
@related_authorization = if related_resource
|
161
|
+
related_resource.authorization(user: _current_user)
|
162
|
+
else
|
163
|
+
Services::AuthorizationService.new _current_user
|
164
|
+
end
|
165
|
+
end
|
155
166
|
end
|
156
167
|
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks
|
2
|
+
|
3
|
+
# The "main" locale.
|
4
|
+
base_locale: en
|
5
|
+
## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
|
6
|
+
locales: [en, fr, nb, nn, pt-BR, ro, tr]
|
7
|
+
## Reporting locale, default: en. Available: en, ru.
|
8
|
+
# internal_locale: en
|
9
|
+
|
10
|
+
# Read and write translations.
|
11
|
+
data:
|
12
|
+
## Translations are read from the file system. Supported format: YAML, JSON.
|
13
|
+
## Provide a custom adapter:
|
14
|
+
# adapter: I18n::Tasks::Data::FileSystem
|
15
|
+
|
16
|
+
# Locale files or `File.find` patterns where translations are read from:
|
17
|
+
read:
|
18
|
+
## Default:
|
19
|
+
# - config/locales/%{locale}.yml
|
20
|
+
## More files:
|
21
|
+
- lib/generators/avo/templates/locales/**/*.%{locale}.yml
|
22
|
+
|
23
|
+
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
|
24
|
+
# `i18n-tasks normalize -p` will force move the keys according to these rules
|
25
|
+
write:
|
26
|
+
## For example, write devise and simple form keys to their respective files:
|
27
|
+
# - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
|
28
|
+
## Catch-all default:
|
29
|
+
# - config/locales/%{locale}.yml
|
30
|
+
|
31
|
+
# External locale data (e.g. gems).
|
32
|
+
# This data is not considered unused and is never written to.
|
33
|
+
external:
|
34
|
+
## Example (replace %#= with %=):
|
35
|
+
# - "<%#= %x[bundle info vagrant --path].chomp %>/templates/locales/%{locale}.yml"
|
36
|
+
|
37
|
+
## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
|
38
|
+
# router: conservative_router
|
39
|
+
|
40
|
+
yaml:
|
41
|
+
write:
|
42
|
+
# do not wrap lines at 80 characters
|
43
|
+
line_width: -1
|
44
|
+
|
45
|
+
## Pretty-print JSON:
|
46
|
+
# json:
|
47
|
+
# write:
|
48
|
+
# indent: ' '
|
49
|
+
# space: ' '
|
50
|
+
# object_nl: "\n"
|
51
|
+
# array_nl: "\n"
|
52
|
+
|
53
|
+
# Find translate calls
|
54
|
+
search:
|
55
|
+
## Paths or `File.find` patterns to search in:
|
56
|
+
# paths:
|
57
|
+
# - app/
|
58
|
+
|
59
|
+
## Root directories for relative keys resolution.
|
60
|
+
# relative_roots:
|
61
|
+
# - app/controllers
|
62
|
+
# - app/helpers
|
63
|
+
# - app/mailers
|
64
|
+
# - app/presenters
|
65
|
+
# - app/views
|
66
|
+
|
67
|
+
## Directories where method names which should not be part of a relative key resolution.
|
68
|
+
# By default, if a relative translation is used inside a method, the name of the method will be considered part of the resolved key.
|
69
|
+
# Directories listed here will not consider the name of the method part of the resolved key
|
70
|
+
#
|
71
|
+
# relative_exclude_method_name_paths:
|
72
|
+
# -
|
73
|
+
|
74
|
+
## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
|
75
|
+
## *.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less
|
76
|
+
## *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus *.webp *.map *.xlsx
|
77
|
+
exclude:
|
78
|
+
- app/assets/images
|
79
|
+
- app/assets/fonts
|
80
|
+
- app/assets/videos
|
81
|
+
- app/assets/builds
|
82
|
+
|
83
|
+
## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
|
84
|
+
## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
|
85
|
+
# only: ["*.rb", "*.html.slim"]
|
86
|
+
|
87
|
+
## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
|
88
|
+
# strict: true
|
89
|
+
|
90
|
+
## Allows adding ast_matchers for finding translations using the AST-scanners
|
91
|
+
## The available matchers are:
|
92
|
+
## - RailsModelMatcher
|
93
|
+
## Matches ActiveRecord translations like
|
94
|
+
## User.human_attribute_name(:email) and User.model_name.human
|
95
|
+
##
|
96
|
+
## To implement your own, please see `I18n::Tasks::Scanners::AstMatchers::BaseMatcher`.
|
97
|
+
<%# I18n::Tasks.add_ast_matcher('I18n::Tasks::Scanners::AstMatchers::RailsModelMatcher') %>
|
98
|
+
|
99
|
+
## Multiple scanners can be used. Their results are merged.
|
100
|
+
## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
|
101
|
+
## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
|
102
|
+
|
103
|
+
## Translation Services
|
104
|
+
# translation:
|
105
|
+
# # Google Translate
|
106
|
+
# # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
|
107
|
+
# google_translate_api_key: "AbC-dEf5"
|
108
|
+
# # DeepL Pro Translate
|
109
|
+
# # Get an API key and subscription at https://www.deepl.com/pro to use DeepL Pro
|
110
|
+
# deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A"
|
111
|
+
# # deepl_host: "https://api.deepl.com"
|
112
|
+
# # deepl_version: "v2"
|
113
|
+
|
114
|
+
## Do not consider these keys missing:
|
115
|
+
ignore_missing:
|
116
|
+
- 'avo.field_translations.file'
|
117
|
+
- 'avo.field_translations.people'
|
118
|
+
- 'avo.number_of_items'
|
119
|
+
- 'avo.resource_translations.user'
|
120
|
+
- 'avo.x_items_more'
|
121
|
+
|
122
|
+
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
|
123
|
+
# - '{devise,simple_form}.*'
|
124
|
+
|
125
|
+
## Consider these keys used:
|
126
|
+
# ignore_unused:
|
127
|
+
# - 'activerecord.attributes.*'
|
128
|
+
# - '{devise,kaminari,will_paginate}.*'
|
129
|
+
# - 'simple_form.{yes,no}'
|
130
|
+
# - 'simple_form.{placeholders,hints,labels}.*'
|
131
|
+
# - 'simple_form.{error_notification,required}.:'
|
132
|
+
|
133
|
+
## Exclude these keys from the `i18n-tasks eq-base' report:
|
134
|
+
# ignore_eq_base:
|
135
|
+
# all:
|
136
|
+
# - common.ok
|
137
|
+
# fr,es:
|
138
|
+
# - common.brand
|
139
|
+
|
140
|
+
## Exclude these keys from the `i18n-tasks check-consistent-interpolations` report:
|
141
|
+
# ignore_inconsistent_interpolations:
|
142
|
+
# - 'activerecord.attributes.*'
|
143
|
+
|
144
|
+
## Ignore these keys completely:
|
145
|
+
# ignore:
|
146
|
+
# - kaminari.*
|
147
|
+
|
148
|
+
## Sometimes, it isn't possible for i18n-tasks to match the key correctly,
|
149
|
+
## e.g. in case of a relative key defined in a helper method.
|
150
|
+
## In these cases you can use the built-in PatternMapper to map patterns to keys, e.g.:
|
151
|
+
#
|
152
|
+
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
|
153
|
+
# only: %w(*.html.haml *.html.slim),
|
154
|
+
# patterns: [['= title\b', '.page_title']] %>
|
155
|
+
#
|
156
|
+
# The PatternMapper can also match key literals via a special %{key} interpolation, e.g.:
|
157
|
+
#
|
158
|
+
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
|
159
|
+
# patterns: [['\bSpree\.t[( ]\s*%{key}', 'spree.%{key}']] %>
|
data/config/master.key
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2aeb23d82b909d9c6b5abb62f7058c2a
|
data/lib/avo/configuration.rb
CHANGED
@@ -37,6 +37,7 @@ module Avo
|
|
37
37
|
attr_accessor :model_resource_mapping
|
38
38
|
attr_accessor :tabs_style
|
39
39
|
attr_accessor :resource_default_view
|
40
|
+
attr_accessor :authorization_client
|
40
41
|
attr_writer :branding
|
41
42
|
|
42
43
|
def initialize
|
@@ -85,6 +86,7 @@ module Avo
|
|
85
86
|
@model_resource_mapping = {}
|
86
87
|
@tabs_style = :tabs
|
87
88
|
@resource_default_view = :show
|
89
|
+
@authorization_client = nil
|
88
90
|
end
|
89
91
|
|
90
92
|
def current_user_method(&block)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Avo
|
2
|
+
module Services
|
3
|
+
module AuthorizationClients
|
4
|
+
class PunditClient
|
5
|
+
def authorize(user, record, action, policy_class: nil)
|
6
|
+
Pundit.authorize(user, record, action, policy_class: policy_class)
|
7
|
+
rescue Pundit::NotDefinedError
|
8
|
+
raise NoPolicyError
|
9
|
+
rescue Pundit::NotAuthorizedError
|
10
|
+
raise NotAuthorizedError
|
11
|
+
end
|
12
|
+
|
13
|
+
def policy(user, record)
|
14
|
+
Pundit.policy(user, record)
|
15
|
+
end
|
16
|
+
|
17
|
+
def policy!(user, record)
|
18
|
+
Pundit.policy!(user, record)
|
19
|
+
rescue Pundit::NotDefinedError
|
20
|
+
raise NoPolicyError
|
21
|
+
end
|
22
|
+
|
23
|
+
def apply_policy(user, model, policy_class: nil)
|
24
|
+
# Try and figure out the scope from a given policy or auto-detected one
|
25
|
+
scope_from_policy_class = scope_for_policy_class(policy_class)
|
26
|
+
|
27
|
+
# If we discover one use it.
|
28
|
+
# Else fallback to pundit.
|
29
|
+
if scope_from_policy_class.present?
|
30
|
+
scope_from_policy_class.new(user, model).resolve
|
31
|
+
else
|
32
|
+
Pundit.policy_scope!(user, model)
|
33
|
+
end
|
34
|
+
rescue Pundit::NotDefinedError => error
|
35
|
+
raise NoPolicyError
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Fetches the scope for a given policy
|
41
|
+
def scope_for_policy_class(policy_class = nil)
|
42
|
+
return if policy_class.blank?
|
43
|
+
|
44
|
+
if policy_class.present? && defined?(policy_class::Scope)
|
45
|
+
policy_class::Scope
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -3,29 +3,30 @@ module Avo
|
|
3
3
|
class AuthorizationService
|
4
4
|
attr_accessor :user
|
5
5
|
attr_accessor :record
|
6
|
+
attr_accessor :policy_class
|
6
7
|
|
7
8
|
class << self
|
9
|
+
def client
|
10
|
+
(configuration_client || default_client).new
|
11
|
+
end
|
12
|
+
|
8
13
|
def authorize(user, record, action, policy_class: nil, **args)
|
9
14
|
return true if skip_authorization
|
10
15
|
return true if user.nil?
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
false
|
26
|
-
else
|
27
|
-
raise error
|
28
|
-
end
|
17
|
+
client.authorize user, record, action, policy_class: policy_class
|
18
|
+
|
19
|
+
true
|
20
|
+
rescue NoPolicyError => error
|
21
|
+
# By default, Avo allows anything if you don't have a policy present.
|
22
|
+
return true unless Avo.configuration.raise_error_on_missing_policy
|
23
|
+
|
24
|
+
raise error
|
25
|
+
rescue => error
|
26
|
+
if args[:raise_exception] == false
|
27
|
+
false
|
28
|
+
else
|
29
|
+
raise error
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -35,7 +36,7 @@ module Avo
|
|
35
36
|
# If no action passed we should raise error if the user wants that.
|
36
37
|
# If not, just allow it.
|
37
38
|
if action.nil?
|
38
|
-
raise
|
39
|
+
raise NoPolicyError.new "Policy method is missing" if Avo.configuration.raise_error_on_missing_policy
|
39
40
|
|
40
41
|
return true
|
41
42
|
end
|
@@ -48,39 +49,27 @@ module Avo
|
|
48
49
|
def apply_policy(user, model, policy_class: nil)
|
49
50
|
return model if skip_authorization || user.nil?
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
Pundit.policy_scope! user, model
|
56
|
-
end
|
57
|
-
rescue Pundit::NotDefinedError => e
|
58
|
-
return model unless Avo.configuration.raise_error_on_missing_policy
|
52
|
+
client.apply_policy(user, model, policy_class: policy_class)
|
53
|
+
rescue NoPolicyError => error
|
54
|
+
return model unless Avo.configuration.raise_error_on_missing_policy
|
59
55
|
|
60
|
-
|
61
|
-
end
|
56
|
+
raise error
|
62
57
|
end
|
63
58
|
|
64
59
|
def skip_authorization
|
65
60
|
Avo::App.license.lacks_with_trial :authorization
|
66
61
|
end
|
67
62
|
|
68
|
-
def authorized_methods(user, record)
|
69
|
-
[:new, :edit, :update, :show, :destroy].map do |method|
|
70
|
-
[method, authorize(user, record, Avo.configuration.authorization_methods[method])]
|
71
|
-
end.to_h
|
72
|
-
end
|
73
|
-
|
74
63
|
def defined_methods(user, record, policy_class: nil, **args)
|
75
|
-
return
|
64
|
+
return client.policy!(user, record).methods if policy_class.nil?
|
76
65
|
|
77
66
|
# I'm aware this will not raise a Pundit error.
|
78
67
|
# Should the policy not exist, it will however raise an uninitialized constant error, which is probably what we want when specifying a custom policy
|
79
68
|
policy_class.new(user, record).methods
|
80
|
-
rescue
|
69
|
+
rescue NoPolicyError => error
|
81
70
|
return [] unless Avo.configuration.raise_error_on_missing_policy
|
82
71
|
|
83
|
-
raise
|
72
|
+
raise error
|
84
73
|
rescue => error
|
85
74
|
if args[:raise_exception] == false
|
86
75
|
[]
|
@@ -88,16 +77,28 @@ module Avo
|
|
88
77
|
raise error
|
89
78
|
end
|
90
79
|
end
|
80
|
+
|
81
|
+
def configuration_client
|
82
|
+
client = Avo.configuration.authorization_client
|
83
|
+
|
84
|
+
return if client.blank?
|
85
|
+
|
86
|
+
if client.is_a?(String)
|
87
|
+
client.safe_constantize
|
88
|
+
else
|
89
|
+
client
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def default_client
|
94
|
+
Avo::Services::AuthorizationClients::PunditClient
|
95
|
+
end
|
91
96
|
end
|
92
97
|
|
93
98
|
def initialize(user = nil, record = nil, policy_class: nil)
|
94
99
|
@user = user
|
95
100
|
@record = record
|
96
|
-
@policy_class = policy_class ||
|
97
|
-
end
|
98
|
-
|
99
|
-
def authorize(action, **args)
|
100
|
-
self.class.authorize(user, record, action, policy_class: @policy_class, **args)
|
101
|
+
@policy_class = policy_class || self.class.client.policy(user, record)&.class
|
101
102
|
end
|
102
103
|
|
103
104
|
def set_record(record)
|
@@ -106,22 +107,16 @@ module Avo
|
|
106
107
|
self
|
107
108
|
end
|
108
109
|
|
109
|
-
def set_user(user)
|
110
|
-
@user = user
|
111
|
-
|
112
|
-
self
|
113
|
-
end
|
114
|
-
|
115
110
|
def authorize_action(action, **args)
|
116
|
-
self.class.authorize_action(user, record, action, policy_class:
|
111
|
+
self.class.authorize_action(user, record, action, policy_class: policy_class, **args)
|
117
112
|
end
|
118
113
|
|
119
114
|
def apply_policy(model)
|
120
|
-
self.class.apply_policy(user, model, policy_class:
|
115
|
+
self.class.apply_policy(user, model, policy_class: policy_class)
|
121
116
|
end
|
122
117
|
|
123
118
|
def defined_methods(model, **args)
|
124
|
-
self.class.defined_methods(user, model, policy_class:
|
119
|
+
self.class.defined_methods(user, model, policy_class: policy_class, **args)
|
125
120
|
end
|
126
121
|
|
127
122
|
def has_method?(method, **args)
|
data/lib/avo/version.rb
CHANGED
data/lib/avo.rb
CHANGED
@@ -44,6 +44,10 @@ module Avo
|
|
44
44
|
class LicenseVerificationTemperedError < StandardError; end
|
45
45
|
|
46
46
|
class LicenseInvalidError < StandardError; end
|
47
|
+
|
48
|
+
class NotAuthorizedError < StandardError; end
|
49
|
+
|
50
|
+
class NoPolicyError < StandardError; end
|
47
51
|
end
|
48
52
|
|
49
53
|
loader.eager_load
|