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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce1ecba413a03866498a9f2992647e7f1ab99a55b854a67ba86154fde854f7d1
4
- data.tar.gz: a060cca4fd407dd9d479fa5aa5bd1c6688d6c3eaab3ca23bdfc7b338341452f6
3
+ metadata.gz: 1e76409a6dd8d5c3a89a467e4cbed5e46f0c292988fd60efa5a1c673be10e36a
4
+ data.tar.gz: '09bde2e9be219d3f9af5fb3256ee9ed60c77d86d587e8f9131c8d3e95d03ef29'
5
5
  SHA512:
6
- metadata.gz: 703bc0074a7db187b5d5d75e4cb9a1db908b7eb5c2381c97f668993320b499d8a4b5fee55799576f087ecd712ccfca8896a59334a5d526167a8ba74771b5fb00
7
- data.tar.gz: d90939f46f227a5a3e14d7bf5ee77b621f4311121ea6fbad75f8db2fb6905b6254d6a3efe553083bd9d552e441bae43d1615f652532344e2fdb414d7fb776dbd
6
+ metadata.gz: 82ceba1946394ea1bea5cf4ef8283d75ddb40fdcfcfdd55ee19cad8aff34ed873698442dd846711134e6d961e288ca723cf8f9fab0aab122c0a49319e432ff05
7
+ data.tar.gz: 3829a9ec1348318c537aee5954463c41864ee710790a8a333c2f075102d205ec90e50e70f766051aa2e892c2d0d8609b0bedc299a502d557a0806e9c34107269
data/Gemfile CHANGED
@@ -90,6 +90,7 @@ end
90
90
  group :development, :test do
91
91
  gem "awesome_print"
92
92
  gem "faker", require: false
93
+ gem "i18n-tasks", "~> 1.0.12"
93
94
  end
94
95
 
95
96
  group :test do
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (2.17.0)
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.4.0)
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.0.0)
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 Pundit::NotAuthorizedError, with: :render_unauthorized
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(exception)
261
- if !exception.is_a? Pundit::NotDefinedError
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
- redirect_to(redirect_url)
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
@@ -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
- policy_class ||= Pundit.policy(user, record)&.class
13
- begin
14
- if policy_class&.new(user, record)
15
- Pundit.authorize user, record, action, policy_class: policy_class
16
- end
17
-
18
- true
19
- rescue Pundit::NotDefinedError => e
20
- return false unless Avo.configuration.raise_error_on_missing_policy
21
-
22
- raise e
23
- rescue => error
24
- if args[:raise_exception] == false
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 Pundit::NotDefinedError.new "Policy method is missing" if Avo.configuration.raise_error_on_missing_policy
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
- begin
52
- if policy_class
53
- policy_class::Scope.new(user, model).resolve
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
- raise e
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 Pundit.policy!(user, record).methods if policy_class.nil?
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 Pundit::NotDefinedError => e
69
+ rescue NoPolicyError => error
81
70
  return [] unless Avo.configuration.raise_error_on_missing_policy
82
71
 
83
- raise e
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 || Pundit.policy(user, record)&.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: @policy_class, **args)
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: @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: @policy_class, **args)
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
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.17.0" unless const_defined?(:VERSION)
2
+ VERSION = "2.17.1.pre.2.customauthorizationclients" unless const_defined?(:VERSION)
3
3
  end
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
@@ -30,6 +30,7 @@ Avo.configure do |config|
30
30
  # destroy: 'destroy?',
31
31
  # }
32
32
  # config.raise_error_on_missing_policy = false
33
+ # config.authorization_client = false
33
34
 
34
35
  ## == Localization ==
35
36
  # config.locale = 'en-US'