wallaby-core 0.2.11 → 0.3.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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 +29 -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 +91 -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 +1 -1
- 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 +18 -85
- 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 +10 -3
- 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 +5 -5
- 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 +1 -18
- 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 +8 -28
- metadata +113 -14
- 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: 86ff434d6a25fa665cb828cc1a1839166f386a71dff24afacb7a114402a81f50
|
4
|
+
data.tar.gz: 1a923d492ef62f597608a9c49f8a1341fe59687e8c4668749f3ad25d7a1b1c71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73183959d1177a5d707baae5c698e57f6e5ca47fe4b248e1014402dbe95c9015418d3d6d46194161c38543745c685a99bfacb73c197a1972e85beec758d8598c
|
7
|
+
data.tar.gz: ffdeeb4e9df6b63f281912c21acb758e0a7bb9d8863d38a5e081b5c81cbfed5bf4942910ebf8d03fcef2c90cb8cd66f3bf0d9763302f59ae084003ea4f82dfb3
|
@@ -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
|