salestation 3.0.0 → 3.1.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: 74e15cabce10d8f11e755cfb31e55c4d899697add6a2451aaef49d71a03a5355
4
- data.tar.gz: 75b689eca24b1845be472c16aff50ee6baca356e0add8d8f9925c1a5c0113607
3
+ metadata.gz: 7fcf3aa0603e1d5f3d69869ff66efb2dd01b45d59c01fd6fc420ff059a982243
4
+ data.tar.gz: 5be0e81ae79ab73818e5eca163d2b2519d693f8fcaf4f6e2bf1a0adfa7028046
5
5
  SHA512:
6
- metadata.gz: e797e8c7c9436c7f57951c6442c2a2e39987c1fa306c0cc94349d778a2b8d764b451c5110e3cbe2250799ecccd8135bd3f64a510c652fdc88b6ba855e80c1548
7
- data.tar.gz: b16b3d1f3c66d3ef6e76bb6997d5919de6bd545aa0563606e49ed4bd9bb033900333975a310923dedc84076f039f6c6875d7b045f7439b22447267d7e77ff5b3
6
+ metadata.gz: 5a62b86a731b21328bc616c5703377edb694d539c0c5677f23a865b2b693346ac850fc9b1a3fdffe75d88e6bab56c22a6bcc4a4710e9407b04c6d65eeec10e8f
7
+ data.tar.gz: d0a00c8c57fb9c7515532025d54c94e2540bd10c9889afe8788bff1c3b38b097ea300cd268e3ac5436b4d62f94112892fa18fb734173bc5e84d412c61bd1cfbf
data/README.md CHANGED
@@ -98,10 +98,27 @@ end
98
98
  post '/hello/:name' do |name|
99
99
  extractor = BodyParamExtractor[:age]
100
100
  .merge(ConstantInput[name: name])
101
- .merge(HeadersExtractor[{'authorization' => :auth}])
101
+ .merge(HeadersExtractor[
102
+ 'accept' => :accept,
103
+ 'content-type' => :content_type,
104
+ 'x-my-value' => :my_value
105
+ ])
102
106
  .coerce(age: ->(age) { age.to_s })
103
107
 
108
+ validate_input = Salestation::Web::InputValidator[
109
+ accept: Salestation::Web::InputValidators::AcceptHeader['application/json', 'application/xml'],
110
+ content_type: Salestation::Web::InputValidators::ContentTypeHeader['application/json'],
111
+ my_value: lambda do |my_value|
112
+ if my_value == 'foo'
113
+ Deterministic::Result::Success(nil)
114
+ else
115
+ Deterministic::Result::Failure('invalid value')
116
+ end
117
+ end
118
+ ]
119
+
104
120
  response = extractor.call(request)
121
+ .map(validate_input)
105
122
  .map(create_app_request)
106
123
  .map(HelloUser)
107
124
  .map(Responses.to_ok)
@@ -45,3 +45,6 @@ require_relative './result_helper'
45
45
  require_relative './web/active_record_connection_management'
46
46
  require_relative './web/request_logger'
47
47
  require_relative './web/statsd_middleware'
48
+ require_relative './web/input_validator'
49
+ require_relative './web/input_validators/accept_header'
50
+ require_relative './web/input_validators/content_type_header'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Salestation
4
+ class Web < Module
5
+ class InputValidator
6
+ include Deterministic::Prelude
7
+
8
+ def self.[](**validations)
9
+ new(validations)
10
+ end
11
+
12
+ def initialize(**validations)
13
+ @validations = validations
14
+ end
15
+
16
+ def call(input)
17
+ @validations.reduce(Deterministic::Result::Success({})) do |result, (key, validation)|
18
+ result.map do
19
+ validation.call(input.fetch(key, nil))
20
+ end
21
+ end.map(->(_) { Deterministic::Result::Success(input) })
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Salestation
4
+ class Web < Module
5
+ module InputValidators
6
+ class AcceptHeader
7
+ include Deterministic::Prelude
8
+
9
+ def self.[](*allowed_headers)
10
+ new(allowed_headers)
11
+ end
12
+
13
+ def initialize(allowed_headers)
14
+ @allowed_headers = allowed_headers
15
+ end
16
+
17
+ def call(header_value)
18
+ header_valid = @allowed_headers.empty? || @allowed_headers.include?(header_value)
19
+
20
+ if header_valid
21
+ Success(nil)
22
+ else
23
+ Failure(App::Errors::NotAcceptable.new(
24
+ message: "Unsupported Accept Header '#{header_value}'",
25
+ debug_message: "Available Accept Headers are #{@allowed_headers.join(', ')}"
26
+ ))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Salestation
4
+ class Web < Module
5
+ module InputValidators
6
+ class ContentTypeHeader
7
+ include Deterministic::Prelude
8
+
9
+ def self.[](*allowed_headers)
10
+ new(allowed_headers)
11
+ end
12
+
13
+ def initialize(allowed_headers)
14
+ @allowed_headers = allowed_headers
15
+ end
16
+
17
+ def call(header_value)
18
+ # Some headers can have additional information such as `multipart/form-data`
19
+ parsed_header_value = header_value ? header_value.split(';').first : nil
20
+
21
+ header_valid = @allowed_headers.empty? || @allowed_headers.include?(parsed_header_value)
22
+
23
+ if header_valid
24
+ Success(nil)
25
+ else
26
+ Failure(App::Errors::UnsupportedMediaType.new(
27
+ message: "Unsupported Content-Type Header '#{header_value}'",
28
+ debug_message: "Available Content-Type Headers are #{@allowed_headers.join(', ')}"
29
+ ))
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
data/salestation.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "salestation"
7
- spec.version = "3.0.0"
7
+ spec.version = "3.1.0"
8
8
  spec.authors = ["SaleMove TechMovers"]
9
9
  spec.email = ["techmovers@salemove.com"]
10
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: salestation
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SaleMove TechMovers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-14 00:00:00.000000000 Z
11
+ date: 2019-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -132,6 +132,9 @@ files:
132
132
  - lib/salestation/web/active_record_connection_management.rb
133
133
  - lib/salestation/web/error_mapper.rb
134
134
  - lib/salestation/web/extractors.rb
135
+ - lib/salestation/web/input_validator.rb
136
+ - lib/salestation/web/input_validators/accept_header.rb
137
+ - lib/salestation/web/input_validators/content_type_header.rb
135
138
  - lib/salestation/web/request_logger.rb
136
139
  - lib/salestation/web/responses.rb
137
140
  - lib/salestation/web/statsd_middleware.rb
@@ -155,8 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
158
  - !ruby/object:Gem::Version
156
159
  version: '0'
157
160
  requirements: []
158
- rubyforge_project:
159
- rubygems_version: 2.7.6
161
+ rubygems_version: 3.0.4
160
162
  signing_key:
161
163
  specification_version: 4
162
164
  summary: ''