Re-add session errors (preparation for merge) (#395)
Raise helpful errors from Hanami::Action#flash and Hanami::Action#session when sessions are not enabled.
This commit is contained in:
parent
24ee339323
commit
e47fe2484e
|
@ -24,6 +24,7 @@ require_relative "action/mime"
|
|||
require_relative "action/rack/file"
|
||||
require_relative "action/request"
|
||||
require_relative "action/response"
|
||||
require_relative "action/error"
|
||||
|
||||
module Hanami
|
||||
# An HTTP endpoint
|
||||
|
@ -318,13 +319,14 @@ module Hanami
|
|||
|
||||
halted = catch :halt do
|
||||
params = self.class.params_class.new(env)
|
||||
request = build_request(env, params)
|
||||
request = build_request(env: env, params: params, sessions_enabled: sessions_enabled?)
|
||||
response = build_response(
|
||||
request: request,
|
||||
config: config,
|
||||
content_type: Mime.calculate_content_type_with_charset(config, request, config.accepted_mime_types),
|
||||
env: env,
|
||||
headers: config.default_headers
|
||||
headers: config.default_headers,
|
||||
sessions_enabled: sessions_enabled?
|
||||
)
|
||||
|
||||
enforce_accepted_mime_types(request)
|
||||
|
@ -430,10 +432,17 @@ module Hanami
|
|||
nil
|
||||
end
|
||||
|
||||
# @see Session#sessions_enabled?
|
||||
# @since 2.0.0
|
||||
# @api private
|
||||
def build_request(env, params)
|
||||
Request.new(env, params)
|
||||
def sessions_enabled?
|
||||
false
|
||||
end
|
||||
|
||||
# @since 2.0.0
|
||||
# @api private
|
||||
def build_request(**options)
|
||||
Request.new(**options)
|
||||
end
|
||||
|
||||
# @since 2.0.0
|
||||
|
|
|
@ -96,6 +96,7 @@ module Hanami
|
|||
# @api private
|
||||
def self.included(action)
|
||||
unless Hanami.respond_to?(:env?) && Hanami.env?(:test)
|
||||
action.include Hanami::Action::Session
|
||||
action.class_eval do
|
||||
before :set_csrf_token, :verify_csrf_token
|
||||
end
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Hanami
|
||||
class Action
|
||||
# @since 2.0.0
|
||||
class Error < ::StandardError
|
||||
end
|
||||
|
||||
# Missing session error
|
||||
#
|
||||
# This error is raised when `session` or `flash` is accessed/set on request/response objects
|
||||
# in actions which do not include `Hanami::Action::Session`.
|
||||
#
|
||||
# @since 2.0.0
|
||||
#
|
||||
# @see Hanami::Action::Session
|
||||
# @see Hanami::Action::Request#session
|
||||
# @see Hanami::Action::Response#session
|
||||
# @see Hanami::Action::Response#flash
|
||||
class MissingSessionError < Error
|
||||
def initialize(session_method)
|
||||
super(<<~TEXT)
|
||||
Sessions are not enabled. To use `#{session_method}`:
|
||||
|
||||
Configure sessions in your Hanami app, e.g.
|
||||
|
||||
module MyApp
|
||||
class App < Hanami::App
|
||||
# See Rack::Session::Cookie for options
|
||||
config.sessions = :cookie, {**cookie_session_options}
|
||||
end
|
||||
end
|
||||
|
||||
Or include session support directly in your action class:
|
||||
|
||||
include Hanami::Action::Session
|
||||
TEXT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,9 +16,11 @@ module Hanami
|
|||
class Request < ::Rack::Request
|
||||
attr_reader :params
|
||||
|
||||
def initialize(env, params)
|
||||
def initialize(env:, params:, sessions_enabled: false)
|
||||
super(env)
|
||||
|
||||
@params = params
|
||||
@sessions_enabled = sessions_enabled
|
||||
end
|
||||
|
||||
def id
|
||||
|
@ -36,6 +38,14 @@ module Hanami
|
|||
accept != Action::DEFAULT_ACCEPT
|
||||
end
|
||||
|
||||
def session
|
||||
unless @sessions_enabled
|
||||
raise Hanami::Action::MissingSessionError.new("Hanami::Action::Request#session")
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# @since 0.1.0
|
||||
# @api private
|
||||
def accept
|
||||
|
|
|
@ -45,7 +45,7 @@ module Hanami
|
|||
|
||||
# @since 2.0.0
|
||||
# @api private
|
||||
def initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil) # rubocop:disable Metrics/ParameterLists
|
||||
def initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil, sessions_enabled: false) # rubocop:disable Layout/LineLength, Metrics/ParameterLists
|
||||
super([], 200, headers.dup)
|
||||
set_header(Action::CONTENT_TYPE, content_type)
|
||||
|
||||
|
@ -56,6 +56,7 @@ module Hanami
|
|||
@env = env
|
||||
@view_options = view_options || DEFAULT_VIEW_OPTIONS
|
||||
|
||||
@sessions_enabled = sessions_enabled
|
||||
@sending_file = false
|
||||
end
|
||||
|
||||
|
@ -102,6 +103,10 @@ module Hanami
|
|||
# @since 2.0.0
|
||||
# @api public
|
||||
def session
|
||||
unless @sessions_enabled
|
||||
raise Hanami::Action::MissingSessionError.new("Hanami::Action::Response#session")
|
||||
end
|
||||
|
||||
env[Action::RACK_SESSION] ||= {}
|
||||
end
|
||||
|
||||
|
@ -114,6 +119,10 @@ module Hanami
|
|||
# @since 2.0.0
|
||||
# @api public
|
||||
def flash
|
||||
unless @sessions_enabled
|
||||
raise Hanami::Action::MissingSessionError.new("Hanami::Action::Response#flash")
|
||||
end
|
||||
|
||||
@flash ||= Flash.new(session[Flash::KEY])
|
||||
end
|
||||
|
||||
|
@ -179,7 +188,8 @@ module Hanami
|
|||
def request_id
|
||||
env.fetch(Action::REQUEST_ID) do
|
||||
# FIXME: raise a meaningful error, by inviting devs to include Hanami::Action::Session
|
||||
raise "Can't find request ID"
|
||||
# raise "Can't find request ID"
|
||||
raise Hanami::Action::MissingSessionError.new("request_id")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ module Hanami
|
|||
|
||||
private
|
||||
|
||||
def sessions_enabled?
|
||||
true
|
||||
end
|
||||
|
||||
# Finalize the response
|
||||
#
|
||||
# @return [void]
|
||||
|
|
|
@ -41,4 +41,13 @@ RSpec.describe "Flash application" do
|
|||
expect(last_response.body).to match(/flash_map: \[\[:hello, "world"\]\]/)
|
||||
end
|
||||
end
|
||||
|
||||
context "when sessions not enabled" do
|
||||
it "raises Hanami::Action::MissingSessionError" do
|
||||
expect { get "/disabled" }.to raise_error(
|
||||
Hanami::Action::MissingSessionError,
|
||||
/Hanami::Action::Response#flash/
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,6 +12,7 @@ RSpec.describe "HTTP sessions" do
|
|||
get "/", to: Dashboard::Index.new
|
||||
post "/login", to: Sessions::Create.new
|
||||
delete "/logout", to: Sessions::Destroy.new
|
||||
get "/disabled", to: Sessions::Disabled.new
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -52,6 +53,13 @@ RSpec.describe "HTTP sessions" do
|
|||
get "/"
|
||||
expect(response.status).to be(401)
|
||||
end
|
||||
|
||||
context "when sessions not enabled" do
|
||||
it "raises Hanami::Action::MissingSessionError" do
|
||||
expected = Hanami::Action::MissingSessionError
|
||||
expect { get "/disabled" }.to raise_error(expected, /Hanami::Action::Response#session/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe "HTTP Standalone Sessions" do
|
||||
|
|
|
@ -347,15 +347,21 @@ class YieldAfterBlockAction < AfterBlockAction
|
|||
end
|
||||
end
|
||||
|
||||
class MissingSessionAction < Hanami::Action
|
||||
def handle(*)
|
||||
session
|
||||
class MissingRequestSessionAction < Hanami::Action
|
||||
def handle(req, _)
|
||||
req.session[:user_id]
|
||||
end
|
||||
end
|
||||
|
||||
class MissingFlashAction < Hanami::Action
|
||||
def handle(*)
|
||||
flash
|
||||
class MissingResponseSessionAction < Hanami::Action
|
||||
def handle(_, res)
|
||||
res.session[:user_id] = 23
|
||||
end
|
||||
end
|
||||
|
||||
class MissingResponseFlashAction < Hanami::Action
|
||||
def handle(_, res)
|
||||
res.flash[:error] = "ouch"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -854,6 +860,12 @@ module Sessions
|
|||
res.session[:user_id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
class Disabled < Hanami::Action
|
||||
def handle(*, res)
|
||||
res.session[:user_id] = 23
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class StandaloneSession < Hanami::Action
|
||||
|
@ -1803,6 +1815,12 @@ module Flash
|
|||
res.body = "flash_map: #{res.flash.map { |type, message| [type, message] }}"
|
||||
end
|
||||
end
|
||||
|
||||
class Disabled < Hanami::Action
|
||||
def handle(_, res)
|
||||
res.flash[:error] = "ouch"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1817,6 +1835,7 @@ module Flash
|
|||
get "/each_redirect", to: Flash::Controllers::Home::EachRedirect.new
|
||||
get "/map", to: Flash::Controllers::Home::Map.new
|
||||
get "/each", to: Flash::Controllers::Home::Each.new
|
||||
get "/disabled", to: Flash::Controllers::Home::Disabled.new
|
||||
end
|
||||
|
||||
@middleware = Rack::Builder.new do
|
||||
|
|
|
@ -63,7 +63,10 @@ RSpec.describe Hanami::Action::Request do
|
|||
|
||||
context "non-standard port" do
|
||||
it "gets host and port" do
|
||||
request = described_class.new(Rack::MockRequest.env_for("http://example.com:81/foo?q=bar", {}), {})
|
||||
request = described_class.new(
|
||||
env: Rack::MockRequest.env_for("http://example.com:81/foo?q=bar", {}),
|
||||
params: {}
|
||||
)
|
||||
expect(request.host_with_port).to eq("example.com:81")
|
||||
end
|
||||
end
|
||||
|
@ -155,6 +158,6 @@ RSpec.describe Hanami::Action::Request do
|
|||
def build_request(attributes = {})
|
||||
url = attributes.delete("url") || "http://example.com/foo?q=bar"
|
||||
env = Rack::MockRequest.env_for(url, attributes)
|
||||
described_class.new(env, {})
|
||||
described_class.new(env: env, params: {})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -77,6 +77,36 @@ RSpec.describe Hanami::Action do
|
|||
expect(response.body).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context "when setting res.session with sessions disabled" do
|
||||
it "raises an informative exception" do
|
||||
expected = Hanami::Action::MissingSessionError
|
||||
expect { MissingResponseSessionAction.new.call({}) }.to raise_error(
|
||||
expected,
|
||||
/Hanami::Action::Response#session/
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when setting res.flash with sessions disabled" do
|
||||
it "raises an informative exception" do
|
||||
expected = Hanami::Action::MissingSessionError
|
||||
expect { MissingResponseFlashAction.new.call({}) }.to raise_error(
|
||||
expected,
|
||||
/Hanami::Action::Response#flash/
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when accessing req.session with sessions disabled" do
|
||||
it "raises an informative exception" do
|
||||
expected = Hanami::Action::MissingSessionError
|
||||
expect { MissingRequestSessionAction.new.call({}) }.to raise_error(
|
||||
expected,
|
||||
/Hanami::Action::Request#session/
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "request" do
|
||||
|
|
Loading…
Reference in New Issue