hanami-controller 0.7.0 → 0.7.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
  SHA1:
3
- metadata.gz: 4e9a92b39aa9c373400fe07e64b270d3066af888
4
- data.tar.gz: f146d4da77a9c4ced2bfdfea31826db63f0ef992
3
+ metadata.gz: 19ed324ba067df9dae1f836edc8232f5ab9ec658
4
+ data.tar.gz: 83d999e3d478d6b5048da0f57bc6ce9e4a3bd42e
5
5
  SHA512:
6
- metadata.gz: 089577daf70c460f7bedaa4d613c65551b0a9bd10af1e7725e0654398ad81c8d5abd7df550f0cce0f97b73f5d00cbf3072f039753a1eb9255218b555705f7e57
7
- data.tar.gz: 34ce5a95575dc90669f87469d5494c7b8208b9ac1efc1015c8f6078ca906178d0cdeed585b02f36c4eda64f4977d0a825d0785bfd4f65728da352821cac57df3
6
+ metadata.gz: 4df22338de1f7d4ec7fc609327917a905db7939f28dbb2113d54e1bc2394b6877bccecd94aba0047e3a745a8098a6341e9afc7fbd36a81b1cd56d2a494685140
7
+ data.tar.gz: dcb8ffe55c81813c9bd976a04cc840811b9ee0993f46ad76282d8e1f27eb58d9c069807c5f900afffacb9767d0ac900b55c2a49c0955c0c19a1a93e71488d300
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # Hanami::Controller
2
2
  Complete, fast and testable actions for Rack
3
3
 
4
+ ## v0.7.1 - 2016-10-06
5
+ ### Added
6
+ - [Kyle Chong] Introduced `parsed_request_body` for action
7
+ - [Luca Guidi] Introduced `Hanami::Action::BaseParams#each`
8
+
9
+ ### Fixed
10
+ - [Ayleen McCann] Use default content type when `HTTP_ACCEPT` is `*/*`
11
+ - [Kyle Chong] Don't stringify uploaded files
12
+ - [Kyle Chong] Don't stringify params values when not necessary
13
+
14
+ ### Changed
15
+ - [akhramov & Luca Guidi] Raise `Hanami::Controller::IllegalExposureError` when try to expose reserved words: `params`, and `flash`.
16
+
4
17
  ## v0.7.0 - 2016-07-22
5
18
  ### Added
6
19
  - [Luca Guidi] Introduced `Hanami::Action::Params#error_messages` which returns a flat collection of full error messages
@@ -124,6 +124,15 @@ module Hanami
124
124
  end
125
125
  alias_method :to_hash, :to_h
126
126
 
127
+ # Iterates through params
128
+ #
129
+ # @param blk [Proc]
130
+ #
131
+ # @since 0.7.1
132
+ def each(&blk)
133
+ to_h.each(&blk)
134
+ end
135
+
127
136
  private
128
137
 
129
138
  # @since 0.7.0
@@ -1,3 +1,5 @@
1
+ require 'hanami/action/exposable/guard'
2
+
1
3
  module Hanami
2
4
  module Action
3
5
  # Exposures API
@@ -18,7 +20,9 @@ module Hanami
18
20
  def self.included(base)
19
21
  base.class_eval do
20
22
  extend ClassMethods
21
- expose :params
23
+ include Guard
24
+
25
+ _expose :params
22
26
  end
23
27
  end
24
28
 
@@ -68,6 +72,10 @@ module Hanami
68
72
  end
69
73
  end
70
74
 
75
+ # Alias of #expose to be used in internal modules.
76
+ # #_expose is not watched by the Guard
77
+ alias _expose expose
78
+
71
79
  # Set of exposures attribute names
72
80
  #
73
81
  # @return [Array] the exposures attribute names
@@ -0,0 +1,102 @@
1
+ require 'hanami/controller/error'
2
+
3
+ module Hanami
4
+ module Controller
5
+ # Exposure of reserved words
6
+ #
7
+ # @since 0.7.1
8
+ class IllegalExposureError < Error
9
+ end
10
+ end
11
+
12
+ module Action
13
+ module Exposable
14
+ # Guard for Exposures API.
15
+ # Prevents exposure of reserved words
16
+ #
17
+ # @since 0.7.1
18
+ #
19
+ # @see Hanami::Action::Exposable::Guard::ClassMethods#expose
20
+ # @see Hanami::Action::Exposable::Guard::ClassMethods#reserved_word?
21
+ module Guard
22
+ # Override Ruby's hook for modules.
23
+ # It prepends a guard for the exposures logic
24
+ #
25
+ # @param base [Class] the target action
26
+ #
27
+ # @since 0.7.1
28
+ # @api private
29
+ #
30
+ # @see http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-included
31
+ def self.included(base)
32
+ class << base
33
+ prepend ClassMethods
34
+ end
35
+ end
36
+
37
+ # Exposures API Guard class methods
38
+ #
39
+ # @since 0.7.1
40
+ # @api private
41
+ module ClassMethods
42
+ # Prevents exposure if names contain a reserved word.
43
+ #
44
+ # @param names [Array<Symbol>] the name(s) of the attribute(s) to be
45
+ # exposed
46
+ #
47
+ # @return [void]
48
+ #
49
+ # @since 0.7.1
50
+ def expose(*names)
51
+ detect_reserved_words!(names)
52
+
53
+ super
54
+ end
55
+
56
+ private
57
+
58
+ # Raises error if given names contain a reserved word.
59
+ #
60
+ # @param names [Array<Symbol>] a list of names to be checked.
61
+ #
62
+ # @return [void]
63
+ #
64
+ # @raise [IllegalExposeError] if names contain one or more of reserved
65
+ # words
66
+ #
67
+ # @since 0.7.1
68
+ # @api private
69
+ def detect_reserved_words!(names)
70
+ names.each do |name|
71
+ if reserved_word?(name)
72
+ raise Hanami::Controller::IllegalExposureError.new("#{name} is a reserved word. It cannot be exposed")
73
+ end
74
+ end
75
+ end
76
+
77
+ # Checks if a string is a reserved word
78
+ #
79
+ # Reserved word is a name of the method defined in one of the modules
80
+ # of a given namespace.
81
+ #
82
+ # @param name [Symbol] the word to be checked
83
+ # @param namespace [String] the namespace containing internal modules
84
+ #
85
+ # @return [true, false]
86
+ #
87
+ # @since 0.7.1
88
+ # @api private
89
+ def reserved_word?(name, namespace = 'Hanami')
90
+ if method_defined?(name) || private_method_defined?(name)
91
+ method_owner = instance_method(name).owner
92
+
93
+ Utils::String.new(method_owner).namespace == namespace
94
+ else
95
+ false
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -23,7 +23,7 @@ module Hanami
23
23
  # @api private
24
24
  # @since 0.3.0
25
25
  def self.included(base)
26
- base.class_eval { expose(:format) if respond_to?(:expose) }
26
+ base.class_eval { _expose(:format) if respond_to?(:_expose) }
27
27
  end
28
28
 
29
29
  # Check if the current HTTP request is renderable.
@@ -487,9 +487,13 @@ module Hanami
487
487
  # @see https://github.com/hanami/controller/issues/104
488
488
  def best_q_match(q_value_header, available_mimes)
489
489
  values = ::Rack::Utils.q_values(q_value_header)
490
-
491
490
  values = values.map do |req_mime, quality|
492
- match = available_mimes.find { |am| ::Rack::Mime.match?(am, req_mime) }
491
+ if req_mime == DEFAULT_ACCEPT
492
+ # See https://github.com/hanami/controller/issues/167
493
+ match = default_content_type
494
+ else
495
+ match = available_mimes.find { |am| ::Rack::Mime.match?(am, req_mime) }
496
+ end
493
497
  next unless match
494
498
  [match, quality]
495
499
  end.compact
@@ -90,6 +90,15 @@ module Hanami
90
90
  end
91
91
  end
92
92
 
93
+ # Returns true if no validation errors are found,
94
+ # false otherwise.
95
+ #
96
+ # @return [TrueClass, FalseClass]
97
+ #
98
+ # @since 0.7.0
99
+ #
100
+ # @example
101
+ # params.valid? # => true
93
102
  def valid?
94
103
  @result.success?
95
104
  end
@@ -106,32 +115,9 @@ module Hanami
106
115
 
107
116
  private
108
117
 
109
- # @since 0.7.0
110
- # @api private
111
- def _extract_params
112
- # FIXME: this is required for dry-v whitelisting
113
- stringify!(super)
114
- end
115
-
116
118
  def _params
117
119
  @result.output.merge(_router_params)
118
120
  end
119
-
120
- def stringify!(result)
121
- result.keys.each do |key|
122
- value = result.delete(key)
123
- result[key.to_s] = case value
124
- when ::Hash
125
- stringify!(value)
126
- when ::Array
127
- value.map(&:to_s)
128
- else
129
- value.to_s
130
- end
131
- end
132
-
133
- result
134
- end
135
121
  end
136
122
  end
137
123
  end
@@ -42,6 +42,9 @@ module Hanami
42
42
  # @api private
43
43
  HEAD = 'HEAD'.freeze
44
44
 
45
+ # The key that returns router parsed body from the Rack env
46
+ ROUTER_PARSED_BODY = 'router.parsed_body'.freeze
47
+
45
48
  # Override Ruby's hook for modules.
46
49
  # It includes basic Hanami::Action modules to the given class.
47
50
  #
@@ -202,6 +205,10 @@ module Hanami
202
205
  @request ||= ::Hanami::Action::Request.new(@_env)
203
206
  end
204
207
 
208
+ def parsed_request_body
209
+ @_env.fetch(ROUTER_PARSED_BODY, nil)
210
+ end
211
+
205
212
  private
206
213
 
207
214
  # Sets the HTTP status code for the response
@@ -26,7 +26,7 @@ module Hanami
26
26
  # @api private
27
27
  def self.included(action)
28
28
  action.class_eval do
29
- expose :session
29
+ _expose :session
30
30
  end
31
31
  end
32
32
 
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '0.7.0'.freeze
6
+ VERSION = '0.7.1'.freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-07-22 00:00:00.000000000 Z
13
+ date: 2016-10-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -115,6 +115,7 @@ files:
115
115
  - lib/hanami/action/cookie_jar.rb
116
116
  - lib/hanami/action/cookies.rb
117
117
  - lib/hanami/action/exposable.rb
118
+ - lib/hanami/action/exposable/guard.rb
118
119
  - lib/hanami/action/flash.rb
119
120
  - lib/hanami/action/glue.rb
120
121
  - lib/hanami/action/head.rb