rubypitaya 2.17.0 → 2.18.0
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 +4 -4
- data/lib/rubypitaya/app-template/Gemfile +1 -1
- data/lib/rubypitaya/app-template/Gemfile.lock +15 -21
- data/lib/rubypitaya/app-template/app/bll/player_bll.rb +2 -2
- data/lib/rubypitaya/app-template/app/handlers/player_handler.rb +1 -1
- data/lib/rubypitaya/app-template/docker/dev/Dockerfile +9 -6
- data/lib/rubypitaya/app-template/docker/prod/Dockerfile +17 -18
- data/lib/rubypitaya/core/config.rb +12 -5
- data/lib/rubypitaya/core/config_core.rb +4 -21
- data/lib/rubypitaya/core/main.rb +1 -1
- data/lib/rubypitaya/core/parameters.rb +449 -138
- data/lib/rubypitaya/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38d15208a32190c01690735d3d8433bb0f8cc9b6f71a64f7897ba668c21e4e97
|
4
|
+
data.tar.gz: 7396c21b202d611ea5945fd9838b68323b4751777d3e154b20b31557ee470b7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b70755f160f42aa9a145bf55c0709bb82ec92f1f2105874127439bdc286ea124e7f2093cdae34a377d595bb54e21e75af244d34cbd9c30f8feac08849db7d9a
|
7
|
+
data.tar.gz: 50df16ee2575fd5840b0af30cfa3aedb9a7e4b35d27291a3a484ac2233b09b41700618ef9a1d8b2223cc1dba3e0cc0d8c7fc42a168971e548bd0301e34b77e7d
|
@@ -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'][
|
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'][
|
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
|
-
|
4
|
-
|
3
|
+
ENV LANG=C.UTF-8
|
4
|
+
ENV LC_ALL=C.UTF-8
|
5
5
|
|
6
|
-
|
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
|
-
|
16
|
+
WORKDIR /app/rubypitaya/
|
13
17
|
|
14
|
-
|
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
|
-
|
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
|
-
|
8
|
-
|
10
|
+
RUN bundle config --local without "development test" && \
|
11
|
+
bundle install
|
9
12
|
|
10
|
-
|
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
|
-
|
15
|
-
|
17
|
+
ENV LANG=C.UTF-8
|
18
|
+
ENV LC_ALL=C.UTF-8
|
16
19
|
|
17
|
-
RUN
|
18
|
-
|
19
|
-
|
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 /
|
24
|
-
|
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
|
-
|
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
|
-
|
21
|
-
|
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
|
-
|
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
|
-
|
48
|
-
.split('/')
|
46
|
+
file_name = file_path.sub(/^#{configs_folder_path}/, '')[0..-6]
|
49
47
|
|
50
|
-
|
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
|
data/lib/rubypitaya/core/main.rb
CHANGED
@@ -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
|
30
|
-
|
31
|
-
|
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
|
-
|
75
|
+
def initialize(parameters = {})
|
76
|
+
@parameters = parameters.with_indifferent_access
|
77
|
+
@permitted = self.class.permit_all_parameters
|
78
|
+
end
|
34
79
|
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
40
|
-
|
41
|
-
|
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
|
47
|
-
|
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
|
-
|
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
|
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,
|
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
|
-
|
85
|
-
|
86
|
-
|
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
|
90
|
-
|
91
|
-
|
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
|
96
|
-
self.class.new(
|
97
|
-
duplicate.
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
116
|
-
|
117
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
425
|
+
yield object
|
128
426
|
end
|
129
427
|
end
|
428
|
+
end
|
130
429
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
|
167
|
-
|
168
|
-
|
169
|
-
end
|
443
|
+
def unpermitted_keys(params)
|
444
|
+
keys - params.keys - always_permitted_parameters
|
445
|
+
end
|
170
446
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
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
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
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
|
-
|
185
|
-
|
486
|
+
def non_scalar?(value)
|
487
|
+
value.is_a?(Array) || value.is_a?(Parameters)
|
488
|
+
end
|
186
489
|
|
187
|
-
|
188
|
-
|
189
|
-
|
490
|
+
EMPTY_ARRAY = []
|
491
|
+
EMPTY_HASH = {}
|
492
|
+
def hash_filter(params, filter)
|
493
|
+
filter = filter.with_indifferent_access
|
190
494
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
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
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
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
|
-
|
242
|
-
|
243
|
-
|
551
|
+
def initialize_copy(source)
|
552
|
+
super
|
553
|
+
@parameters = @parameters.dup
|
554
|
+
end
|
244
555
|
end
|
245
556
|
end
|
data/lib/rubypitaya/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2021-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|