rubypitaya 2.17.0 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90b11b45f712986bf00e347425a7f4f237fd540ba4ab74c6cdb87b5a0fe795d2
4
- data.tar.gz: 58ab166182fe804946ac6f42a25f16ca1902ce969112b12ee716083226d4b7cb
3
+ metadata.gz: 38d15208a32190c01690735d3d8433bb0f8cc9b6f71a64f7897ba668c21e4e97
4
+ data.tar.gz: 7396c21b202d611ea5945fd9838b68323b4751777d3e154b20b31557ee470b7a
5
5
  SHA512:
6
- metadata.gz: c06fc55a0ec2749b56658aa3ab579329393e341d789a764966361877c04d46bcd1b48ca2677c8f692115f3f67913b74787264950c80ea3604c60354831d29186
7
- data.tar.gz: e5cbfa9e030ecfa0a41bbdd2604f559fd7d8370eae633d13f05857b9f5bcc556b0b9168a232b1a4f329ebad2596dfd46c6d336250832ff75514b688d11f4033c
6
+ metadata.gz: 6b70755f160f42aa9a145bf55c0709bb82ec92f1f2105874127439bdc286ea124e7f2093cdae34a377d595bb54e21e75af244d34cbd9c30f8feac08849db7d9a
7
+ data.tar.gz: 50df16ee2575fd5840b0af30cfa3aedb9a7e4b35d27291a3a484ac2233b09b41700618ef9a1d8b2223cc1dba3e0cc0d8c7fc42a168971e548bd0301e34b77e7d
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'rubypitaya', '2.17.0'
3
+ gem 'rubypitaya', '2.18.0'
4
4
 
5
5
  group :development do
6
6
  gem 'pry', '0.14.0'
@@ -1,21 +1,3 @@
1
- GIT
2
- remote: https://gitlab.com/LucianoPC/ruby-pitaya
3
- revision: 9c28f2a16f3140d24f019164a254155f524f2593
4
- branch: ruby2.7.2
5
- specs:
6
- rubypitaya (2.17.0)
7
- activerecord (= 6.1.3)
8
- etcdv3 (= 0.10.2)
9
- eventmachine (= 1.2.7)
10
- nats (= 0.11.0)
11
- ostruct (= 0.3.3)
12
- pg (= 1.2.3)
13
- protobuf (= 3.10.0)
14
- rake (= 13.0.3)
15
- redis (= 4.2.5)
16
- sinatra (= 2.1.0)
17
- sinatra-contrib (= 2.1.0)
18
-
19
1
  GEM
20
2
  remote: https://rubygems.org/
21
3
  specs:
@@ -69,10 +51,10 @@ GEM
69
51
  grpc (~> 1.17)
70
52
  eventmachine (1.2.7)
71
53
  ffi (1.14.2)
72
- google-protobuf (3.15.3)
54
+ google-protobuf (3.15.3-x86_64-linux)
73
55
  googleapis-common-protos-types (1.0.6)
74
56
  google-protobuf (~> 3.14)
75
- grpc (1.36.0)
57
+ grpc (1.36.0-x86_64-linux)
76
58
  google-protobuf (~> 3.14)
77
59
  googleapis-common-protos-types (~> 1.0)
78
60
  i18n (1.8.9)
@@ -126,6 +108,18 @@ GEM
126
108
  rspec-support (~> 3.10.0)
127
109
  rspec-support (3.10.2)
128
110
  ruby2_keywords (0.0.4)
111
+ rubypitaya (2.18.0)
112
+ activerecord (= 6.1.3)
113
+ etcdv3 (= 0.10.2)
114
+ eventmachine (= 1.2.7)
115
+ nats (= 0.11.0)
116
+ ostruct (= 0.3.3)
117
+ pg (= 1.2.3)
118
+ protobuf (= 3.10.0)
119
+ rake (= 13.0.3)
120
+ redis (= 4.2.5)
121
+ sinatra (= 2.1.0)
122
+ sinatra-contrib (= 2.1.0)
129
123
  sinatra (2.1.0)
130
124
  mustermann (~> 1.0)
131
125
  rack (~> 2.2)
@@ -155,7 +149,7 @@ DEPENDENCIES
155
149
  listen (= 3.4.1)
156
150
  pry (= 0.14.0)
157
151
  rspec (= 3.10.0)
158
- rubypitaya!
152
+ rubypitaya (= 2.18.0)
159
153
 
160
154
  BUNDLED WITH
161
155
  2.1.4
@@ -1,11 +1,11 @@
1
1
  class PlayerBLL
2
2
 
3
3
  def create_new_player(setup, config)
4
- name = config['initial_player']['name']
4
+ name = config['initial_player'][:name]
5
5
  gold = setup['initial_player.wallet.gold']
6
6
 
7
7
  player = Player.new(name: name, gold: gold, user: User.new)
8
- player.save
8
+ player.save!
9
9
  player
10
10
  end
11
11
  end
@@ -17,7 +17,7 @@ class PlayerHandler < RubyPitaya::HandlerBase
17
17
  # Given you have the following file "app/config/initial_player.json"
18
18
  # And this json content is {'name': 'Guest'}
19
19
  # And you can get the initial player name
20
- # Then you can run the following code: @config['initial_player']['name']
20
+ # Then you can run the following code: @config['initial_player'][:name]
21
21
  #
22
22
  # - @params
23
23
  # - info: Special hash with the request parameters
@@ -1,18 +1,21 @@
1
1
  FROM ruby:2.7.2
2
2
 
3
- RUN apt update
4
- RUN apt install -y git vim postgresql-client docker.io --no-install-recommends
3
+ ENV LANG=C.UTF-8
4
+ ENV LC_ALL=C.UTF-8
5
5
 
6
- WORKDIR /app/rubypitaya/
6
+ RUN apt update && \
7
+ apt install -y --no-install-recommends \
8
+ docker.io \
9
+ postgresql-client \
10
+ && rm -rf /var/lib/apt/lists/*
7
11
 
8
12
  COPY Gemfile Gemfile.lock ./
9
13
 
10
14
  RUN bundle install
11
15
 
12
- COPY . .
16
+ WORKDIR /app/rubypitaya/
13
17
 
14
- ENV LANG=C.UTF-8
15
- ENV LC_ALL=C.UTF-8
18
+ COPY . .
16
19
 
17
20
  ENTRYPOINT ["./docker/entrypoint.sh"]
18
21
 
@@ -1,36 +1,35 @@
1
1
  FROM ruby:2.7.2 as builder
2
2
 
3
- WORKDIR /app/rubypitaya/
3
+ RUN apt update && \
4
+ apt install -y --no-install-recommends \
5
+ curl \
6
+ && rm -rf /var/lib/apt/lists/*
4
7
 
5
8
  COPY Gemfile Gemfile.lock ./
6
9
 
7
- ENV BUNDLER_WITHOUT development test
8
- RUN bundle install
10
+ RUN bundle config --local without "development test" && \
11
+ bundle install
9
12
 
10
- COPY . .
13
+ RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
11
14
 
12
15
  FROM ruby:2.7.2-slim
13
16
 
14
- RUN apt update && apt install -y postgresql-client curl python3 bash vim --no-install-recommends
15
- RUN rm -rf /var/lib/apt/lists/*
17
+ ENV LANG=C.UTF-8
18
+ ENV LC_ALL=C.UTF-8
16
19
 
17
- RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
18
- RUN chmod +x ./kubectl
19
- RUN mv ./kubectl /usr/local/bin
20
+ RUN apt update && \
21
+ apt install -y --no-install-recommends \
22
+ postgresql-client \
23
+ && rm -rf /var/lib/apt/lists/*
20
24
 
21
- COPY --from=builder /usr/local/etc /usr/local/etc
22
25
  COPY --from=builder /usr/local/bundle /usr/local/bundle
23
- COPY --from=builder /usr/local/bin/ruby /usr/local/bin/ruby
24
- COPY --from=builder /usr/local/lib/ruby/gems/2.7.0 /usr/local/lib/ruby/gems/2.7.0
25
-
26
- COPY --from=builder /app/rubypitaya /app/rubypitaya
26
+ COPY --from=builder /kubectl /usr/local/bin/kubectl
27
+
28
+ RUN chmod +x /usr/local/bin/kubectl
27
29
 
28
30
  WORKDIR /app/rubypitaya/
29
31
 
30
- RUN rm -rf vendor/
31
-
32
- ENV LANG=C.UTF-8
33
- ENV LC_ALL=C.UTF-8
32
+ COPY . .
34
33
 
35
34
  ENTRYPOINT ["./docker/entrypoint.sh"]
36
35
 
@@ -4,11 +4,10 @@ module RubyPitaya
4
4
 
5
5
  class Config
6
6
 
7
- attr_writer :config_core_override
8
-
9
7
  def initialize
10
8
  @config_core = ConfigCore.new
11
9
  @config_core_override = nil
10
+ @has_config_core_override = false
12
11
 
13
12
  @result_cache = {}
14
13
  end
@@ -17,10 +16,13 @@ module RubyPitaya
17
16
  result = @result_cache[key]
18
17
  return result unless result.nil?
19
18
 
20
- result = @config_core_override[key] unless @config_core_override.nil?
21
- result = @config_core[key] if result.nil?
19
+ if @has_config_core_override
20
+ result = @config_core_override[key]
21
+ else
22
+ result = @config_core[key]
23
+ end
22
24
 
23
- @result_cache[key] = result
25
+ @result_cache[key] = result.deep_symbolize_keys
24
26
 
25
27
  result
26
28
  end
@@ -33,5 +35,10 @@ module RubyPitaya
33
35
  def clear_cache
34
36
  @result_cache.clear
35
37
  end
38
+
39
+ def config_core_override=(value)
40
+ @config_core_override = value
41
+ @has_config_core_override = !value.nil?
42
+ end
36
43
  end
37
44
  end
@@ -17,8 +17,7 @@ module RubyPitaya
17
17
  end
18
18
 
19
19
  def [](key)
20
- split_key = key.split('/')
21
- @config.dig(*split_key)
20
+ @config[key]
22
21
  end
23
22
 
24
23
  def auto_reload
@@ -42,12 +41,11 @@ module RubyPitaya
42
41
 
43
42
  def load_config_file(configs_folder_path, file_path)
44
43
  config_text = File.open(file_path, &:read)
45
- config_hash = JSON.parse(config_text)
44
+ config_hash = JSON.parse(config_text, symbolize_names: true)
46
45
 
47
- path_array = file_path.sub(/^#{configs_folder_path}/, '')[0..-6]
48
- .split('/')
46
+ file_name = file_path.sub(/^#{configs_folder_path}/, '')[0..-6]
49
47
 
50
- set_config_value(path_array, config_hash)
48
+ @config[file_name] = config_hash
51
49
 
52
50
  rescue Exception => error
53
51
  puts "ERROR: #{error}"
@@ -69,20 +67,5 @@ module RubyPitaya
69
67
  puts "MODIFIED @config: #{path}"
70
68
  end
71
69
  end
72
-
73
- def set_config_value(keys, value)
74
- config = @config
75
-
76
- keys.each_with_index do |key, index|
77
- is_last_index = index == keys.size - 1
78
-
79
- if is_last_index
80
- config[key] = value
81
- else
82
- config[key] = {} unless config.key?(key)
83
- config = config[key]
84
- end
85
- end
86
- end
87
70
  end
88
71
  end
@@ -144,7 +144,7 @@ module RubyPitaya
144
144
  start_time_seconds = Time.now.to_f
145
145
 
146
146
  message_route = request[:msg][:route]
147
- message_data = request[:msg][:data]
147
+ message_data = request[:msg][:data] || {}
148
148
  message_data = JSON.parse(message_data) if message_data.class == String
149
149
 
150
150
  params = Parameters.new(message_data)
@@ -1,4 +1,5 @@
1
1
  require 'date'
2
+ require 'yaml'
2
3
  require 'bigdecimal'
3
4
  require 'stringio'
4
5
 
@@ -9,12 +10,36 @@ require 'active_support/core_ext/array/wrap'
9
10
  module RubyPitaya
10
11
 
11
12
  class ParameterMissing < IndexError
12
- attr_reader :param
13
+ attr_reader :param, :keys
13
14
 
14
- def initialize(param)
15
+ def initialize(param, keys = nil)
15
16
  @param = param
17
+ @keys = keys
16
18
  super("param is missing or the value is empty: #{param}")
17
19
  end
20
+
21
+ class Correction
22
+ def initialize(error)
23
+ @error = error
24
+ end
25
+
26
+ def corrections
27
+ if @error.param && @error.keys
28
+ maybe_these = @error.keys
29
+
30
+ maybe_these.sort_by { |n|
31
+ DidYouMean::Jaro.distance(@error.param.to_s, n)
32
+ }.reverse.first(4)
33
+ else
34
+ []
35
+ end
36
+ end
37
+ end
38
+
39
+ # We may not have DYM, and DYM might not let us register error handlers
40
+ if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
41
+ DidYouMean.correct_error(self, Correction)
42
+ end
18
43
  end
19
44
 
20
45
  class UnpermittedParameters < IndexError
@@ -26,26 +51,98 @@ module RubyPitaya
26
51
  end
27
52
  end
28
53
 
29
- class Parameters < ActiveSupport::HashWithIndifferentAccess
30
- attr_accessor :permitted
31
- alias :permitted? :permitted
54
+ class UnfilteredParameters < ArgumentError
55
+ def initialize # :nodoc:
56
+ super("unable to convert unpermitted parameters to hash")
57
+ end
58
+ end
59
+
60
+ class Parameters
61
+ cattr_accessor :permit_all_parameters, instance_accessor: false, default: false
62
+ cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
63
+
64
+ delegate :keys, :key?, :has_key?, :member?, :values, :has_value?, :value?, :empty?, :include?,
65
+ :as_json, :to_s, :each_key, to: :@parameters
66
+
67
+ cattr_accessor :always_permitted_parameters, default: %w( controller action )
68
+
69
+ class << self
70
+ def nested_attribute?(key, value) # :nodoc:
71
+ /\A-?\d+\z/.match?(key) && (value.is_a?(Hash) || value.is_a?(Parameters))
72
+ end
73
+ end
32
74
 
33
- cattr_accessor :action_on_unpermitted_parameters, :instance_accessor => false
75
+ def initialize(parameters = {})
76
+ @parameters = parameters.with_indifferent_access
77
+ @permitted = self.class.permit_all_parameters
78
+ end
34
79
 
35
- # Never raise an UnpermittedParameters exception because of these params
36
- # are present. They are added by Rails and it's of no concern.
37
- NEVER_UNPERMITTED_PARAMS = %w( controller action )
80
+ def ==(other)
81
+ if other.respond_to?(:permitted?)
82
+ permitted? == other.permitted? && parameters == other.parameters
83
+ else
84
+ @parameters == other
85
+ end
86
+ end
87
+ alias eql? ==
38
88
 
39
- def initialize(attributes = nil)
40
- super(attributes)
41
- @permitted = false
89
+ def hash
90
+ [@parameters.hash, @permitted].hash
91
+ end
92
+
93
+ def to_h
94
+ if permitted?
95
+ convert_parameters_to_hashes(@parameters, :to_h)
96
+ else
97
+ raise UnfilteredParameters
98
+ end
99
+ end
100
+
101
+ def to_hash
102
+ to_h.to_hash
103
+ end
104
+
105
+ def to_query(*args)
106
+ to_h.to_query(*args)
107
+ end
108
+ alias_method :to_param, :to_query
109
+
110
+ def to_unsafe_h
111
+ convert_parameters_to_hashes(@parameters, :to_unsafe_h)
112
+ end
113
+ alias_method :to_unsafe_hash, :to_unsafe_h
114
+
115
+ def each_pair(&block)
116
+ return to_enum(__callee__) unless block_given?
117
+ @parameters.each_pair do |key, value|
118
+ yield [key, convert_hashes_to_parameters(key, value)]
119
+ end
120
+
121
+ self
122
+ end
123
+ alias_method :each, :each_pair
124
+
125
+ def each_value(&block)
126
+ return to_enum(:each_value) unless block_given?
127
+ @parameters.each_pair do |key, value|
128
+ yield convert_hashes_to_parameters(key, value)
129
+ end
130
+
131
+ self
132
+ end
133
+
134
+ def converted_arrays
135
+ @converted_arrays ||= Set.new
136
+ end
137
+
138
+ def permitted?
139
+ @permitted
42
140
  end
43
141
 
44
142
  def permit!
45
143
  each_pair do |key, value|
46
- value = convert_hashes_to_parameters(key, value)
47
- Array.wrap(value).each do |_|
48
- _.permit! if _.respond_to? :permit!
144
+ Array.wrap(value).flatten.each do |v|
145
+ v.permit! if v.respond_to? :permit!
49
146
  end
50
147
  end
51
148
 
@@ -54,7 +151,13 @@ module RubyPitaya
54
151
  end
55
152
 
56
153
  def require(key)
57
- self[key].presence || raise(ParameterMissing.new(key))
154
+ return key.map { |k| require(k) } if key.is_a?(Array)
155
+ value = self[key]
156
+ if value.present? || value == false
157
+ value
158
+ else
159
+ raise ParameterMissing.new(key, @parameters.keys)
160
+ end
58
161
  end
59
162
 
60
163
  alias :required :require
@@ -66,7 +169,7 @@ module RubyPitaya
66
169
  case filter
67
170
  when Symbol, String
68
171
  permitted_scalar_filter(params, filter)
69
- when Hash then
172
+ when Hash
70
173
  hash_filter(params, filter)
71
174
  end
72
175
  end
@@ -77,169 +180,377 @@ module RubyPitaya
77
180
  end
78
181
 
79
182
  def [](key)
80
- convert_hashes_to_parameters(key, super)
183
+ convert_hashes_to_parameters(key, @parameters[key])
184
+ end
185
+
186
+ def []=(key, value)
187
+ @parameters[key] = value
81
188
  end
82
189
 
83
190
  def fetch(key, *args)
84
- convert_hashes_to_parameters(key, super, false)
85
- rescue KeyError, IndexError
86
- raise ParameterMissing.new(key)
191
+ convert_value_to_parameters(
192
+ @parameters.fetch(key) {
193
+ if block_given?
194
+ yield
195
+ else
196
+ args.fetch(0) { raise ActionController::ParameterMissing.new(key, @parameters.keys) }
197
+ end
198
+ }
199
+ )
200
+ end
201
+
202
+ def dig(*keys)
203
+ convert_hashes_to_parameters(keys.first, @parameters[keys.first])
204
+ @parameters.dig(*keys)
205
+ end
206
+
207
+ def slice!(*keys)
208
+ @parameters.slice!(*keys)
209
+ self
210
+ end
211
+
212
+ def except(*keys)
213
+ new_instance_with_inherited_permitted_status(@parameters.except(*keys))
214
+ end
215
+
216
+ def extract!(*keys)
217
+ new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
218
+ end
219
+
220
+ def transform_values
221
+ return to_enum(:transform_values) unless block_given?
222
+ new_instance_with_inherited_permitted_status(
223
+ @parameters.transform_values { |v| yield convert_value_to_parameters(v) }
224
+ )
225
+ end
226
+
227
+ def transform_values!
228
+ return to_enum(:transform_values!) unless block_given?
229
+ @parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
230
+ self
231
+ end
232
+
233
+ def transform_keys(&block)
234
+ return to_enum(:transform_keys) unless block_given?
235
+ new_instance_with_inherited_permitted_status(
236
+ @parameters.transform_keys(&block)
237
+ )
238
+ end
239
+
240
+ def transform_keys!(&block)
241
+ return to_enum(:transform_keys!) unless block_given?
242
+ @parameters.transform_keys!(&block)
243
+ self
244
+ end
245
+
246
+ def deep_transform_keys(&block)
247
+ new_instance_with_inherited_permitted_status(
248
+ @parameters.deep_transform_keys(&block)
249
+ )
250
+ end
251
+
252
+ def deep_transform_keys!(&block)
253
+ @parameters.deep_transform_keys!(&block)
254
+ self
255
+ end
256
+
257
+ def delete(key, &block)
258
+ convert_value_to_parameters(@parameters.delete(key, &block))
259
+ end
260
+
261
+ def select(&block)
262
+ new_instance_with_inherited_permitted_status(@parameters.select(&block))
87
263
  end
88
264
 
89
- def slice(*keys)
90
- self.class.new(super).tap do |new_instance|
91
- new_instance.instance_variable_set :@permitted, @permitted
265
+ def select!(&block)
266
+ @parameters.select!(&block)
267
+ self
268
+ end
269
+ alias_method :keep_if, :select!
270
+
271
+ def reject(&block)
272
+ new_instance_with_inherited_permitted_status(@parameters.reject(&block))
273
+ end
274
+
275
+ def reject!(&block)
276
+ @parameters.reject!(&block)
277
+ self
278
+ end
279
+ alias_method :delete_if, :reject!
280
+
281
+ def compact
282
+ new_instance_with_inherited_permitted_status(@parameters.compact)
283
+ end
284
+
285
+ def compact!
286
+ self if @parameters.compact!
287
+ end
288
+
289
+ def compact_blank
290
+ reject { |_k, v| v.blank? }
291
+ end
292
+
293
+ def compact_blank!
294
+ reject! { |_k, v| v.blank? }
295
+ end
296
+
297
+ def values_at(*keys)
298
+ convert_value_to_parameters(@parameters.values_at(*keys))
299
+ end
300
+
301
+ def merge(other_hash)
302
+ new_instance_with_inherited_permitted_status(
303
+ @parameters.merge(other_hash.to_h)
304
+ )
305
+ end
306
+
307
+ def merge!(other_hash)
308
+ @parameters.merge!(other_hash.to_h)
309
+ self
310
+ end
311
+
312
+ def reverse_merge(other_hash)
313
+ new_instance_with_inherited_permitted_status(
314
+ other_hash.to_h.merge(@parameters)
315
+ )
316
+ end
317
+ alias_method :with_defaults, :reverse_merge
318
+
319
+ def reverse_merge!(other_hash)
320
+ @parameters.merge!(other_hash.to_h) { |key, left, right| left }
321
+ self
322
+ end
323
+ alias_method :with_defaults!, :reverse_merge!
324
+
325
+ def stringify_keys
326
+ dup
327
+ end
328
+
329
+ def inspect
330
+ "#<#{self.class} #{@parameters} permitted: #{@permitted}>"
331
+ end
332
+
333
+ def self.hook_into_yaml_loading
334
+ YAML.load_tags["!ruby/hash-with-ivars:ActionController::Parameters"] = name
335
+ YAML.load_tags["!ruby/hash:ActionController::Parameters"] = name
336
+ end
337
+ hook_into_yaml_loading
338
+
339
+ def init_with(coder)
340
+ case coder.tag
341
+ when "!ruby/hash:ActionController::Parameters"
342
+ @parameters = coder.map.with_indifferent_access
343
+ @permitted = false
344
+ when "!ruby/hash-with-ivars:ActionController::Parameters"
345
+ @parameters = coder.map["elements"].with_indifferent_access
346
+ @permitted = coder.map["ivars"][:@permitted]
347
+ when "!ruby/object:ActionController::Parameters"
348
+ @parameters, @permitted = coder.map["parameters"], coder.map["permitted"]
92
349
  end
93
350
  end
94
351
 
95
- def dup
96
- self.class.new(self).tap do |duplicate|
97
- duplicate.default = default
98
- duplicate.instance_variable_set :@permitted, @permitted
352
+ def deep_dup
353
+ self.class.new(@parameters.deep_dup).tap do |duplicate|
354
+ duplicate.permitted = @permitted
99
355
  end
100
356
  end
101
357
 
102
358
  protected
103
- def convert_value(value, conversion = nil)
104
- if value.class == Hash
105
- Parameters.new(value)
106
- elsif value.is_a?(Array)
107
- value.dup.replace(value.map { |e| convert_value(e) })
108
- else
109
- value
110
- end
111
- end
359
+
360
+ attr_reader :parameters
361
+
362
+ attr_writer :permitted
363
+
364
+ def nested_attributes?
365
+ @parameters.any? { |k, v| Parameters.nested_attribute?(k, v) }
366
+ end
367
+
368
+ def each_nested_attribute
369
+ hash = self.class.new
370
+ self.each { |k, v| hash[k] = yield v if Parameters.nested_attribute?(k, v) }
371
+ hash
372
+ end
112
373
 
113
374
  private
114
375
 
115
- def convert_hashes_to_parameters(key, value, assign_if_converted=true)
116
- converted = convert_value_to_parameters(value)
117
- self[key] = converted if assign_if_converted && !converted.equal?(value)
376
+ def new_instance_with_inherited_permitted_status(hash)
377
+ self.class.new(hash).tap do |new_instance|
378
+ new_instance.permitted = @permitted
379
+ end
380
+ end
381
+
382
+ def convert_parameters_to_hashes(value, using)
383
+ case value
384
+ when Array
385
+ value.map { |v| convert_parameters_to_hashes(v, using) }
386
+ when Hash
387
+ value.transform_values do |v|
388
+ convert_parameters_to_hashes(v, using)
389
+ end.with_indifferent_access
390
+ when Parameters
391
+ value.send(using)
392
+ else
393
+ value
394
+ end
395
+ end
396
+
397
+ def convert_hashes_to_parameters(key, value)
398
+ converted = convert_value_to_parameters(value)
399
+ @parameters[key] = converted unless converted.equal?(value)
400
+ converted
401
+ end
402
+
403
+ def convert_value_to_parameters(value)
404
+ case value
405
+ when Array
406
+ return value if converted_arrays.member?(value)
407
+ converted = value.map { |_| convert_value_to_parameters(_) }
408
+ converted_arrays << converted
118
409
  converted
410
+ when Hash
411
+ self.class.new(value)
412
+ else
413
+ value
119
414
  end
415
+ end
120
416
 
121
- def convert_value_to_parameters(value)
122
- if value.is_a?(Array)
123
- value.map { |_| convert_value_to_parameters(_) }
124
- elsif value.is_a?(Parameters) || !value.is_a?(Hash)
125
- value
417
+ def each_element(object, &block)
418
+ case object
419
+ when Array
420
+ object.grep(Parameters).map { |el| yield el }.compact
421
+ when Parameters
422
+ if object.nested_attributes?
423
+ object.each_nested_attribute(&block)
126
424
  else
127
- self.class.new(value)
425
+ yield object
128
426
  end
129
427
  end
428
+ end
130
429
 
131
- #
132
- # --- Filtering ----------------------------------------------------------
133
- #
134
-
135
- # This is a white list of permitted scalar types that includes the ones
136
- # supported in XML and JSON requests.
137
- #
138
- # This list is in particular used to filter ordinary requests, String goes
139
- # as first element to quickly short-circuit the common case.
140
- #
141
- # If you modify this collection please update the README.
142
- PERMITTED_SCALAR_TYPES = [
143
- String,
144
- Symbol,
145
- NilClass,
146
- Numeric,
147
- TrueClass,
148
- FalseClass,
149
- Date,
150
- Time,
151
- # DateTimes are Dates, we document the type but avoid the redundant check.
152
- StringIO,
153
- IO,
154
- ]
155
-
156
- def permitted_scalar?(value)
157
- PERMITTED_SCALAR_TYPES.any? {|type| value.is_a?(type)}
158
- end
159
-
160
- def array_of_permitted_scalars?(value)
161
- if value.is_a?(Array)
162
- value.all? {|element| permitted_scalar?(element)}
430
+ def unpermitted_parameters!(params)
431
+ unpermitted_keys = unpermitted_keys(params)
432
+ if unpermitted_keys.any?
433
+ case self.class.action_on_unpermitted_parameters
434
+ when :log
435
+ name = "unpermitted_parameters.action_controller"
436
+ ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys)
437
+ when :raise
438
+ raise ActionController::UnpermittedParameters.new(unpermitted_keys)
163
439
  end
164
440
  end
441
+ end
165
442
 
166
- def permitted_scalar_filter(params, key)
167
- if has_key?(key) && permitted_scalar?(self[key])
168
- params[key] = self[key]
169
- end
443
+ def unpermitted_keys(params)
444
+ keys - params.keys - always_permitted_parameters
445
+ end
170
446
 
171
- keys.grep(/\A#{Regexp.escape(key.to_s)}\(\d+[if]?\)\z/).each do |key|
172
- if permitted_scalar?(self[key])
173
- params[key] = self[key]
174
- end
175
- end
447
+ PERMITTED_SCALAR_TYPES = [
448
+ String,
449
+ Symbol,
450
+ NilClass,
451
+ Numeric,
452
+ TrueClass,
453
+ FalseClass,
454
+ Date,
455
+ Time,
456
+ # DateTimes are Dates, we document the type but avoid the redundant check.
457
+ StringIO,
458
+ IO,
459
+ ]
460
+
461
+ def permitted_scalar?(value)
462
+ PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) }
463
+ end
464
+
465
+ def permitted_scalar_filter(params, permitted_key)
466
+ permitted_key = permitted_key.to_s
467
+
468
+ if has_key?(permitted_key) && permitted_scalar?(self[permitted_key])
469
+ params[permitted_key] = self[permitted_key]
176
470
  end
177
471
 
178
- def array_of_permitted_scalars_filter(params, key, hash = self)
179
- if hash.has_key?(key) && array_of_permitted_scalars?(hash[key])
180
- params[key] = hash[key]
181
- end
472
+ each_key do |key|
473
+ next unless key =~ /\(\d+[if]?\)\z/
474
+ next unless $~.pre_match == permitted_key
475
+
476
+ params[key] = self[key] if permitted_scalar?(self[key])
477
+ end
478
+ end
479
+
480
+ def array_of_permitted_scalars?(value)
481
+ if value.is_a?(Array) && value.all? { |element| permitted_scalar?(element) }
482
+ yield value
182
483
  end
484
+ end
183
485
 
184
- def hash_filter(params, filter)
185
- filter = filter.with_indifferent_access
486
+ def non_scalar?(value)
487
+ value.is_a?(Array) || value.is_a?(Parameters)
488
+ end
186
489
 
187
- # Slicing filters out non-declared keys.
188
- slice(*filter.keys).each do |key, value|
189
- next unless value
490
+ EMPTY_ARRAY = []
491
+ EMPTY_HASH = {}
492
+ def hash_filter(params, filter)
493
+ filter = filter.with_indifferent_access
190
494
 
191
- if filter[key] == []
192
- # Declaration {:comment_ids => []}.
193
- array_of_permitted_scalars_filter(params, key)
194
- else
195
- # Declaration {:user => :name} or {:user => [:name, :age, {:adress => ...}]}.
196
- params[key] = each_element(value) do |element, index|
197
- if element.is_a?(Hash)
198
- element = self.class.new(element) unless element.respond_to?(:permit)
199
- element.permit(*Array.wrap(filter[key]))
200
- elsif filter[key].is_a?(Hash) && filter[key][index] == []
201
- array_of_permitted_scalars_filter(params, index, value)
202
- end
203
- end
495
+ # Slicing filters out non-declared keys.
496
+ slice(*filter.keys).each do |key, value|
497
+ next unless value
498
+ next unless has_key? key
499
+
500
+ if filter[key] == EMPTY_ARRAY
501
+ # Declaration { comment_ids: [] }.
502
+ array_of_permitted_scalars?(self[key]) do |val|
503
+ params[key] = val
504
+ end
505
+ elsif filter[key] == EMPTY_HASH
506
+ # Declaration { preferences: {} }.
507
+ if value.is_a?(Parameters)
508
+ params[key] = permit_any_in_parameters(value)
509
+ end
510
+ elsif non_scalar?(value)
511
+ # Declaration { user: :name } or { user: [:name, :age, { address: ... }] }.
512
+ params[key] = each_element(value) do |element|
513
+ element.permit(*Array.wrap(filter[key]))
204
514
  end
205
515
  end
206
516
  end
517
+ end
207
518
 
208
- def each_element(value)
209
- if value.is_a?(Array)
210
- value.map { |el| yield el }.compact
211
- # fields_for on an array of records uses numeric hash keys.
212
- elsif fields_for_style?(value)
213
- hash = value.class.new
214
- value.each { |k,v| hash[k] = yield(v, k) }
215
- hash
216
- else
217
- yield value
519
+ def permit_any_in_parameters(params)
520
+ self.class.new.tap do |sanitized|
521
+ params.each do |key, value|
522
+ case value
523
+ when ->(v) { permitted_scalar?(v) }
524
+ sanitized[key] = value
525
+ when Array
526
+ sanitized[key] = permit_any_in_array(value)
527
+ when Parameters
528
+ sanitized[key] = permit_any_in_parameters(value)
529
+ else
530
+ # Filter this one out.
531
+ end
218
532
  end
219
533
  end
534
+ end
220
535
 
221
- def fields_for_style?(object)
222
- object.is_a?(Hash) && object.all? { |k, v| k =~ /\A-?\d+\z/ && v.is_a?(Hash) }
223
- end
224
-
225
- def unpermitted_parameters!(params)
226
- return unless self.class.action_on_unpermitted_parameters
227
-
228
- unpermitted_keys = unpermitted_keys(params)
229
-
230
- if unpermitted_keys.any?
231
- case self.class.action_on_unpermitted_parameters
232
- when :log
233
- name = "unpermitted_parameters.action_controller"
234
- ActiveSupport::Notifications.instrument(name, :keys => unpermitted_keys)
235
- when :raise
236
- raise UnpermittedParameters.new(unpermitted_keys)
536
+ def permit_any_in_array(array)
537
+ [].tap do |sanitized|
538
+ array.each do |element|
539
+ case element
540
+ when ->(e) { permitted_scalar?(e) }
541
+ sanitized << element
542
+ when Parameters
543
+ sanitized << permit_any_in_parameters(element)
544
+ else
545
+ # Filter this one out.
237
546
  end
238
547
  end
239
548
  end
549
+ end
240
550
 
241
- def unpermitted_keys(params)
242
- self.keys - params.keys - NEVER_UNPERMITTED_PARAMS
243
- end
551
+ def initialize_copy(source)
552
+ super
553
+ @parameters = @parameters.dup
554
+ end
244
555
  end
245
556
  end
@@ -1,3 +1,3 @@
1
1
  module RubyPitaya
2
- VERSION = '2.17.0'
2
+ VERSION = '2.18.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubypitaya
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.0
4
+ version: 2.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luciano Prestes Cavalcanti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-28 00:00:00.000000000 Z
11
+ date: 2021-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg