hanami-controller 2.3.0.beta2 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 194fc2615c1034ce507513f72e4f218a45fafe60ad53823e0b04e07cae0469f6
4
- data.tar.gz: fff5370bd197844f24e83d88490a950fac8cb44c1683c489da94cbb8b5d92402
3
+ metadata.gz: 8fe7ba06a133967bb3119f5a4cacd11507d7e0b658dc446088bbb5fbe5f6e109
4
+ data.tar.gz: e86ac135385c01b1da0c9d5c87a461dbc743812ab2b1f0bc44ba347cc7685453
5
5
  SHA512:
6
- metadata.gz: f61ceab1aba8a83b459e1c07698802f45fc27f5852454578a4cb135cf520bcf6c12a9a70ae90763dbdb0f1e0dde927da3eb67f071045344c44bb32bc86c8981a
7
- data.tar.gz: f2d5905a9d93d09b4a328dbc27d564226293f89a54bb23155b5bd2ececfece6fe768a58d9e3473a228659e790c83018ee90b9f0b1ce1d783bba82679351abc1c
6
+ metadata.gz: 74acf00dfb30458595a50e87cb3544be5c181941ac4e94be1e89fc70b02132ec0b41947fb827ee9706a1a1d88f2206f8ce6d0c9eccf50c39ce0a22017f04940b
7
+ data.tar.gz: 283d12b473fac98a5538ef116ac9b7ccc3174d1abeff2c5054a45033a8219f7d0d9c857891221ec93a15b2b54bd4e781b498bcdefc0c7872f3ca2b717cbbe958
data/CHANGELOG.md CHANGED
@@ -2,6 +2,65 @@
2
2
 
3
3
  Complete, fast and testable actions for Rack
4
4
 
5
+ ## [Unreleased]
6
+
7
+ ### Added
8
+
9
+ ### Changed
10
+
11
+ ### Deprecated
12
+
13
+ ### Removed
14
+
15
+ ### Fixed
16
+
17
+ ### Security
18
+
19
+ [Unreleased]: https://github.com/hanami/hanami-controller/compare/v2.3.1...main
20
+
21
+ ## [2.3.1] - 2025-12-06
22
+
23
+ ### Fixed
24
+
25
+ - Allow `handle_exception` to receive multiple class names as strings. (@sidane in #495)
26
+
27
+ ```ruby
28
+ class MyAction < Hanami::Action
29
+ config.handle_exception(
30
+ "MyException" => 500,
31
+ "MyOtherException" => 501
32
+ )
33
+ end
34
+ ```
35
+
36
+ [2.3.1]: https://github.com/hanami/hanami-controller/compare/v2.3.0...v2.3.1
37
+
38
+ ## v2.3.0 - 2025-11-12
39
+
40
+ ### Added
41
+
42
+ - Fetch CSRF tokens from `X-CSRF-Token` request header, in addition to body params. (@masterT in #422)
43
+
44
+ ### Changed
45
+
46
+ - Allow `config.handle_exception` to receive an exception class name as a string. (@mathewdbutton in #488)
47
+
48
+ This allows you to handle exceptions in your actions without having to require the Ruby files that define the exception constants, which is often awkward if those exceptions come from far-removed layers of your app.
49
+
50
+ ```ruby
51
+ class MyAction < Hanami::Action
52
+ config.handle_exception "ROM::TupleCountMismatchError" => 404
53
+ end
54
+ ```
55
+ - Allow both `:unprocessable_entity` and `:unprocessable_content` and to be used to refer to the 422 HTTP status code (Rack v3 dropped the former and replaced it with the latter). (@alassek in #490)
56
+
57
+ ```ruby
58
+ def handle(request, response)
59
+ # Or :unprocessable_content, both work, on all Rack versions
60
+ response.status = :unprocessable_entity
61
+ end
62
+ ```
63
+
5
64
  ## v2.3.0.beta2 - 2025-10-17
6
65
 
7
66
  ### Added
data/README.md CHANGED
@@ -5,9 +5,8 @@ Complete, fast, and testable actions for Rack and [Hanami](http://hanamirb.org)
5
5
  ## Status
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/hanami-controller.svg)](https://badge.fury.io/rb/hanami-controller)
8
- [![CI](https://github.com/hanami/controller/actions/workflows/ci.yml/badge.svg)](https://github.com/hanami/controller/actions?query=workflow%3Aci+branch%3Amain)
9
- [![Test Coverage](https://codecov.io/gh/hanami/controller/branch/main/graph/badge.svg)](https://codecov.io/gh/hanami/controller)
10
- [![Depfu](https://badges.depfu.com/badges/7cd17419fba78b726be1353118fb01de/overview.svg)](https://depfu.com/github/hanami/controller?project=Bundler)
8
+ [![CI](https://github.com/hanami/hanami-controller/actions/workflows/ci.yml/badge.svg)](https://github.com/hanami/hanami-controller/actions?query=workflow%3Aci+branch%3Amain)
9
+ [![Test Coverage](https://codecov.io/gh/hanami/hanami-controller/branch/main/graph/badge.svg)](https://codecov.io/gh/hanami/hanami-controller)
11
10
 
12
11
  ## Contact
13
12
 
@@ -21,8 +20,6 @@ Complete, fast, and testable actions for Rack and [Hanami](http://hanamirb.org)
21
20
 
22
21
  ## Installation
23
22
 
24
- __Hanami::Controller__ supports Ruby (MRI) 3.1+
25
-
26
23
  Add this line to your application's Gemfile:
27
24
 
28
25
  ```ruby
@@ -7,8 +7,8 @@ require "hanami/controller/version"
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = "hanami-controller"
9
9
  spec.version = Hanami::Controller::VERSION
10
- spec.authors = ["Luca Guidi"]
11
- spec.email = ["me@lucaguidi.com"]
10
+ spec.authors = ["Hanakai team"]
11
+ spec.email = ["info@hanakai.org"]
12
12
  spec.description = "Complete, fast and testable actions for Rack"
13
13
  spec.summary = "Complete, fast and testable actions for Rack and Hanami"
14
14
  spec.homepage = "http://hanamirb.org"
@@ -21,12 +21,11 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = ">= 3.2"
22
22
 
23
23
  spec.add_dependency "rack", ">= 2.1"
24
- spec.add_dependency "hanami-utils", "~> 2.3.0.beta1"
24
+ spec.add_dependency "hanami-utils", "~> 2.3.0"
25
25
  spec.add_dependency "dry-configurable", "~> 1.0", "< 2"
26
26
  spec.add_dependency "dry-core", "~> 1.0"
27
27
  spec.add_dependency "zeitwerk", "~> 2.6"
28
28
 
29
- spec.add_development_dependency "bundler", ">= 1.6", "< 3"
30
29
  spec.add_development_dependency "rack-test", "~> 2.0"
31
30
  spec.add_development_dependency "rake", "~> 13"
32
31
  spec.add_development_dependency "rspec", "~> 3.9"
@@ -54,7 +54,11 @@ module Hanami
54
54
  def handle_exception(exceptions)
55
55
  self.handled_exceptions = handled_exceptions
56
56
  .merge(exceptions)
57
- .sort { |(ex1, _), (ex2, _)| ex1.ancestors.include?(ex2) ? -1 : 1 }
57
+ .sort do |(ex1, _), (ex2, _)|
58
+ next 0 if [ex1, ex2].any?(String)
59
+
60
+ ex1.ancestors.include?(ex2) ? -1 : 1
61
+ end
58
62
  .to_h
59
63
  end
60
64
 
@@ -13,10 +13,11 @@ module Hanami
13
13
  # This security mechanism is enabled automatically if sessions are turned on.
14
14
  #
15
15
  # It stores a "challenge" token in session. For each "state changing request"
16
- # (eg. <tt>POST</tt>, <tt>PATCH</tt> etc..), we should send a special param:
17
- # <tt>_csrf_token</tt>.
16
+ # (eg. <tt>POST</tt>, <tt>PATCH</tt> etc..), we should send a special param
17
+ # <tt>_csrf_token</tt> or header <tt>X-CSRF-Token</tt> which contain the "challenge"
18
+ # token.
18
19
  #
19
- # If the param matches with the challenge token, the flow can continue.
20
+ # If the request token matches with the challenge token, the flow can continue.
20
21
  # Otherwise the application detects an attack attempt, it reset the session
21
22
  # and <tt>Hanami::Action::InvalidCSRFTokenError</tt> is raised.
22
23
  #
@@ -107,6 +108,16 @@ module Hanami
107
108
  res.session[CSRF_TOKEN] ||= generate_csrf_token
108
109
  end
109
110
 
111
+ # Get CSRF Token in request.
112
+ #
113
+ # Retreives the CSRF token from the request param <tt>_csrf_token</tt> or the request header
114
+ # <tt>X-CSRF-Token</tt>.
115
+ #
116
+ # @api private
117
+ def request_csrf_token(req)
118
+ req.params.raw[CSRF_TOKEN.to_s] || req.get_header("HTTP_X_CSRF_TOKEN")
119
+ end
120
+
110
121
  # Verify if CSRF token from params, matches the one stored in session.
111
122
  # If not, it raises an error.
112
123
  #
@@ -131,14 +142,14 @@ module Hanami
131
142
  return false unless verify_csrf_token?(req, res)
132
143
 
133
144
  missing_csrf_token?(req, res) ||
134
- !::Rack::Utils.secure_compare(req.session[CSRF_TOKEN], req.params.raw[CSRF_TOKEN.to_s])
145
+ !::Rack::Utils.secure_compare(req.session[CSRF_TOKEN], request_csrf_token(req))
135
146
  end
136
147
 
137
148
  # Verify the CSRF token was passed in params.
138
149
  #
139
150
  # @api private
140
151
  def missing_csrf_token?(req, *)
141
- Hanami::Utils::Blank.blank?(req.params.raw[CSRF_TOKEN.to_s])
152
+ Hanami::Utils::Blank.blank?(request_csrf_token(req))
142
153
  end
143
154
 
144
155
  # Generates a random CSRF Token
data/lib/hanami/action.rb CHANGED
@@ -373,13 +373,15 @@ module Hanami
373
373
  # Otherwise, it sets the response body with the default message associated
374
374
  # to the code (eg 404 will set `"Not Found"`).
375
375
  #
376
- # @param status [Fixnum] a valid HTTP status code
376
+ # @param status [Integer, Symbol] A valid HTTP status code or a symbol representing the HTTP status code
377
377
  # @param body [String] the response body
378
378
  #
379
379
  # @raise [StandardError] if the code isn't valid
380
380
  #
381
381
  # @since 0.2.0
382
382
  #
383
+ # @see https://hanakai.org/learn/hanami/actions/status-codes List of status codes and symbols
384
+ #
383
385
  # @see Hanami::Action::Throwable#handle_exception
384
386
  # @see Hanami::Http::Status:ALL
385
387
  #
@@ -433,7 +435,12 @@ module Hanami
433
435
  # @api private
434
436
  def exception_handler(exception)
435
437
  config.handled_exceptions.each do |exception_class, handler|
436
- return handler if exception.is_a?(exception_class)
438
+ case exception_class
439
+ when String
440
+ return handler if exception.class.name == exception_class # rubocop:disable Style/ClassEqualityComparison
441
+ else
442
+ return handler if exception.is_a?(exception_class)
443
+ end
437
444
  end
438
445
 
439
446
  nil
@@ -8,6 +8,6 @@ module Hanami
8
8
  #
9
9
  # @since 0.1.0
10
10
  # @api public
11
- VERSION = "2.3.0.beta2"
11
+ VERSION = "2.3.1"
12
12
  end
13
13
  end
@@ -21,7 +21,10 @@ module Hanami
21
21
  #
22
22
  # @since 2.0.2
23
23
  # @api private
24
- SYMBOLS = ::Rack::Utils::SYMBOL_TO_STATUS_CODE
24
+ SYMBOLS = ::Rack::Utils::SYMBOL_TO_STATUS_CODE.merge(
25
+ unprocessable_content: 422,
26
+ unprocessable_entity: 422
27
+ )
25
28
 
26
29
  # Return a status for the given code
27
30
  #
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0.beta2
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
- - Luca Guidi
7
+ - Hanakai team
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 2.3.0.beta1
32
+ version: 2.3.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 2.3.0.beta1
39
+ version: 2.3.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: dry-configurable
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -85,26 +85,6 @@ dependencies:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
87
  version: '2.6'
88
- - !ruby/object:Gem::Dependency
89
- name: bundler
90
- requirement: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: '1.6'
95
- - - "<"
96
- - !ruby/object:Gem::Version
97
- version: '3'
98
- type: :development
99
- prerelease: false
100
- version_requirements: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '1.6'
105
- - - "<"
106
- - !ruby/object:Gem::Version
107
- version: '3'
108
88
  - !ruby/object:Gem::Dependency
109
89
  name: rack-test
110
90
  requirement: !ruby/object:Gem::Requirement
@@ -163,7 +143,7 @@ dependencies:
163
143
  version: '1.0'
164
144
  description: Complete, fast and testable actions for Rack
165
145
  email:
166
- - me@lucaguidi.com
146
+ - info@hanakai.org
167
147
  executables: []
168
148
  extensions: []
169
149
  extra_rdoc_files: []