actionpack 7.0.2.4 → 7.0.4
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.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +80 -0
- data/lib/abstract_controller/base.rb +6 -5
- data/lib/abstract_controller/callbacks.rb +1 -1
- data/lib/abstract_controller/helpers.rb +1 -1
- data/lib/action_controller/api.rb +5 -5
- data/lib/action_controller/base.rb +5 -4
- data/lib/action_controller/form_builder.rb +2 -2
- data/lib/action_controller/metal/conditional_get.rb +1 -1
- data/lib/action_controller/metal/content_security_policy.rb +35 -1
- data/lib/action_controller/metal/helpers.rb +1 -1
- data/lib/action_controller/metal/http_authentication.rb +56 -29
- data/lib/action_controller/metal/live.rb +1 -0
- data/lib/action_controller/metal/permissions_policy.rb +18 -27
- data/lib/action_controller/metal/redirecting.rb +4 -3
- data/lib/action_controller/metal/renderers.rb +10 -11
- data/lib/action_controller/metal/rendering.rb +3 -3
- data/lib/action_controller/metal/request_forgery_protection.rb +4 -4
- data/lib/action_controller/metal/streaming.rb +5 -5
- data/lib/action_controller/metal/strong_parameters.rb +13 -4
- data/lib/action_controller/metal/url_for.rb +3 -3
- data/lib/action_controller/metal.rb +3 -3
- data/lib/action_controller/renderer.rb +1 -1
- data/lib/action_controller/test_case.rb +3 -3
- data/lib/action_controller.rb +1 -0
- data/lib/action_dispatch/http/content_security_policy.rb +71 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +2 -2
- data/lib/action_dispatch/http/permissions_policy.rb +16 -0
- data/lib/action_dispatch/http/request.rb +2 -2
- data/lib/action_dispatch/http/response.rb +2 -3
- data/lib/action_dispatch/middleware/cookies.rb +6 -3
- data/lib/action_dispatch/middleware/flash.rb +8 -7
- data/lib/action_dispatch/middleware/request_id.rb +1 -1
- data/lib/action_dispatch/middleware/server_timing.rb +53 -10
- data/lib/action_dispatch/middleware/session/cookie_store.rb +9 -9
- data/lib/action_dispatch/routing/mapper.rb +5 -5
- data/lib/action_dispatch/routing/redirection.rb +5 -0
- data/lib/action_dispatch/routing/route_set.rb +3 -1
- data/lib/action_dispatch/routing/url_for.rb +3 -3
- data/lib/action_dispatch/routing.rb +3 -4
- data/lib/action_dispatch/testing/assertions/routing.rb +3 -2
- data/lib/action_dispatch/testing/test_response.rb +20 -2
- data/lib/action_pack/gem_version.rb +3 -3
- data/lib/action_pack/version.rb +1 -1
- metadata +12 -12
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 1f920e0c8edecebb6708efc39f5bc4de2d9dd1beb20b11fac4c2408406ef4812
         | 
| 4 | 
            +
              data.tar.gz: e87d2d36beb62a55feb9677d7009725531c2187692099d41682014822e478204
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4ed2fb214470bb89c3a6c6101428806f6ebb2eb01044cc8426dddecdb189a541511aa7355b07f13e898a076a2a7f9b3eabefdfdfb7130918c216993da503e173
         | 
| 7 | 
            +
              data.tar.gz: 0c4a9b5b27a03faec9e2d971cce098cb943fbdc7bf0cb25ba243755bfa72760c2a0eefc18e80134877f2a382d7d154deee64faaccacbe557768a978771873ee4
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,83 @@ | |
| 1 | 
            +
            ## Rails 7.0.4 (September 09, 2022) ##
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            *   Prevent `ActionDispatch::ServerTiming` from overwriting existing values in `Server-Timing`.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                Previously, if another middleware down the chain set `Server-Timing` header,
         | 
| 6 | 
            +
                it would overwritten by `ActionDispatch::ServerTiming`.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                *Jakub Malinowski*
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            ## Rails 7.0.3.1 (July 12, 2022) ##
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            *   No changes.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            ## Rails 7.0.3 (May 09, 2022) ##
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            *   Allow relative redirects when `raise_on_open_redirects` is enabled.
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                *Tom Hughes*
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            *   Fix `authenticate_with_http_basic` to allow for missing password.
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                Before Rails 7.0 it was possible to handle basic authentication with only a username.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                ```ruby
         | 
| 27 | 
            +
                authenticate_with_http_basic do |token, _|
         | 
| 28 | 
            +
                  ApiClient.authenticate(token)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
                ```
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                This ability is restored.
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                *Jean Boussier*
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            *   Fix `content_security_policy` returning invalid directives.
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                Directives such as `self`, `unsafe-eval` and few others were not
         | 
| 39 | 
            +
                single quoted when the directive was the result of calling a lambda
         | 
| 40 | 
            +
                returning an array.
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                ```ruby
         | 
| 43 | 
            +
                content_security_policy do |policy|
         | 
| 44 | 
            +
                  policy.frame_ancestors lambda { [:self, "https://example.com"] }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
                ```
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                With this fix the policy generated from above will now be valid.
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                *Edouard Chin*
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            *   Fix `skip_forgery_protection` to run without raising an error if forgery
         | 
| 53 | 
            +
                protection has not been enabled / `verify_authenticity_token` is not a
         | 
| 54 | 
            +
                defined callback.
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                This fix prevents the Rails 7.0 Welcome Page (`/`) from raising an
         | 
| 57 | 
            +
                `ArgumentError` if `default_protect_from_forgery` is false.
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                *Brad Trick*
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            *   Fix `ActionController::Live` to copy the IsolatedExecutionState in the ephemeral thread.
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                Since its inception `ActionController::Live` has been copying thread local variables
         | 
| 64 | 
            +
                to keep things such as `CurrentAttributes` set from middlewares working in the controller action.
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                With the introduction of `IsolatedExecutionState` in 7.0, some of that global state was lost in
         | 
| 67 | 
            +
                `ActionController::Live` controllers.
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                *Jean Boussier*
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            *   Fix setting `trailing_slash: true` in route definition.
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                ```ruby
         | 
| 74 | 
            +
                get '/test' => "test#index", as: :test, trailing_slash: true
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                test_path() # => "/test/"
         | 
| 77 | 
            +
                ```
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                *Jean Boussier*
         | 
| 80 | 
            +
             | 
| 1 81 | 
             
            ## Rails 7.0.2.4 (April 26, 2022) ##
         | 
| 2 82 |  | 
| 3 83 | 
             
            *   Allow Content Security Policy DSL to generate for API responses.
         | 
| @@ -150,13 +150,14 @@ module AbstractController | |
| 150 150 |  | 
| 151 151 | 
             
                  process_action(action_name, *args)
         | 
| 152 152 | 
             
                end
         | 
| 153 | 
            +
                ruby2_keywords(:process)
         | 
| 153 154 |  | 
| 154 | 
            -
                # Delegates to the class' ::controller_path
         | 
| 155 | 
            +
                # Delegates to the class's ::controller_path.
         | 
| 155 156 | 
             
                def controller_path
         | 
| 156 157 | 
             
                  self.class.controller_path
         | 
| 157 158 | 
             
                end
         | 
| 158 159 |  | 
| 159 | 
            -
                # Delegates to the class' ::action_methods
         | 
| 160 | 
            +
                # Delegates to the class's ::action_methods.
         | 
| 160 161 | 
             
                def action_methods
         | 
| 161 162 | 
             
                  self.class.action_methods
         | 
| 162 163 | 
             
                end
         | 
| @@ -177,7 +178,7 @@ module AbstractController | |
| 177 178 |  | 
| 178 179 | 
             
                # Tests if a response body is set. Used to determine if the
         | 
| 179 180 | 
             
                # +process_action+ callback needs to be terminated in
         | 
| 180 | 
            -
                #  | 
| 181 | 
            +
                # AbstractController::Callbacks.
         | 
| 181 182 | 
             
                def performed?
         | 
| 182 183 | 
             
                  response_body
         | 
| 183 184 | 
             
                end
         | 
| @@ -210,8 +211,8 @@ module AbstractController | |
| 210 211 | 
             
                  #
         | 
| 211 212 | 
             
                  # Notice that the first argument is the method to be dispatched
         | 
| 212 213 | 
             
                  # which is *not* necessarily the same as the action name.
         | 
| 213 | 
            -
                  def process_action( | 
| 214 | 
            -
                    send_action( | 
| 214 | 
            +
                  def process_action(...)
         | 
| 215 | 
            +
                    send_action(...)
         | 
| 215 216 | 
             
                  end
         | 
| 216 217 |  | 
| 217 218 | 
             
                  # Actually call the method associated with the action. Override
         | 
| @@ -229,7 +229,7 @@ module AbstractController | |
| 229 229 | 
             
                private
         | 
| 230 230 | 
             
                  # Override <tt>AbstractController::Base#process_action</tt> to run the
         | 
| 231 231 | 
             
                  # <tt>process_action</tt> callbacks around the normal behavior.
         | 
| 232 | 
            -
                  def process_action( | 
| 232 | 
            +
                  def process_action(...)
         | 
| 233 233 | 
             
                    run_callbacks(:process_action) do
         | 
| 234 234 | 
             
                      super
         | 
| 235 235 | 
             
                    end
         | 
| @@ -110,7 +110,7 @@ module AbstractController | |
| 110 110 | 
             
                  # The last two assume that <tt>"foo".camelize</tt> returns "Foo".
         | 
| 111 111 | 
             
                  #
         | 
| 112 112 | 
             
                  # When strings or symbols are passed, the method finds the actual module
         | 
| 113 | 
            -
                  # object using  | 
| 113 | 
            +
                  # object using String#constantize. Therefore, if the module has not been
         | 
| 114 114 | 
             
                  # yet loaded, it has to be autoloadable, which is normally the case.
         | 
| 115 115 | 
             
                  #
         | 
| 116 116 | 
             
                  # Namespaces are supported. The following calls include +Foo::BarHelper+:
         | 
| @@ -5,7 +5,7 @@ require "action_controller" | |
| 5 5 | 
             
            require "action_controller/log_subscriber"
         | 
| 6 6 |  | 
| 7 7 | 
             
            module ActionController
         | 
| 8 | 
            -
              # API Controller is a lightweight version of  | 
| 8 | 
            +
              # API Controller is a lightweight version of ActionController::Base,
         | 
| 9 9 | 
             
              # created for applications that don't require all functionalities that a complete
         | 
| 10 10 | 
             
              # \Rails controller provides, allowing you to create controllers with just the
         | 
| 11 11 | 
             
              # features that you need for API only applications.
         | 
| @@ -32,7 +32,7 @@ module ActionController | |
| 32 32 | 
             
              #   end
         | 
| 33 33 | 
             
              #
         | 
| 34 34 | 
             
              # Request, response, and parameters objects all work the exact same way as
         | 
| 35 | 
            -
              #  | 
| 35 | 
            +
              # ActionController::Base.
         | 
| 36 36 | 
             
              #
         | 
| 37 37 | 
             
              # == Renders
         | 
| 38 38 | 
             
              #
         | 
| @@ -51,7 +51,7 @@ module ActionController | |
| 51 51 | 
             
              #
         | 
| 52 52 | 
             
              # Redirects are used to move from one action to another. You can use the
         | 
| 53 53 | 
             
              # <tt>redirect_to</tt> method in your controllers in the same way as in
         | 
| 54 | 
            -
              #  | 
| 54 | 
            +
              # ActionController::Base. For example:
         | 
| 55 55 | 
             
              #
         | 
| 56 56 | 
             
              #   def create
         | 
| 57 57 | 
             
              #     redirect_to root_url and return if not_authorized?
         | 
| @@ -61,7 +61,7 @@ module ActionController | |
| 61 61 | 
             
              # == Adding New Behavior
         | 
| 62 62 | 
             
              #
         | 
| 63 63 | 
             
              # In some scenarios you may want to add back some functionality provided by
         | 
| 64 | 
            -
              #  | 
| 64 | 
            +
              # ActionController::Base that is not present by default in
         | 
| 65 65 | 
             
              # <tt>ActionController::API</tt>, for instance <tt>MimeResponds</tt>. This
         | 
| 66 66 | 
             
              # module gives you the <tt>respond_to</tt> method. Adding it is quite simple,
         | 
| 67 67 | 
             
              # you just need to include the module in a specific controller or in
         | 
| @@ -83,7 +83,7 @@ module ActionController | |
| 83 83 | 
             
              #     end
         | 
| 84 84 | 
             
              #   end
         | 
| 85 85 | 
             
              #
         | 
| 86 | 
            -
              # Make sure to check the modules included in  | 
| 86 | 
            +
              # Make sure to check the modules included in ActionController::Base
         | 
| 87 87 | 
             
              # if you want to use any other functionality that is not provided
         | 
| 88 88 | 
             
              # by <tt>ActionController::API</tt> out of the box.
         | 
| 89 89 | 
             
              class API < Metal
         | 
| @@ -87,10 +87,11 @@ module ActionController | |
| 87 87 | 
             
              #
         | 
| 88 88 | 
             
              # or you can remove the entire session with +reset_session+.
         | 
| 89 89 | 
             
              #
         | 
| 90 | 
            -
              #  | 
| 91 | 
            -
              #  | 
| 92 | 
            -
              #
         | 
| 93 | 
            -
              #  | 
| 90 | 
            +
              # By default, sessions are stored in an encrypted browser cookie (see
         | 
| 91 | 
            +
              # ActionDispatch::Session::CookieStore). Thus the user will not be able to
         | 
| 92 | 
            +
              # read or edit the session data. However, the user can keep a copy of the
         | 
| 93 | 
            +
              # cookie even after it has expired, so you should avoid storing sensitive
         | 
| 94 | 
            +
              # information in cookie-based sessions.
         | 
| 94 95 | 
             
              #
         | 
| 95 96 | 
             
              # == Responses
         | 
| 96 97 | 
             
              #
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            module ActionController
         | 
| 4 4 | 
             
              # Override the default form builder for all views rendered by this
         | 
| 5 5 | 
             
              # controller and any of its descendants. Accepts a subclass of
         | 
| 6 | 
            -
              #  | 
| 6 | 
            +
              # ActionView::Helpers::FormBuilder.
         | 
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              # For example, given a form builder:
         | 
| 9 9 | 
             
              #
         | 
| @@ -36,7 +36,7 @@ module ActionController | |
| 36 36 | 
             
                  # in the views rendered by this controller and its subclasses.
         | 
| 37 37 | 
             
                  #
         | 
| 38 38 | 
             
                  # ==== Parameters
         | 
| 39 | 
            -
                  # * <tt>builder</tt> - Default form builder, an instance of  | 
| 39 | 
            +
                  # * <tt>builder</tt> - Default form builder, an instance of ActionView::Helpers::FormBuilder
         | 
| 40 40 | 
             
                  def default_form_builder(builder)
         | 
| 41 41 | 
             
                    self._default_form_builder = builder
         | 
| 42 42 | 
             
                  end
         | 
| @@ -268,7 +268,7 @@ module ActionController | |
| 268 268 | 
             
                #   expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds, stale_if_error: 5.minutes
         | 
| 269 269 | 
             
                #
         | 
| 270 270 | 
             
                # HTTP Cache-Control Extensions other values: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
         | 
| 271 | 
            -
                # Any additional key-value pairs are concatenated onto the  | 
| 271 | 
            +
                # Any additional key-value pairs are concatenated onto the Cache-Control header in the response:
         | 
| 272 272 | 
             
                #
         | 
| 273 273 | 
             
                #   expires_in 3.hours, public: true, "s-maxage": 3.hours, "no-transform": true
         | 
| 274 274 | 
             
                #
         | 
| @@ -2,7 +2,6 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module ActionController # :nodoc:
         | 
| 4 4 | 
             
              module ContentSecurityPolicy
         | 
| 5 | 
            -
                # TODO: Documentation
         | 
| 6 5 | 
             
                extend ActiveSupport::Concern
         | 
| 7 6 |  | 
| 8 7 | 
             
                include AbstractController::Helpers
         | 
| @@ -14,6 +13,29 @@ module ActionController # :nodoc: | |
| 14 13 | 
             
                end
         | 
| 15 14 |  | 
| 16 15 | 
             
                module ClassMethods
         | 
| 16 | 
            +
                  # Overrides parts of the globally configured Content-Security-Policy
         | 
| 17 | 
            +
                  # header:
         | 
| 18 | 
            +
                  #
         | 
| 19 | 
            +
                  #   class PostsController < ApplicationController
         | 
| 20 | 
            +
                  #     content_security_policy do |policy|
         | 
| 21 | 
            +
                  #       policy.base_uri "https://www.example.com"
         | 
| 22 | 
            +
                  #     end
         | 
| 23 | 
            +
                  #   end
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                  # Options can be passed similar to +before_action+. For example, pass
         | 
| 26 | 
            +
                  # <tt>only: :index</tt> to override the header on the index action only:
         | 
| 27 | 
            +
                  #
         | 
| 28 | 
            +
                  #   class PostsController < ApplicationController
         | 
| 29 | 
            +
                  #     content_security_policy(only: :index) do |policy|
         | 
| 30 | 
            +
                  #       policy.default_src :self, :https
         | 
| 31 | 
            +
                  #     end
         | 
| 32 | 
            +
                  #   end
         | 
| 33 | 
            +
                  #
         | 
| 34 | 
            +
                  # Pass +false+ to remove the Content-Security-Policy header:
         | 
| 35 | 
            +
                  #
         | 
| 36 | 
            +
                  #   class PostsController < ApplicationController
         | 
| 37 | 
            +
                  #     content_security_policy false, only: :index
         | 
| 38 | 
            +
                  #   end
         | 
| 17 39 | 
             
                  def content_security_policy(enabled = true, **options, &block)
         | 
| 18 40 | 
             
                    before_action(options) do
         | 
| 19 41 | 
             
                      if block_given?
         | 
| @@ -28,6 +50,18 @@ module ActionController # :nodoc: | |
| 28 50 | 
             
                    end
         | 
| 29 51 | 
             
                  end
         | 
| 30 52 |  | 
| 53 | 
            +
                  # Overrides the globally configured Content-Security-Policy-Report-Only
         | 
| 54 | 
            +
                  # header:
         | 
| 55 | 
            +
                  #
         | 
| 56 | 
            +
                  #   class PostsController < ApplicationController
         | 
| 57 | 
            +
                  #     content_security_policy_report_only only: :index
         | 
| 58 | 
            +
                  #   end
         | 
| 59 | 
            +
                  #
         | 
| 60 | 
            +
                  # Pass +false+ to remove the Content-Security-Policy-Report-Only header:
         | 
| 61 | 
            +
                  #
         | 
| 62 | 
            +
                  #   class PostsController < ApplicationController
         | 
| 63 | 
            +
                  #     content_security_policy_report_only false, only: :index
         | 
| 64 | 
            +
                  #   end
         | 
| 31 65 | 
             
                  def content_security_policy_report_only(report_only = true, **options)
         | 
| 32 66 | 
             
                    before_action(options) do
         | 
| 33 67 | 
             
                      request.content_security_policy_report_only = report_only
         | 
| @@ -5,9 +5,9 @@ require "active_support/security_utils" | |
| 5 5 | 
             
            require "active_support/core_ext/array/access"
         | 
| 6 6 |  | 
| 7 7 | 
             
            module ActionController
         | 
| 8 | 
            -
              # HTTP Basic, Digest and Token authentication.
         | 
| 8 | 
            +
              # HTTP Basic, Digest, and Token authentication.
         | 
| 9 9 | 
             
              module HttpAuthentication
         | 
| 10 | 
            -
                # HTTP \Basic authentication | 
| 10 | 
            +
                # = HTTP \Basic authentication
         | 
| 11 11 | 
             
                #
         | 
| 12 12 | 
             
                # === Simple \Basic example
         | 
| 13 13 | 
             
                #
         | 
| @@ -70,7 +70,12 @@ module ActionController | |
| 70 70 | 
             
                    extend ActiveSupport::Concern
         | 
| 71 71 |  | 
| 72 72 | 
             
                    module ClassMethods
         | 
| 73 | 
            +
                      # Enables HTTP \Basic authentication.
         | 
| 74 | 
            +
                      #
         | 
| 75 | 
            +
                      # See ActionController::HttpAuthentication::Basic for example usage.
         | 
| 73 76 | 
             
                      def http_basic_authenticate_with(name:, password:, realm: nil, **options)
         | 
| 77 | 
            +
                        raise ArgumentError, "Expected name: to be a String, got #{name.class}" unless name.is_a?(String)
         | 
| 78 | 
            +
                        raise ArgumentError, "Expected password: to be a String, got #{password.class}" unless password.is_a?(String)
         | 
| 74 79 | 
             
                        before_action(options) { http_basic_authenticate_or_request_with name: name, password: password, realm: realm }
         | 
| 75 80 | 
             
                      end
         | 
| 76 81 | 
             
                    end
         | 
| @@ -79,8 +84,8 @@ module ActionController | |
| 79 84 | 
             
                      authenticate_or_request_with_http_basic(realm, message) do |given_name, given_password|
         | 
| 80 85 | 
             
                        # This comparison uses & so that it doesn't short circuit and
         | 
| 81 86 | 
             
                        # uses `secure_compare` so that length information isn't leaked.
         | 
| 82 | 
            -
                        ActiveSupport::SecurityUtils.secure_compare(given_name, name) &
         | 
| 83 | 
            -
                          ActiveSupport::SecurityUtils.secure_compare(given_password, password)
         | 
| 87 | 
            +
                        ActiveSupport::SecurityUtils.secure_compare(given_name.to_s, name) &
         | 
| 88 | 
            +
                          ActiveSupport::SecurityUtils.secure_compare(given_password.to_s, password)
         | 
| 84 89 | 
             
                      end
         | 
| 85 90 | 
             
                    end
         | 
| 86 91 |  | 
| @@ -104,7 +109,7 @@ module ActionController | |
| 104 109 | 
             
                  end
         | 
| 105 110 |  | 
| 106 111 | 
             
                  def has_basic_credentials?(request)
         | 
| 107 | 
            -
                    request.authorization.present? && (auth_scheme(request).downcase == "basic") | 
| 112 | 
            +
                    request.authorization.present? && (auth_scheme(request).downcase == "basic")
         | 
| 108 113 | 
             
                  end
         | 
| 109 114 |  | 
| 110 115 | 
             
                  def user_name_and_password(request)
         | 
| @@ -135,7 +140,7 @@ module ActionController | |
| 135 140 | 
             
                  end
         | 
| 136 141 | 
             
                end
         | 
| 137 142 |  | 
| 138 | 
            -
                # HTTP \Digest authentication | 
| 143 | 
            +
                # = HTTP \Digest authentication
         | 
| 139 144 | 
             
                #
         | 
| 140 145 | 
             
                # === Simple \Digest example
         | 
| 141 146 | 
             
                #
         | 
| @@ -181,22 +186,28 @@ module ActionController | |
| 181 186 | 
             
                  extend self
         | 
| 182 187 |  | 
| 183 188 | 
             
                  module ControllerMethods
         | 
| 189 | 
            +
                    # Authenticate using an HTTP \Digest, or otherwise render an HTTP header
         | 
| 190 | 
            +
                    # requesting the client to send a \Digest.
         | 
| 191 | 
            +
                    #
         | 
| 192 | 
            +
                    # See ActionController::HttpAuthentication::Digest for example usage.
         | 
| 184 193 | 
             
                    def authenticate_or_request_with_http_digest(realm = "Application", message = nil, &password_procedure)
         | 
| 185 194 | 
             
                      authenticate_with_http_digest(realm, &password_procedure) || request_http_digest_authentication(realm, message)
         | 
| 186 195 | 
             
                    end
         | 
| 187 196 |  | 
| 188 | 
            -
                    # Authenticate  | 
| 197 | 
            +
                    # Authenticate using an HTTP \Digest. Returns true if authentication is
         | 
| 198 | 
            +
                    # successful, false otherwise.
         | 
| 189 199 | 
             
                    def authenticate_with_http_digest(realm = "Application", &password_procedure)
         | 
| 190 200 | 
             
                      HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
         | 
| 191 201 | 
             
                    end
         | 
| 192 202 |  | 
| 193 | 
            -
                    # Render  | 
| 203 | 
            +
                    # Render an HTTP header requesting the client to send a \Digest for
         | 
| 204 | 
            +
                    # authentication.
         | 
| 194 205 | 
             
                    def request_http_digest_authentication(realm = "Application", message = nil)
         | 
| 195 206 | 
             
                      HttpAuthentication::Digest.authentication_request(self, realm, message)
         | 
| 196 207 | 
             
                    end
         | 
| 197 208 | 
             
                  end
         | 
| 198 209 |  | 
| 199 | 
            -
                  # Returns false on a valid response, true otherwise
         | 
| 210 | 
            +
                  # Returns false on a valid response, true otherwise.
         | 
| 200 211 | 
             
                  def authenticate(request, realm, &password_procedure)
         | 
| 201 212 | 
             
                    request.authorization && validate_digest_response(request, realm, &password_procedure)
         | 
| 202 213 | 
             
                  end
         | 
| @@ -301,7 +312,7 @@ module ActionController | |
| 301 312 | 
             
                  #
         | 
| 302 313 | 
             
                  # An implementation might choose not to accept a previously used nonce or a previously used digest, in order to
         | 
| 303 314 | 
             
                  # protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for
         | 
| 304 | 
            -
                  # POST, PUT, or PATCH requests and a time-stamp for GET requests. For more details on the issues involved see Section 4
         | 
| 315 | 
            +
                  # POST, PUT, or PATCH requests, and a time-stamp for GET requests. For more details on the issues involved see Section 4
         | 
| 305 316 | 
             
                  # of this document.
         | 
| 306 317 | 
             
                  #
         | 
| 307 318 | 
             
                  # The nonce is opaque to the client. Composed of Time, and hash of Time with secret
         | 
| @@ -331,9 +342,9 @@ module ActionController | |
| 331 342 | 
             
                  end
         | 
| 332 343 | 
             
                end
         | 
| 333 344 |  | 
| 334 | 
            -
                # HTTP Token authentication | 
| 345 | 
            +
                # = HTTP \Token authentication
         | 
| 335 346 | 
             
                #
         | 
| 336 | 
            -
                # Simple Token example | 
| 347 | 
            +
                # === Simple \Token example
         | 
| 337 348 | 
             
                #
         | 
| 338 349 | 
             
                #   class PostsController < ApplicationController
         | 
| 339 350 | 
             
                #     TOKEN = "secret"
         | 
| @@ -412,14 +423,22 @@ module ActionController | |
| 412 423 | 
             
                  extend self
         | 
| 413 424 |  | 
| 414 425 | 
             
                  module ControllerMethods
         | 
| 426 | 
            +
                    # Authenticate using an HTTP Bearer token, or otherwise render an HTTP
         | 
| 427 | 
            +
                    # header requesting the client to send a Bearer token.
         | 
| 428 | 
            +
                    #
         | 
| 429 | 
            +
                    # See ActionController::HttpAuthentication::Token for example usage.
         | 
| 415 430 | 
             
                    def authenticate_or_request_with_http_token(realm = "Application", message = nil, &login_procedure)
         | 
| 416 431 | 
             
                      authenticate_with_http_token(&login_procedure) || request_http_token_authentication(realm, message)
         | 
| 417 432 | 
             
                    end
         | 
| 418 433 |  | 
| 434 | 
            +
                    # Authenticate using an HTTP Bearer token. Returns true if
         | 
| 435 | 
            +
                    # authentication is successful, false otherwise.
         | 
| 419 436 | 
             
                    def authenticate_with_http_token(&login_procedure)
         | 
| 420 437 | 
             
                      Token.authenticate(self, &login_procedure)
         | 
| 421 438 | 
             
                    end
         | 
| 422 439 |  | 
| 440 | 
            +
                    # Render an HTTP header requesting the client to send a Bearer token for
         | 
| 441 | 
            +
                    # authentication.
         | 
| 423 442 | 
             
                    def request_http_token_authentication(realm = "Application", message = nil)
         | 
| 424 443 | 
             
                      Token.authentication_request(self, realm, message)
         | 
| 425 444 | 
             
                    end
         | 
| @@ -428,17 +447,17 @@ module ActionController | |
| 428 447 | 
             
                  # If token Authorization header is present, call the login
         | 
| 429 448 | 
             
                  # procedure with the present token and options.
         | 
| 430 449 | 
             
                  #
         | 
| 431 | 
            -
                  #  | 
| 432 | 
            -
                  # | 
| 450 | 
            +
                  # Returns the return value of <tt>login_procedure</tt> if a
         | 
| 451 | 
            +
                  # token is found. Returns <tt>nil</tt> if no token is found.
         | 
| 452 | 
            +
                  #
         | 
| 453 | 
            +
                  # ==== Parameters
         | 
| 433 454 | 
             
                  #
         | 
| 434 | 
            -
                  #  | 
| 435 | 
            -
                  # | 
| 455 | 
            +
                  # * +controller+ - ActionController::Base instance for the current request.
         | 
| 456 | 
            +
                  # * +login_procedure+ - Proc to call if a token is present. The Proc
         | 
| 457 | 
            +
                  #   should take two arguments:
         | 
| 436 458 | 
             
                  #
         | 
| 437 459 | 
             
                  #     authenticate(controller) { |token, options| ... }
         | 
| 438 460 | 
             
                  #
         | 
| 439 | 
            -
                  # Returns the return value of <tt>login_procedure</tt> if a
         | 
| 440 | 
            -
                  # token is found. Returns <tt>nil</tt> if no token is found.
         | 
| 441 | 
            -
             | 
| 442 461 | 
             
                  def authenticate(controller, &login_procedure)
         | 
| 443 462 | 
             
                    token, options = token_and_options(controller.request)
         | 
| 444 463 | 
             
                    unless token.blank?
         | 
| @@ -449,14 +468,18 @@ module ActionController | |
| 449 468 | 
             
                  # Parses the token and options out of the token Authorization header.
         | 
| 450 469 | 
             
                  # The value for the Authorization header is expected to have the prefix
         | 
| 451 470 | 
             
                  # <tt>"Token"</tt> or <tt>"Bearer"</tt>. If the header looks like this:
         | 
| 471 | 
            +
                  #
         | 
| 452 472 | 
             
                  #   Authorization: Token token="abc", nonce="def"
         | 
| 453 | 
            -
                  # Then the returned token is <tt>"abc"</tt>, and the options are
         | 
| 454 | 
            -
                  # <tt>{nonce: "def"}</tt>
         | 
| 455 473 | 
             
                  #
         | 
| 456 | 
            -
                  #  | 
| 474 | 
            +
                  # Then the returned token is <tt>"abc"</tt>, and the options are
         | 
| 475 | 
            +
                  # <tt>{nonce: "def"}</tt>.
         | 
| 457 476 | 
             
                  #
         | 
| 458 477 | 
             
                  # Returns an +Array+ of <tt>[String, Hash]</tt> if a token is present.
         | 
| 459 478 | 
             
                  # Returns +nil+ if no token is found.
         | 
| 479 | 
            +
                  #
         | 
| 480 | 
            +
                  # ==== Parameters
         | 
| 481 | 
            +
                  #
         | 
| 482 | 
            +
                  # * +request+ - ActionDispatch::Request instance with the current headers.
         | 
| 460 483 | 
             
                  def token_and_options(request)
         | 
| 461 484 | 
             
                    authorization_request = request.authorization.to_s
         | 
| 462 485 | 
             
                    if authorization_request[TOKEN_REGEX]
         | 
| @@ -469,7 +492,7 @@ module ActionController | |
| 469 492 | 
             
                    rewrite_param_values params_array_from raw_params auth
         | 
| 470 493 | 
             
                  end
         | 
| 471 494 |  | 
| 472 | 
            -
                  # Takes raw_params and turns it into an array of parameters
         | 
| 495 | 
            +
                  # Takes +raw_params+ and turns it into an array of parameters.
         | 
| 473 496 | 
             
                  def params_array_from(raw_params)
         | 
| 474 497 | 
             
                    raw_params.map { |param| param.split %r/=(.+)?/ }
         | 
| 475 498 | 
             
                  end
         | 
| @@ -494,10 +517,12 @@ module ActionController | |
| 494 517 |  | 
| 495 518 | 
             
                  # Encodes the given token and options into an Authorization header value.
         | 
| 496 519 | 
             
                  #
         | 
| 497 | 
            -
                  # token   - String token.
         | 
| 498 | 
            -
                  # options - optional Hash of the options.
         | 
| 499 | 
            -
                  #
         | 
| 500 520 | 
             
                  # Returns String.
         | 
| 521 | 
            +
                  #
         | 
| 522 | 
            +
                  # ==== Parameters
         | 
| 523 | 
            +
                  #
         | 
| 524 | 
            +
                  # * +token+ - String token.
         | 
| 525 | 
            +
                  # * +options+ - Optional Hash of the options.
         | 
| 501 526 | 
             
                  def encode_credentials(token, options = {})
         | 
| 502 527 | 
             
                    values = ["#{TOKEN_KEY}#{token.to_s.inspect}"] + options.map do |key, value|
         | 
| 503 528 | 
             
                      "#{key}=#{value.to_s.inspect}"
         | 
| @@ -507,10 +532,12 @@ module ActionController | |
| 507 532 |  | 
| 508 533 | 
             
                  # Sets a WWW-Authenticate header to let the client know a token is desired.
         | 
| 509 534 | 
             
                  #
         | 
| 510 | 
            -
                  # controller - ActionController::Base instance for the outgoing response.
         | 
| 511 | 
            -
                  # realm      - String realm to use in the header.
         | 
| 512 | 
            -
                  #
         | 
| 513 535 | 
             
                  # Returns nothing.
         | 
| 536 | 
            +
                  #
         | 
| 537 | 
            +
                  # ==== Parameters
         | 
| 538 | 
            +
                  #
         | 
| 539 | 
            +
                  # * +controller+ - ActionController::Base instance for the outgoing response.
         | 
| 540 | 
            +
                  # * +realm+ - String realm to use in the header.
         | 
| 514 541 | 
             
                  def authentication_request(controller, realm, message = nil)
         | 
| 515 542 | 
             
                    message ||= "HTTP Token: Access denied.\n"
         | 
| 516 543 | 
             
                    controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.tr('"', "")}")
         | 
| @@ -261,6 +261,7 @@ module ActionController | |
| 261 261 | 
             
                      # Since we're processing the view in a different thread, copy the
         | 
| 262 262 | 
             
                      # thread locals from the main thread to the child thread. :'(
         | 
| 263 263 | 
             
                      locals.each { |k, v| t2[k] = v }
         | 
| 264 | 
            +
                      ActiveSupport::IsolatedExecutionState.share_with(t1)
         | 
| 264 265 |  | 
| 265 266 | 
             
                      begin
         | 
| 266 267 | 
             
                        super(name)
         | 
| @@ -1,37 +1,28 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            module ActionController # :nodoc:
         | 
| 4 | 
            -
              # HTTP Permissions Policy is a web standard for defining a mechanism to
         | 
| 5 | 
            -
              # allow and deny the use of browser permissions in its own context, and
         | 
| 6 | 
            -
              # in content within any <iframe> elements in the document.
         | 
| 7 | 
            -
              #
         | 
| 8 | 
            -
              # Full details of HTTP Permissions Policy specification and guidelines can
         | 
| 9 | 
            -
              # be found at MDN:
         | 
| 10 | 
            -
              #
         | 
| 11 | 
            -
              # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
         | 
| 12 | 
            -
              #
         | 
| 13 | 
            -
              # Examples of usage:
         | 
| 14 | 
            -
              #
         | 
| 15 | 
            -
              #   # Global policy
         | 
| 16 | 
            -
              #   Rails.application.config.permissions_policy do |f|
         | 
| 17 | 
            -
              #     f.camera      :none
         | 
| 18 | 
            -
              #     f.gyroscope   :none
         | 
| 19 | 
            -
              #     f.microphone  :none
         | 
| 20 | 
            -
              #     f.usb         :none
         | 
| 21 | 
            -
              #     f.fullscreen  :self
         | 
| 22 | 
            -
              #     f.payment     :self, "https://secure.example.com"
         | 
| 23 | 
            -
              #   end
         | 
| 24 | 
            -
              #
         | 
| 25 | 
            -
              #   # Controller level policy
         | 
| 26 | 
            -
              #   class PagesController < ApplicationController
         | 
| 27 | 
            -
              #     permissions_policy do |p|
         | 
| 28 | 
            -
              #       p.geolocation "https://example.com"
         | 
| 29 | 
            -
              #     end
         | 
| 30 | 
            -
              #   end
         | 
| 31 4 | 
             
              module PermissionsPolicy
         | 
| 32 5 | 
             
                extend ActiveSupport::Concern
         | 
| 33 6 |  | 
| 34 7 | 
             
                module ClassMethods
         | 
| 8 | 
            +
                  # Overrides parts of the globally configured Feature-Policy
         | 
| 9 | 
            +
                  # header:
         | 
| 10 | 
            +
                  #
         | 
| 11 | 
            +
                  #   class PagesController < ApplicationController
         | 
| 12 | 
            +
                  #     permissions_policy do |policy|
         | 
| 13 | 
            +
                  #       policy.geolocation "https://example.com"
         | 
| 14 | 
            +
                  #     end
         | 
| 15 | 
            +
                  #   end
         | 
| 16 | 
            +
                  #
         | 
| 17 | 
            +
                  # Options can be passed similar to +before_action+. For example, pass
         | 
| 18 | 
            +
                  # <tt>only: :index</tt> to override the header on the index action only:
         | 
| 19 | 
            +
                  #
         | 
| 20 | 
            +
                  #   class PagesController < ApplicationController
         | 
| 21 | 
            +
                  #     permissions_policy(only: :index) do |policy|
         | 
| 22 | 
            +
                  #       policy.camera :self
         | 
| 23 | 
            +
                  #     end
         | 
| 24 | 
            +
                  #   end
         | 
| 25 | 
            +
                  #
         | 
| 35 26 | 
             
                  def permissions_policy(**options, &block)
         | 
| 36 27 | 
             
                    before_action(options) do
         | 
| 37 28 | 
             
                      if block_given?
         | 
| @@ -74,7 +74,7 @@ module ActionController | |
| 74 74 | 
             
                #
         | 
| 75 75 | 
             
                # Raises UnsafeRedirectError in the case of an unsafe redirect.
         | 
| 76 76 | 
             
                #
         | 
| 77 | 
            -
                # To allow any external redirects pass  | 
| 77 | 
            +
                # To allow any external redirects pass <tt>allow_other_host: true</tt>, though using a user-provided param in that case is unsafe.
         | 
| 78 78 | 
             
                #
         | 
| 79 79 | 
             
                #   redirect_to "https://rubyonrails.org", allow_other_host: true
         | 
| 80 80 | 
             
                #
         | 
| @@ -117,7 +117,7 @@ module ActionController | |
| 117 117 | 
             
                # * <tt>:allow_other_host</tt> - Allow or disallow redirection to the host that is different to the current host, defaults to true.
         | 
| 118 118 | 
             
                #
         | 
| 119 119 | 
             
                # All other options that can be passed to #redirect_to are accepted as
         | 
| 120 | 
            -
                # options and the behavior is identical.
         | 
| 120 | 
            +
                # options, and the behavior is identical.
         | 
| 121 121 | 
             
                def redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options)
         | 
| 122 122 | 
             
                  if request.referer && (allow_other_host || _url_host_allowed?(request.referer))
         | 
| 123 123 | 
             
                    redirect_to request.referer, allow_other_host: allow_other_host, **options
         | 
| @@ -195,7 +195,8 @@ module ActionController | |
| 195 195 | 
             
                  end
         | 
| 196 196 |  | 
| 197 197 | 
             
                  def _url_host_allowed?(url)
         | 
| 198 | 
            -
                    URI(url.to_s).host | 
| 198 | 
            +
                    host = URI(url.to_s).host
         | 
| 199 | 
            +
                    host == request.host || host.nil? && url.to_s.start_with?("/")
         | 
| 199 200 | 
             
                  rescue ArgumentError, URI::Error
         | 
| 200 201 | 
             
                    false
         | 
| 201 202 | 
             
                  end
         |