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.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/wallaby/resources_controller.rb +20 -7
  3. data/app/security/ability.rb +1 -1
  4. data/config/routes.rb +21 -14
  5. data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
  6. data/lib/adaptors/wallaby/custom/model_decorator.rb +5 -17
  7. data/lib/adaptors/wallaby/custom/model_finder.rb +3 -3
  8. data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
  9. data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -1
  10. data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +12 -5
  11. data/lib/authorizers/wallaby/default_authorization_provider.rb +10 -1
  12. data/lib/authorizers/wallaby/model_authorizer.rb +41 -16
  13. data/lib/authorizers/wallaby/pundit_authorization_provider.rb +22 -8
  14. data/lib/concerns/wallaby/application_concern.rb +41 -71
  15. data/lib/concerns/wallaby/authentication_concern.rb +29 -127
  16. data/lib/concerns/wallaby/authorizable.rb +14 -57
  17. data/lib/concerns/wallaby/baseable.rb +24 -57
  18. data/lib/concerns/wallaby/configurable.rb +416 -0
  19. data/lib/concerns/wallaby/decoratable.rb +24 -60
  20. data/lib/concerns/wallaby/engineable.rb +29 -46
  21. data/lib/concerns/wallaby/fieldable.rb +45 -56
  22. data/lib/concerns/wallaby/paginatable.rb +20 -51
  23. data/lib/concerns/wallaby/prefixable.rb +24 -4
  24. data/lib/concerns/wallaby/resourcable.rb +130 -72
  25. data/lib/concerns/wallaby/resources_concern.rb +205 -305
  26. data/lib/concerns/wallaby/servicable.rb +8 -48
  27. data/lib/concerns/wallaby/urlable.rb +69 -0
  28. data/lib/decorators/wallaby/resource_decorator.rb +72 -34
  29. data/lib/errors/wallaby/class_not_found.rb +1 -2
  30. data/lib/errors/wallaby/forbidden.rb +1 -2
  31. data/lib/errors/wallaby/general_error.rb +1 -1
  32. data/lib/errors/wallaby/invalid_error.rb +1 -2
  33. data/lib/errors/wallaby/method_removed.rb +5 -0
  34. data/lib/errors/wallaby/model_not_found.rb +1 -2
  35. data/lib/errors/wallaby/not_authenticated.rb +1 -2
  36. data/lib/errors/wallaby/not_found.rb +1 -2
  37. data/lib/errors/wallaby/not_implemented.rb +1 -2
  38. data/lib/errors/wallaby/resource_not_found.rb +1 -2
  39. data/lib/errors/wallaby/unprocessable_entity.rb +1 -2
  40. data/lib/fields/wallaby/all_fields.rb +63 -0
  41. data/lib/forms/wallaby/form_builder.rb +2 -2
  42. data/lib/generators/wallaby/engine/application_generator.rb +33 -0
  43. data/lib/generators/wallaby/engine/authorizer/USAGE +20 -0
  44. data/lib/generators/wallaby/engine/authorizer/authorizer_generator.rb +19 -0
  45. data/lib/generators/wallaby/engine/authorizer/templates/authorizer.rb.erb +35 -0
  46. data/lib/generators/wallaby/engine/controller/USAGE +20 -0
  47. data/lib/generators/wallaby/engine/controller/controller_generator.rb +23 -0
  48. data/lib/generators/wallaby/engine/controller/templates/controller.rb.erb +130 -0
  49. data/lib/generators/wallaby/engine/decorator/USAGE +20 -0
  50. data/lib/generators/wallaby/engine/decorator/decorator_generator.rb +19 -0
  51. data/lib/generators/wallaby/engine/decorator/templates/decorator.rb.erb +5 -0
  52. data/lib/generators/wallaby/engine/install/USAGE +19 -0
  53. data/lib/generators/wallaby/engine/install/install_generator.rb +91 -0
  54. data/lib/generators/wallaby/engine/install/templates/application_authorizer.rb.erb +37 -0
  55. data/lib/generators/wallaby/engine/install/templates/application_controller.rb.erb +173 -0
  56. data/lib/generators/wallaby/engine/install/templates/application_decorator.rb.erb +7 -0
  57. data/lib/generators/wallaby/engine/install/templates/application_paginator.rb.erb +27 -0
  58. data/lib/generators/wallaby/engine/install/templates/application_servicer.rb.erb +47 -0
  59. data/lib/generators/wallaby/engine/install/templates/initializer.rb.erb +16 -0
  60. data/lib/generators/wallaby/engine/paginator/USAGE +20 -0
  61. data/lib/generators/wallaby/engine/paginator/paginator_generator.rb +19 -0
  62. data/lib/generators/wallaby/engine/paginator/templates/paginator.rb.erb +25 -0
  63. data/lib/generators/wallaby/engine/servicer/USAGE +20 -0
  64. data/lib/generators/wallaby/engine/servicer/servicer_generator.rb +19 -0
  65. data/lib/generators/wallaby/engine/servicer/templates/servicer.rb.erb +45 -0
  66. data/lib/helpers/wallaby/application_helper.rb +10 -59
  67. data/lib/helpers/wallaby/base_helper.rb +11 -11
  68. data/lib/helpers/wallaby/configuration_helper.rb +36 -4
  69. data/lib/helpers/wallaby/form_helper.rb +1 -1
  70. data/lib/helpers/wallaby/index_helper.rb +19 -9
  71. data/lib/helpers/wallaby/links_helper.rb +13 -80
  72. data/lib/helpers/wallaby/resources_helper.rb +39 -7
  73. data/lib/helpers/wallaby/secure_helper.rb +20 -19
  74. data/lib/interfaces/wallaby/mode.rb +8 -8
  75. data/lib/interfaces/wallaby/model_authorization_provider.rb +23 -22
  76. data/lib/interfaces/wallaby/model_decorator.rb +36 -48
  77. data/lib/interfaces/wallaby/model_finder.rb +3 -3
  78. data/lib/interfaces/wallaby/model_pagination_provider.rb +2 -6
  79. data/lib/interfaces/wallaby/model_service_provider.rb +4 -4
  80. data/lib/paginators/wallaby/model_paginator.rb +1 -1
  81. data/lib/responders/wallaby/json_api_responder.rb +10 -5
  82. data/lib/responders/wallaby/resources_responder.rb +7 -2
  83. data/lib/routes/wallaby/engines/base_route.rb +78 -0
  84. data/lib/routes/wallaby/engines/custom_app_route.rb +92 -0
  85. data/lib/routes/wallaby/engines/engine_route.rb +77 -0
  86. data/lib/routes/wallaby/resources_router.rb +100 -45
  87. data/lib/servicers/wallaby/model_servicer.rb +13 -13
  88. data/lib/services/wallaby/authorizer_finder.rb +23 -0
  89. data/lib/services/wallaby/class_finder.rb +42 -0
  90. data/lib/services/wallaby/controller_finder.rb +29 -0
  91. data/lib/services/wallaby/decorator_finder.rb +34 -0
  92. data/lib/services/wallaby/default_models_excluder.rb +45 -0
  93. data/lib/services/wallaby/engine_name_finder.rb +14 -11
  94. data/lib/services/wallaby/engine_url_for.rb +82 -37
  95. data/lib/services/wallaby/fields_regulator.rb +34 -0
  96. data/lib/services/wallaby/map/mode_mapper.rb +4 -4
  97. data/lib/services/wallaby/map/model_class_mapper.rb +1 -1
  98. data/lib/services/wallaby/model_class_filter.rb +29 -0
  99. data/lib/services/wallaby/paginator_finder.rb +24 -0
  100. data/lib/services/wallaby/prefixes_builder.rb +49 -8
  101. data/lib/services/wallaby/servicer_finder.rb +31 -0
  102. data/lib/services/wallaby/sorting/hash_builder.rb +9 -0
  103. data/lib/services/wallaby/sorting/link_builder.rb +7 -10
  104. data/lib/services/wallaby/sorting/next_builder.rb +1 -12
  105. data/lib/services/wallaby/sorting/single_builder.rb +1 -1
  106. data/lib/support/action_dispatch/routing/mapper.rb +29 -4
  107. data/lib/utils/wallaby/field_utils.rb +9 -8
  108. data/lib/utils/wallaby/inflector.rb +94 -0
  109. data/lib/utils/wallaby/locale.rb +2 -2
  110. data/lib/utils/wallaby/module_utils.rb +3 -10
  111. data/lib/utils/wallaby/utils.rb +21 -14
  112. data/lib/wallaby/class_array.rb +18 -13
  113. data/lib/wallaby/class_hash.rb +16 -14
  114. data/lib/wallaby/classifier.rb +4 -2
  115. data/lib/wallaby/configuration/features.rb +8 -2
  116. data/lib/wallaby/configuration/mapping.rb +66 -112
  117. data/lib/wallaby/configuration/metadata.rb +15 -12
  118. data/lib/wallaby/configuration/models.rb +27 -25
  119. data/lib/wallaby/configuration/pagination.rb +15 -19
  120. data/lib/wallaby/configuration/security.rb +88 -80
  121. data/lib/wallaby/configuration/sorting.rb +15 -17
  122. data/lib/wallaby/configuration.rb +58 -23
  123. data/lib/wallaby/constants.rb +21 -13
  124. data/lib/wallaby/core/version.rb +1 -1
  125. data/lib/wallaby/core.rb +34 -10
  126. data/lib/wallaby/deprecator.rb +81 -0
  127. data/lib/wallaby/engine.rb +2 -19
  128. data/lib/wallaby/guesser.rb +45 -0
  129. data/lib/wallaby/logger.rb +35 -13
  130. data/lib/wallaby/map.rb +11 -88
  131. data/lib/wallaby/preloader.rb +9 -31
  132. metadata +120 -15
  133. data/config/locales/wallaby_class.en.yml +0 -9
  134. data/lib/concerns/wallaby/defaultable.rb +0 -38
  135. data/lib/concerns/wallaby/shared_helpers.rb +0 -22
  136. data/lib/services/wallaby/map/model_class_collector.rb +0 -49
  137. data/lib/services/wallaby/type_renderer.rb +0 -40
  138. data/lib/utils/wallaby/model_utils.rb +0 -52
  139. data/lib/utils/wallaby/test_utils.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f1ac3bd8eff66540e6b9f6c6c7b1f569bffe58177134b70fde36bd5b9e3df82
4
- data.tar.gz: ec78aac3194fe1dd051160d9f77695247213565260b1035d1aebd7acd84ea1a6
3
+ metadata.gz: ac0d0b6d6922e91c8efb73f107bd9565911f7484b56f4cf3790d156e2de64ff9
4
+ data.tar.gz: 1217566eccf96b6d26d4bc52e0a44674d8bf3681f0b5d8a3ca8def1f57377743
5
5
  SHA512:
6
- metadata.gz: d5b70441c58655aa2bd9aa49175f137e8680a78619c9a5236e560a912dc86995dba8597a60f54ad90ac3a80a074a4ddb8bfca346c8a73fa772edae8e63aa2fc9
7
- data.tar.gz: 459f70f2d01dba201f7873b5a7fa61c33ea3cf8ff8824ea7d33f450878ddbb01242bf71887a3200229cfe44b3c0c70190e76ea165872fe43238e424ed5a0254e
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, superclass for all customization controllers.
7
- # It contains CRUD template action methods
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
- # For better practice, please create an application controller class (see example)
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @!visibility private
4
- # Defualt ability for wallaby
4
+ # Defualt ability for {Wallaby}
5
5
  # If main app has defined `ability.rb`, this file will not be loaded/used.
6
6
  class Ability
7
7
  include ::CanCan::Ability if defined?(::CanCan)
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::ApplicationController#healthy
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 `home` action for more
9
+ # @see Wallaby::ResourcesConcern#home
10
10
  route.root defaults: { action: 'home' }
11
11
 
12
- # To generate error pages for all supported HTTP status
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
- # To generate general CRUD resourceful routes
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::ResourcesController#index
29
+ # @see Wallaby::ResourcesConcern#index
23
30
  route.get '', defaults: { action: 'index' }, as: :resources
24
- # @see Wallaby::ResourcesController#new
31
+ # @see Wallaby::ResourcesConcern#new
25
32
  route.get 'new', defaults: { action: 'new' }, as: :new_resource
26
- # @see Wallaby::ResourcesController#edit
33
+ # @see Wallaby::ResourcesConcern#edit
27
34
  route.get ':id/edit', defaults: { action: 'edit' }, as: :edit_resource
28
- # @see Wallaby::ResourcesController#show
35
+ # @see Wallaby::ResourcesConcern#show
29
36
  route.get ':id', defaults: { action: 'show' }, as: :resource
30
37
 
31
- # @see Wallaby::ResourcesController#create
38
+ # @see Wallaby::ResourcesConcern#create
32
39
  route.post '', defaults: { action: 'create' }
33
- # @see Wallaby::ResourcesController#update
34
- route.match ':id', via: %i(patch put), defaults: { action: 'update' }
35
- # @see Wallaby::ResourcesController#destroy
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 {Wallaby::Custom} mode that whitelists everything.
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
- # {Wallaby::Custom} mode decorator that only pulls out all the attributes from setter/getter methods.
5
+ # {Custom} mode decorator that only pulls out all the attributes from setter/getter pair methods.
6
6
  class ModelDecorator < ::Wallaby::ModelDecorator
7
- # Assume that attributes come from the setter/getter, e.g. `name=`/`name`
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
- # @return [Array<String>] a list of field names for index page
38
- def index_field_names
39
- @index_field_names ||= reposition index_fields.keys, primary_key
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 {Wallaby::Custom} mode that returns the list of model set by
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 [Wallaby::ClashArray] a list of classes
8
+ # @return [ClashArray] a list of classes
9
9
  def all
10
- Wallaby.configuration.custom_models.presence
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 {Wallaby::Custom} mode
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]
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Wallaby
4
4
  class Custom
5
- # Model service provider for {Wallaby::Custom} mode
5
+ # Model service provider for {Custom} mode
6
6
  class ModelServiceProvider < ::Wallaby::ModelServiceProvider
7
7
  end
8
8
  end
@@ -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} (which is a
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 [Wallaby::Forbidden] when user is not authorized to perform the action.
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 whitelists everything.
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 ||= superclass.try :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 [Wallaby::ModelAuthorizationProvider] the instance that does the job
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
- # @param options [Symbol, String, nil]
54
- def initialize(model_class, context, **options)
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
- @provider = guess_provider_from(context)
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
- def guess_provider_from(context)
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
- Map.authorizer_provider_map(model_class).try do |providers|
69
- providers[options[:provider_name] || self.class.provider_name] \
70
- || providers.values.find { |klass| klass.available? context } \
71
- || providers[:default] # fallback to default
72
- end
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 will be mostly used in controller.
25
+ # This method is mostly used in controller.
20
26
  # @param action [Symbol, String]
21
27
  # @param subject [Object, Class]
22
- # @raise [Wallaby::Forbidden] when user is not authorized to perform the action.
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! user, subject
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! user, subject
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! user, subject
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
- # @!parse
10
- # extend Engineable::ClassMethods
11
- # include Engineable
12
- # include SharedHelpers
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
- included do # rubocop:disable Metrics/BlockLength
50
- extend Engineable::ClassMethods
51
- include Engineable
52
- include SharedHelpers
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