wallaby-core 0.2.11 → 0.3.0.beta1
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/app/controllers/wallaby/resources_controller.rb +20 -7
- data/app/security/ability.rb +1 -1
- data/config/routes.rb +21 -14
- data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_decorator.rb +5 -17
- data/lib/adaptors/wallaby/custom/model_finder.rb +3 -3
- data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -1
- data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +12 -5
- data/lib/authorizers/wallaby/default_authorization_provider.rb +10 -1
- data/lib/authorizers/wallaby/model_authorizer.rb +41 -16
- data/lib/authorizers/wallaby/pundit_authorization_provider.rb +22 -8
- data/lib/concerns/wallaby/application_concern.rb +41 -71
- data/lib/concerns/wallaby/authentication_concern.rb +29 -127
- data/lib/concerns/wallaby/authorizable.rb +14 -57
- data/lib/concerns/wallaby/baseable.rb +24 -57
- data/lib/concerns/wallaby/configurable.rb +416 -0
- data/lib/concerns/wallaby/decoratable.rb +24 -60
- data/lib/concerns/wallaby/engineable.rb +29 -46
- data/lib/concerns/wallaby/fieldable.rb +45 -56
- data/lib/concerns/wallaby/paginatable.rb +20 -51
- data/lib/concerns/wallaby/prefixable.rb +24 -4
- data/lib/concerns/wallaby/resourcable.rb +130 -72
- data/lib/concerns/wallaby/resources_concern.rb +205 -305
- data/lib/concerns/wallaby/servicable.rb +8 -48
- data/lib/concerns/wallaby/urlable.rb +69 -0
- data/lib/decorators/wallaby/resource_decorator.rb +72 -34
- data/lib/errors/wallaby/class_not_found.rb +1 -2
- data/lib/errors/wallaby/forbidden.rb +1 -2
- data/lib/errors/wallaby/general_error.rb +1 -1
- data/lib/errors/wallaby/invalid_error.rb +1 -2
- data/lib/errors/wallaby/method_removed.rb +5 -0
- data/lib/errors/wallaby/model_not_found.rb +1 -2
- data/lib/errors/wallaby/not_authenticated.rb +1 -2
- data/lib/errors/wallaby/not_found.rb +1 -2
- data/lib/errors/wallaby/not_implemented.rb +1 -2
- data/lib/errors/wallaby/resource_not_found.rb +1 -2
- data/lib/errors/wallaby/unprocessable_entity.rb +1 -2
- data/lib/fields/wallaby/all_fields.rb +63 -0
- data/lib/forms/wallaby/form_builder.rb +2 -2
- data/lib/generators/wallaby/engine/application_generator.rb +33 -0
- data/lib/generators/wallaby/engine/authorizer/USAGE +20 -0
- data/lib/generators/wallaby/engine/authorizer/authorizer_generator.rb +19 -0
- data/lib/generators/wallaby/engine/authorizer/templates/authorizer.rb.erb +35 -0
- data/lib/generators/wallaby/engine/controller/USAGE +20 -0
- data/lib/generators/wallaby/engine/controller/controller_generator.rb +23 -0
- data/lib/generators/wallaby/engine/controller/templates/controller.rb.erb +130 -0
- data/lib/generators/wallaby/engine/decorator/USAGE +20 -0
- data/lib/generators/wallaby/engine/decorator/decorator_generator.rb +19 -0
- data/lib/generators/wallaby/engine/decorator/templates/decorator.rb.erb +5 -0
- data/lib/generators/wallaby/engine/install/USAGE +19 -0
- data/lib/generators/wallaby/engine/install/install_generator.rb +91 -0
- data/lib/generators/wallaby/engine/install/templates/application_authorizer.rb.erb +37 -0
- data/lib/generators/wallaby/engine/install/templates/application_controller.rb.erb +173 -0
- data/lib/generators/wallaby/engine/install/templates/application_decorator.rb.erb +7 -0
- data/lib/generators/wallaby/engine/install/templates/application_paginator.rb.erb +27 -0
- data/lib/generators/wallaby/engine/install/templates/application_servicer.rb.erb +47 -0
- data/lib/generators/wallaby/engine/install/templates/initializer.rb.erb +16 -0
- data/lib/generators/wallaby/engine/paginator/USAGE +20 -0
- data/lib/generators/wallaby/engine/paginator/paginator_generator.rb +19 -0
- data/lib/generators/wallaby/engine/paginator/templates/paginator.rb.erb +25 -0
- data/lib/generators/wallaby/engine/servicer/USAGE +20 -0
- data/lib/generators/wallaby/engine/servicer/servicer_generator.rb +19 -0
- data/lib/generators/wallaby/engine/servicer/templates/servicer.rb.erb +45 -0
- data/lib/helpers/wallaby/application_helper.rb +10 -59
- data/lib/helpers/wallaby/base_helper.rb +11 -11
- data/lib/helpers/wallaby/configuration_helper.rb +36 -4
- data/lib/helpers/wallaby/form_helper.rb +1 -1
- data/lib/helpers/wallaby/index_helper.rb +19 -9
- data/lib/helpers/wallaby/links_helper.rb +13 -80
- data/lib/helpers/wallaby/resources_helper.rb +39 -7
- data/lib/helpers/wallaby/secure_helper.rb +20 -19
- data/lib/interfaces/wallaby/mode.rb +8 -8
- data/lib/interfaces/wallaby/model_authorization_provider.rb +23 -22
- data/lib/interfaces/wallaby/model_decorator.rb +36 -48
- data/lib/interfaces/wallaby/model_finder.rb +3 -3
- data/lib/interfaces/wallaby/model_pagination_provider.rb +2 -6
- data/lib/interfaces/wallaby/model_service_provider.rb +4 -4
- data/lib/paginators/wallaby/model_paginator.rb +1 -1
- data/lib/responders/wallaby/json_api_responder.rb +10 -5
- data/lib/responders/wallaby/resources_responder.rb +7 -2
- data/lib/routes/wallaby/engines/base_route.rb +78 -0
- data/lib/routes/wallaby/engines/custom_app_route.rb +92 -0
- data/lib/routes/wallaby/engines/engine_route.rb +77 -0
- data/lib/routes/wallaby/resources_router.rb +100 -45
- data/lib/servicers/wallaby/model_servicer.rb +13 -13
- data/lib/services/wallaby/authorizer_finder.rb +23 -0
- data/lib/services/wallaby/class_finder.rb +42 -0
- data/lib/services/wallaby/controller_finder.rb +29 -0
- data/lib/services/wallaby/decorator_finder.rb +34 -0
- data/lib/services/wallaby/default_models_excluder.rb +45 -0
- data/lib/services/wallaby/engine_name_finder.rb +14 -11
- data/lib/services/wallaby/engine_url_for.rb +82 -37
- data/lib/services/wallaby/fields_regulator.rb +34 -0
- data/lib/services/wallaby/map/mode_mapper.rb +4 -4
- data/lib/services/wallaby/map/model_class_mapper.rb +1 -1
- data/lib/services/wallaby/model_class_filter.rb +29 -0
- data/lib/services/wallaby/paginator_finder.rb +24 -0
- data/lib/services/wallaby/prefixes_builder.rb +49 -8
- data/lib/services/wallaby/servicer_finder.rb +31 -0
- data/lib/services/wallaby/sorting/hash_builder.rb +9 -0
- data/lib/services/wallaby/sorting/link_builder.rb +7 -10
- data/lib/services/wallaby/sorting/next_builder.rb +1 -12
- data/lib/services/wallaby/sorting/single_builder.rb +1 -1
- data/lib/support/action_dispatch/routing/mapper.rb +29 -4
- data/lib/utils/wallaby/field_utils.rb +9 -8
- data/lib/utils/wallaby/inflector.rb +94 -0
- data/lib/utils/wallaby/locale.rb +2 -2
- data/lib/utils/wallaby/module_utils.rb +3 -10
- data/lib/utils/wallaby/utils.rb +21 -14
- data/lib/wallaby/class_array.rb +18 -13
- data/lib/wallaby/class_hash.rb +16 -14
- data/lib/wallaby/classifier.rb +4 -2
- data/lib/wallaby/configuration/features.rb +8 -2
- data/lib/wallaby/configuration/mapping.rb +66 -112
- data/lib/wallaby/configuration/metadata.rb +15 -12
- data/lib/wallaby/configuration/models.rb +27 -25
- data/lib/wallaby/configuration/pagination.rb +15 -19
- data/lib/wallaby/configuration/security.rb +88 -80
- data/lib/wallaby/configuration/sorting.rb +15 -17
- data/lib/wallaby/configuration.rb +58 -23
- data/lib/wallaby/constants.rb +21 -13
- data/lib/wallaby/core/version.rb +1 -1
- data/lib/wallaby/core.rb +34 -10
- data/lib/wallaby/deprecator.rb +81 -0
- data/lib/wallaby/engine.rb +2 -19
- data/lib/wallaby/guesser.rb +45 -0
- data/lib/wallaby/logger.rb +35 -13
- data/lib/wallaby/map.rb +11 -88
- data/lib/wallaby/preloader.rb +9 -31
- metadata +120 -15
- data/config/locales/wallaby_class.en.yml +0 -9
- data/lib/concerns/wallaby/defaultable.rb +0 -38
- data/lib/concerns/wallaby/shared_helpers.rb +0 -22
- data/lib/services/wallaby/map/model_class_collector.rb +0 -49
- data/lib/services/wallaby/type_renderer.rb +0 -40
- data/lib/utils/wallaby/model_utils.rb +0 -52
- data/lib/utils/wallaby/test_utils.rb +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac0d0b6d6922e91c8efb73f107bd9565911f7484b56f4cf3790d156e2de64ff9
|
|
4
|
+
data.tar.gz: 1217566eccf96b6d26d4bc52e0a44674d8bf3681f0b5d8a3ca8def1f57377743
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 652027a296d62af1e939591fa866e2fc6fa1a37fc2717e192cf893a02a7ca51ccd862985624fb5d1bedbbc48cfd5e53a9accf491e16b30ea7b09aa2ba2ac1588
|
|
7
|
+
data.tar.gz: 3457d4933495eb845198f869cd74c32c6deba85c500bb5d0e07bd8159004fda5bbbc0972f008facf5d04c44136f86b2e5ae09c2daec44934c22ba385316515fc
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
|
+
# define {ResourcesController}'s parent
|
|
4
5
|
ResourcesController = Class.new configuration.base_controller
|
|
5
6
|
|
|
6
|
-
# Resources controller
|
|
7
|
-
# It
|
|
8
|
-
# ({Wallaby::ResourcesConcern#index #index} / {Wallaby::ResourcesConcern#new #new}
|
|
9
|
-
# / {Wallaby::ResourcesConcern#create #create} / {Wallaby::ResourcesConcern#edit #edit}
|
|
10
|
-
# / {Wallaby::ResourcesConcern#update #update} / {Wallaby::ResourcesConcern#destroy #destroy})
|
|
11
|
-
# that allow subclasses to override.
|
|
7
|
+
# Resources controller is the superclass for all customization controllers.
|
|
8
|
+
# It can be used for both Admin Interface and general purpose.
|
|
12
9
|
#
|
|
13
|
-
#
|
|
10
|
+
# It contains typical resourceful action template methods
|
|
11
|
+
# that can be overridden by subclasses when customizing:
|
|
12
|
+
#
|
|
13
|
+
# - {ResourcesConcern#index #index}
|
|
14
|
+
# - {ResourcesConcern#new #new}
|
|
15
|
+
# - {ResourcesConcern#create #create}
|
|
16
|
+
# - {ResourcesConcern#edit #edit}
|
|
17
|
+
# - {ResourcesConcern#update #update}
|
|
18
|
+
# - {ResourcesConcern#destroy #destroy}
|
|
19
|
+
#
|
|
20
|
+
# And it also contains resource related helper methods, e.g.:
|
|
21
|
+
#
|
|
22
|
+
# - {Resourcable#collection #collection}
|
|
23
|
+
# - {Resourcable#resource #resource}
|
|
24
|
+
# - {Resourcable#resource_params #resource_params}
|
|
25
|
+
#
|
|
26
|
+
# For better practice, please create an application controller class (see example)
|
|
14
27
|
# to better control the functions shared between different resource controllers.
|
|
15
28
|
# @example Create an application class for Admin Interface usage
|
|
16
29
|
# class Admin::ApplicationController < Wallaby::ResourcesController
|
data/app/security/ability.rb
CHANGED
data/config/routes.rb
CHANGED
|
@@ -2,37 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
Wallaby::Engine.routes.draw do
|
|
4
4
|
# NOTE: For health check if needed
|
|
5
|
-
# @see Wallaby::
|
|
5
|
+
# @see Wallaby::ApplicationConcern#healthy
|
|
6
6
|
get 'status', to: 'wallaby/resources#healthy'
|
|
7
7
|
|
|
8
8
|
with_options to: Wallaby::ResourcesRouter.new do |route|
|
|
9
|
-
# @see
|
|
9
|
+
# @see Wallaby::ResourcesConcern#home
|
|
10
10
|
route.root defaults: { action: 'home' }
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# Error pages for all supported HTTP status in {Wallaby::ERRORS}
|
|
13
13
|
Wallaby::ERRORS.each do |status|
|
|
14
14
|
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[status]
|
|
15
|
-
route.get status, defaults: { action: status }
|
|
16
|
-
route.get code.to_s, defaults: { action: status }
|
|
15
|
+
route.get status, defaults: { action: status.to_s }
|
|
16
|
+
route.get code.to_s, defaults: { action: status.to_s }
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
#
|
|
19
|
+
# resourceful routes.
|
|
20
|
+
#
|
|
21
|
+
# `:resources` param here will be converted to the model class in the controller.
|
|
22
|
+
# For instance, `"order::items"` will become `Order::Item` later,
|
|
23
|
+
# and `Order::Item` will be used by servicer/authorizer/paginator through out the whole request process.
|
|
24
|
+
#
|
|
25
|
+
# Using colons in the `:resources` param e.g. `"order::items"` instead of `"order/items"` is
|
|
26
|
+
# to make nested namespace possible to be handled by these dynamic routes.
|
|
20
27
|
# @see Wallaby::ResourcesRouter
|
|
21
28
|
scope path: ':resources' do
|
|
22
|
-
# @see Wallaby::
|
|
29
|
+
# @see Wallaby::ResourcesConcern#index
|
|
23
30
|
route.get '', defaults: { action: 'index' }, as: :resources
|
|
24
|
-
# @see Wallaby::
|
|
31
|
+
# @see Wallaby::ResourcesConcern#new
|
|
25
32
|
route.get 'new', defaults: { action: 'new' }, as: :new_resource
|
|
26
|
-
# @see Wallaby::
|
|
33
|
+
# @see Wallaby::ResourcesConcern#edit
|
|
27
34
|
route.get ':id/edit', defaults: { action: 'edit' }, as: :edit_resource
|
|
28
|
-
# @see Wallaby::
|
|
35
|
+
# @see Wallaby::ResourcesConcern#show
|
|
29
36
|
route.get ':id', defaults: { action: 'show' }, as: :resource
|
|
30
37
|
|
|
31
|
-
# @see Wallaby::
|
|
38
|
+
# @see Wallaby::ResourcesConcern#create
|
|
32
39
|
route.post '', defaults: { action: 'create' }
|
|
33
|
-
# @see Wallaby::
|
|
34
|
-
route.match ':id', via: %i
|
|
35
|
-
# @see Wallaby::
|
|
40
|
+
# @see Wallaby::ResourcesConcern#update
|
|
41
|
+
route.match ':id', via: %i[patch put], defaults: { action: 'update' }
|
|
42
|
+
# @see Wallaby::ResourcesConcern#destroy
|
|
36
43
|
route.delete ':id', defaults: { action: 'destroy' }
|
|
37
44
|
end
|
|
38
45
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
4
|
class Custom
|
|
5
|
-
# Default authorization provider for {
|
|
5
|
+
# Default authorization provider for {Custom} mode that allowlists everything.
|
|
6
6
|
class DefaultProvider < DefaultAuthorizationProvider
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
4
|
class Custom
|
|
5
|
-
# {
|
|
5
|
+
# {Custom} mode decorator that only pulls out all the attributes from setter/getter pair methods.
|
|
6
6
|
class ModelDecorator < ::Wallaby::ModelDecorator
|
|
7
|
-
#
|
|
7
|
+
# Retrieve the attributes from the setter/getter pair methods, e.g. `name=` and `name`
|
|
8
8
|
# @return [ActiveSupport::HashWithIndifferentAccess] metadata
|
|
9
9
|
def fields
|
|
10
10
|
@fields ||=
|
|
@@ -34,21 +34,9 @@ module Wallaby
|
|
|
34
34
|
@form_fields ||= Utils.clone fields
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @return [Array<String>] a list of field names for show page
|
|
43
|
-
def show_field_names
|
|
44
|
-
@show_field_names ||= reposition show_fields.keys, primary_key
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# @return [Array<String>] a list of field names for form (new/edit) page
|
|
48
|
-
def form_field_names
|
|
49
|
-
@form_field_names ||= form_fields.keys - [primary_key.to_s]
|
|
50
|
-
end
|
|
51
|
-
|
|
37
|
+
# It returns an ActiveModel::Errors instance. However, this instance does not contain any errors.
|
|
38
|
+
# You might want to override this method in the custom resource decorator
|
|
39
|
+
# and get the errors out from the given **resource**.
|
|
52
40
|
# @param resource [Object]
|
|
53
41
|
# @return [ActiveModel::Errors]
|
|
54
42
|
def form_active_errors(resource)
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
4
|
class Custom
|
|
5
|
-
# Model finder for {
|
|
5
|
+
# Model finder for {Custom} mode that returns the list of model set by
|
|
6
6
|
# {Wallaby::Configuration#custom_models}
|
|
7
7
|
class ModelFinder < ::Wallaby::ModelFinder
|
|
8
|
-
# @return [
|
|
8
|
+
# @return [ClashArray] a list of classes
|
|
9
9
|
def all
|
|
10
|
-
Wallaby.configuration.custom_models
|
|
10
|
+
Wallaby.configuration.custom_models
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
4
|
class Custom
|
|
5
|
-
# Model pagination provider for {
|
|
5
|
+
# Model pagination provider for {Custom} mode
|
|
6
6
|
class ModelPaginationProvider < ::Wallaby::ModelPaginationProvider
|
|
7
7
|
# By default, it doesn't support pagination
|
|
8
8
|
# @return [false]
|
|
@@ -14,18 +14,25 @@ module Wallaby
|
|
|
14
14
|
defined?(CanCanCan) && context.respond_to?(:current_ability)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# Get the information from context for {ModelAuthorizationProvider#initialize}
|
|
18
|
+
# @param context [ActionController::Base, ActionView::Base]
|
|
19
|
+
# @return [Hash] options
|
|
20
|
+
def self.options_from(context)
|
|
21
|
+
{
|
|
22
|
+
ability: context.try(:current_ability),
|
|
23
|
+
user: context.try(:wallaby_user)
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
17
27
|
# @!attribute [w] ability
|
|
18
28
|
attr_writer :ability
|
|
19
29
|
|
|
20
30
|
# @!attribute [r] ability
|
|
21
|
-
# @return [Ability] the Ability instance for {#user #user}
|
|
22
|
-
# {Wallaby::AuthenticationConcern#wallaby_user #wallaby_user})
|
|
31
|
+
# @return [Ability] the Ability instance for {#user #user} or from the {#options}[:ability]
|
|
23
32
|
def ability
|
|
24
33
|
# NOTE: use current_ability's class to create the ability instance.
|
|
25
34
|
# just in case that developer uses a different Ability class (e.g. UserAbility)
|
|
26
35
|
@ability ||= options[:ability] || Ability.new(user)
|
|
27
|
-
rescue ArgumentError, NameError
|
|
28
|
-
context.current_ability
|
|
29
36
|
end
|
|
30
37
|
|
|
31
38
|
# Check user's permission for an action on given subject.
|
|
@@ -33,7 +40,7 @@ module Wallaby
|
|
|
33
40
|
# This method will be mostly used in controller.
|
|
34
41
|
# @param action [Symbol, String]
|
|
35
42
|
# @param subject [Object, Class]
|
|
36
|
-
# @raise [
|
|
43
|
+
# @raise [Forbidden] when user is not authorized to perform the action.
|
|
37
44
|
def authorize(action, subject)
|
|
38
45
|
ability.authorize! action, subject
|
|
39
46
|
rescue ::CanCan::AccessDenied
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
|
-
# Default authorization provider that
|
|
4
|
+
# Default authorization provider that allowlists everything.
|
|
5
5
|
class DefaultAuthorizationProvider < ModelAuthorizationProvider
|
|
6
6
|
# It returns false so that it can be used as the last resort.
|
|
7
7
|
# @param _context [ActionController::Base, ActionView::Base]
|
|
@@ -10,6 +10,15 @@ module Wallaby
|
|
|
10
10
|
false
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
# It returns empty hash.
|
|
14
|
+
# @param context [ActionController::Base, ActionView::Base]
|
|
15
|
+
# @return [Hash]
|
|
16
|
+
def self.options_from(context)
|
|
17
|
+
{
|
|
18
|
+
user: context.try(:wallaby_user)
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
13
22
|
# Do nothing
|
|
14
23
|
# @param _action [Symbol, String]
|
|
15
24
|
# @param subject [Object, Class]
|
|
@@ -23,7 +23,7 @@ module Wallaby
|
|
|
23
23
|
# It will be inherited from its parent classes if there isn't one for current class.
|
|
24
24
|
# @return [String, Symbol]
|
|
25
25
|
def provider_name
|
|
26
|
-
@provider_name
|
|
26
|
+
@provider_name || superclass.try(:provider_name)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -34,12 +34,12 @@ module Wallaby
|
|
|
34
34
|
attr_reader :model_class
|
|
35
35
|
|
|
36
36
|
# @!attribute [r] provider
|
|
37
|
-
# @return [
|
|
37
|
+
# @return [ModelAuthorizationProvider] the instance that does the job
|
|
38
38
|
# @since wallaby-5.2.0
|
|
39
39
|
attr_reader :provider
|
|
40
40
|
|
|
41
41
|
# @!attribute [r] context
|
|
42
|
-
# @return [ActionController::Base, ActionView::Base]
|
|
42
|
+
# @return [ActionController::Base, ActionView::Base, nil]
|
|
43
43
|
# @since 0.2.2
|
|
44
44
|
attr_reader :context
|
|
45
45
|
|
|
@@ -48,29 +48,54 @@ module Wallaby
|
|
|
48
48
|
# @since 0.2.2
|
|
49
49
|
attr_reader :options
|
|
50
50
|
|
|
51
|
+
# @note use this method instead of {#initialize} to create authorizer instance
|
|
52
|
+
# Factory method to determine which provider and what options to use.
|
|
51
53
|
# @param model_class [Class]
|
|
52
54
|
# @param context [ActionController::Base, ActionView::Base]
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
def self.create(model_class, context)
|
|
56
|
+
model_class ||= self.model_class
|
|
57
|
+
provider_class = guess_and_set_provider_from(model_class, context)
|
|
58
|
+
options = provider_class.options_from(context)
|
|
59
|
+
new(model_class, provider: provider_class.new(options), context: context)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Shortcut of {Map.authorizer_provider_map}
|
|
63
|
+
def self.providers_of(model_class)
|
|
64
|
+
Map.authorizer_provider_map(model_class)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param model_class [Class]
|
|
68
|
+
# @param provider_name [String]
|
|
69
|
+
# @param provider [Wallaby::ModelAuthorizationProvider]
|
|
70
|
+
# @param context [ActionController::Base, ActionView::Base]
|
|
71
|
+
# @param options [Hash]
|
|
72
|
+
def initialize(
|
|
73
|
+
model_class,
|
|
74
|
+
provider_name: nil,
|
|
75
|
+
provider: nil,
|
|
76
|
+
context: nil,
|
|
77
|
+
options: {}
|
|
78
|
+
)
|
|
55
79
|
@model_class = model_class || self.class.model_class
|
|
56
|
-
@context = context
|
|
57
80
|
@options = options
|
|
58
|
-
@
|
|
81
|
+
@context = context
|
|
82
|
+
@provider = provider \
|
|
83
|
+
|| self.class.providers_of(@model_class)[provider_name].new(options)
|
|
59
84
|
end
|
|
60
85
|
|
|
61
|
-
protected
|
|
62
|
-
|
|
63
86
|
# Go through the provider list and find out the one is
|
|
64
87
|
# {Wallaby::ModelAuthorizationProvider.available? .available?}
|
|
88
|
+
# @param model_class [Class]
|
|
65
89
|
# @param context [ActionController::Base, ActionView::Base]
|
|
66
|
-
|
|
90
|
+
# @return [Class] provider class
|
|
91
|
+
def self.guess_and_set_provider_from(model_class, context)
|
|
92
|
+
providers = providers_of(model_class)
|
|
67
93
|
provider_class =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
provider_class.new context, **options
|
|
94
|
+
providers[provider_name] \
|
|
95
|
+
|| providers.values.find { |klass| klass.available? context } \
|
|
96
|
+
|| providers[:default] # fallback to default
|
|
97
|
+
self.provider_name ||= provider_class.provider_name
|
|
98
|
+
provider_class
|
|
74
99
|
end
|
|
75
100
|
end
|
|
76
101
|
end
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Wallaby
|
|
4
|
-
# @note This authorization provider DOES NOT use the
|
|
5
|
-
# {https://github.com/varvet/pundit#customize-pundit-user pundit_user} helper.
|
|
6
|
-
# It uses the one from {Wallaby::AuthenticationConcern#wallaby_user #wallaby_user} instead.
|
|
7
4
|
# {https://github.com/varvet/pundit Pundit} base authorization provider.
|
|
8
5
|
class PunditAuthorizationProvider < ModelAuthorizationProvider
|
|
9
6
|
# Detect and see if Pundit is in use.
|
|
@@ -14,12 +11,21 @@ module Wallaby
|
|
|
14
11
|
defined?(Pundit) && context.respond_to?(:pundit_user)
|
|
15
12
|
end
|
|
16
13
|
|
|
14
|
+
# Get the information from context for {ModelAuthorizationProvider#initialize}
|
|
15
|
+
# @param context [ActionController::Base, ActionView::Base]
|
|
16
|
+
# @return [Hash] options
|
|
17
|
+
def self.options_from(context)
|
|
18
|
+
{
|
|
19
|
+
user: context.try(:pundit_user) || context.try(:wallaby_user)
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
17
23
|
# Check user's permission for an action on given subject.
|
|
18
24
|
#
|
|
19
|
-
# This method
|
|
25
|
+
# This method is mostly used in controller.
|
|
20
26
|
# @param action [Symbol, String]
|
|
21
27
|
# @param subject [Object, Class]
|
|
22
|
-
# @raise [
|
|
28
|
+
# @raise [Forbidden] when user is not authorized to perform the action.
|
|
23
29
|
def authorize(action, subject)
|
|
24
30
|
Pundit.authorize(user, subject, normalize(action)) && subject
|
|
25
31
|
rescue ::Pundit::NotAuthorizedError
|
|
@@ -35,10 +41,18 @@ module Wallaby
|
|
|
35
41
|
# @return [true] if user is allowed to perform the action
|
|
36
42
|
# @return [false] otherwise
|
|
37
43
|
def authorized?(action, subject)
|
|
38
|
-
policy = Pundit.policy!
|
|
44
|
+
policy = Pundit.policy!(user, subject)
|
|
39
45
|
policy.try normalize(action)
|
|
40
46
|
end
|
|
41
47
|
|
|
48
|
+
# Restrict user to access certain scope/query.
|
|
49
|
+
# @param _action [Symbol, String]
|
|
50
|
+
# @param scope [Object]
|
|
51
|
+
# @return [Object]
|
|
52
|
+
def accessible_for(_action, scope)
|
|
53
|
+
Pundit.policy_scope!(user, scope)
|
|
54
|
+
end
|
|
55
|
+
|
|
42
56
|
# Restrict user to assign certain values.
|
|
43
57
|
#
|
|
44
58
|
# It will do a lookup in policy's methods and pick the first available method:
|
|
@@ -49,7 +63,7 @@ module Wallaby
|
|
|
49
63
|
# @param subject [Object]
|
|
50
64
|
# @return [Hash] field value paired hash that user's allowed to assign
|
|
51
65
|
def attributes_for(action, subject)
|
|
52
|
-
policy = Pundit.policy!
|
|
66
|
+
policy = Pundit.policy!(user, subject)
|
|
53
67
|
policy.try("attributes_for_#{action}") || policy.try('attributes_for') || {}
|
|
54
68
|
end
|
|
55
69
|
|
|
@@ -63,7 +77,7 @@ module Wallaby
|
|
|
63
77
|
# @param subject [Object]
|
|
64
78
|
# @return [Array] field list that user's allowed to change.
|
|
65
79
|
def permit_params(action, subject)
|
|
66
|
-
policy = Pundit.policy!
|
|
80
|
+
policy = Pundit.policy!(user, subject)
|
|
67
81
|
# @see https://github.com/varvet/pundit/blob/master/lib/pundit.rb#L258
|
|
68
82
|
policy.try("permitted_attributes_for_#{action}") || policy.try('permitted_attributes')
|
|
69
83
|
end
|
|
@@ -6,105 +6,75 @@ module Wallaby
|
|
|
6
6
|
module ApplicationConcern
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
include Engineable
|
|
10
|
+
include Urlable
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
rescue_from NotFound, with: :not_found
|
|
14
|
+
rescue_from ::ActionController::ParameterMissing, with: :bad_request
|
|
15
|
+
rescue_from ::ActiveRecord::StatementInvalid, with: :unprocessable_entity
|
|
16
|
+
rescue_from NotImplemented, with: :not_implemented
|
|
17
|
+
rescue_from UnprocessableEntity, with: :unprocessable_entity
|
|
18
|
+
|
|
19
|
+
delegate(:configuration, to: Wallaby)
|
|
20
|
+
end
|
|
13
21
|
|
|
14
|
-
# @!method healthy
|
|
15
22
|
# Health check page
|
|
23
|
+
def healthy
|
|
24
|
+
render plain: 'healthy'
|
|
25
|
+
end
|
|
16
26
|
|
|
17
|
-
# @!method not_found(exception = nil)
|
|
18
27
|
# Not found page
|
|
19
28
|
# @param exception [Exception] comes from **rescue_from**
|
|
29
|
+
def not_found(exception = nil)
|
|
30
|
+
render_error exception, __callee__
|
|
31
|
+
end
|
|
20
32
|
|
|
21
|
-
# @!method bad_request(exception = nil)
|
|
22
33
|
# Bad request page
|
|
23
34
|
# @param exception [Exception] comes from **rescue_from**
|
|
35
|
+
def bad_request(exception = nil)
|
|
36
|
+
render_error exception, __callee__
|
|
37
|
+
end
|
|
24
38
|
|
|
25
|
-
# @!method unprocessable_entity(exception = nil)
|
|
26
39
|
# Unprocessable entity page
|
|
27
40
|
# @param exception [Exception] comes from **rescue_from**
|
|
41
|
+
def unprocessable_entity(exception = nil)
|
|
42
|
+
render_error exception, __callee__
|
|
43
|
+
end
|
|
28
44
|
|
|
29
|
-
# @!method internal_server_error(exception = nil)
|
|
30
45
|
# Internal server error page
|
|
31
46
|
# @param exception [Exception] comes from **rescue_from**
|
|
47
|
+
def internal_server_error(exception = nil)
|
|
48
|
+
render_error exception, __callee__
|
|
49
|
+
end
|
|
32
50
|
|
|
33
|
-
# @!method not_implemented(exception = nil)
|
|
34
51
|
# Not implemented
|
|
35
52
|
# @param exception [Exception] comes from **rescue_from**
|
|
53
|
+
def not_implemented(exception = nil)
|
|
54
|
+
render_error exception, __callee__
|
|
55
|
+
end
|
|
36
56
|
|
|
37
|
-
# @!method helpers
|
|
38
57
|
# {https://api.rubyonrails.org/classes/ActionController/Helpers.html#method-i-helpers helpers}
|
|
39
58
|
# exists since Rails 5.0, need to mimic this to support Rails 4.2.
|
|
40
59
|
# @see https://api.rubyonrails.org/classes/ActionController/Helpers.html#method-i-helpers
|
|
41
60
|
# ActionController::Helpers#helpers
|
|
42
61
|
# @see https://github.com/rails/rails/blob/5-0-stable/actionpack/lib/action_controller/metal/helpers.rb#L118
|
|
62
|
+
def helpers
|
|
63
|
+
@helpers ||= defined?(super) ? super : try(:view_context)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
protected
|
|
43
67
|
|
|
44
|
-
# @!method render_error(exception, symbol)
|
|
45
68
|
# Capture exceptions and display the error using error template.
|
|
46
69
|
# @param exception [Exception]
|
|
47
70
|
# @param symbol [Symbol] http status symbol
|
|
71
|
+
def render_error(exception, symbol)
|
|
72
|
+
Logger.error exception
|
|
48
73
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
rescue_from NotFound, with: :not_found
|
|
55
|
-
rescue_from ::ActionController::ParameterMissing, with: :bad_request
|
|
56
|
-
rescue_from ::ActiveRecord::StatementInvalid, with: :unprocessable_entity
|
|
57
|
-
rescue_from NotImplemented, with: :not_implemented
|
|
58
|
-
rescue_from UnprocessableEntity, with: :unprocessable_entity
|
|
59
|
-
|
|
60
|
-
delegate(*ConfigurationHelper.instance_methods(false), :url_for, to: :helpers)
|
|
61
|
-
|
|
62
|
-
# (see #healthy)
|
|
63
|
-
def healthy
|
|
64
|
-
render plain: 'healthy'
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# (see #not_found)
|
|
68
|
-
def not_found(exception = nil)
|
|
69
|
-
render_error exception, __callee__
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# (see #bad_request)
|
|
73
|
-
def bad_request(exception = nil)
|
|
74
|
-
render_error exception, __callee__
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# (see #unprocessable_entity)
|
|
78
|
-
def unprocessable_entity(exception = nil)
|
|
79
|
-
render_error exception, __callee__
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# (see #internal_server_error)
|
|
83
|
-
def internal_server_error(exception = nil)
|
|
84
|
-
render_error exception, __callee__
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# (see #not_implemented)
|
|
88
|
-
def not_implemented(exception = nil)
|
|
89
|
-
render_error exception, __callee__
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# (see #helpers)
|
|
93
|
-
def helpers
|
|
94
|
-
@helpers ||= defined?(super) ? super : view_context
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
protected
|
|
98
|
-
|
|
99
|
-
# (see #render_error)
|
|
100
|
-
def render_error(exception, symbol)
|
|
101
|
-
Logger.error exception
|
|
102
|
-
|
|
103
|
-
@exception = exception
|
|
104
|
-
@symbol = symbol
|
|
105
|
-
@code = Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol].to_i
|
|
106
|
-
respond_with @exception, status: @code, template: ERROR_PATH, prefixes: _prefixes
|
|
107
|
-
end
|
|
74
|
+
@exception = exception
|
|
75
|
+
@symbol = symbol
|
|
76
|
+
@code = Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol].to_i
|
|
77
|
+
respond_with @exception, status: @code, template: ERROR_PATH, prefixes: _prefixes
|
|
108
78
|
end
|
|
109
79
|
end
|
|
110
80
|
end
|