web-connect 0.4.10 → 0.4.11

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
  SHA1:
3
- metadata.gz: 993a6beae2974b8c68863a8de079026471cf22a5
4
- data.tar.gz: a9eaf838e7f5a5d3e3392d80734f64f776513c08
3
+ metadata.gz: 57e9bb59d41e8a0c01c87c705f8025d1d232f4ac
4
+ data.tar.gz: 519a6611cddde1f5c82be9e983d4236eaaa028a3
5
5
  SHA512:
6
- metadata.gz: 5a65c0e7fd57301c39cdd57d344fb00658120c0908f6819ec65651fd529c161f3dd6b1b882a2852d9125bbe27aacf80d9c727fade464c973124e0451ebb443eb
7
- data.tar.gz: e2c02ad0fdbc4ac90208bcc026e68bfca2eb230a81ca876acaf24e73958d8486a131b9b443681a61ee04febdd9477d897bf2d03b9fa82ea896295f6b0551fac9
6
+ metadata.gz: 44e149eb63bb57f314fdd9b5a530aa969d2910aa506c6f719aef1c6f3e40d8c95214127a0d3f795a60025cdb5c41f3a3f2dcfa62bb914f86a4fa37993bf7ffe5
7
+ data.tar.gz: 62ec603899fc3a43d0c83424c0ff94b7b0c5c3420c92ac18fc2f681ccb63a6facd4230cf9a665cdd3e13b017f771f2e6b50f61b1154b336a04be0f614ddaae56
@@ -23,6 +23,20 @@ module Netfira::WebConnect
23
23
  ]
24
24
  rescue Exceptions::HttpException => e
25
25
  make_response e.code, e.body, e.headers, e.code
26
+ rescue => e
27
+ # TODO: provide a way to silence these (i.e. for prod environments)
28
+ # TODO: log errors
29
+ raise e if defined? DONT_CATCH_ALL_EXCEPTIONS
30
+ body = {
31
+ errorCode: 1,
32
+ errorMessage: 'Uncaught Exception',
33
+ exception: {
34
+ class: e.class.name,
35
+ message: e.message,
36
+ backtrace: e.backtrace
37
+ }
38
+ }
39
+ make_response 500, body
26
40
  end
27
41
  end
28
42
 
@@ -45,7 +59,11 @@ module Netfira::WebConnect
45
59
  end
46
60
 
47
61
  def make_response(status, body = {}, headers = {}, error_code = 0)
48
- body_string = {errorCode: error_code}.merge(body).to_json
62
+ begin
63
+ body_string = {errorCode: error_code}.merge(body).to_json
64
+ rescue Encoding::UndefinedConversionError
65
+ body_string = {errorCode: error_code}.merge(sanitize_for_json body).to_json
66
+ end
49
67
  [
50
68
  status,
51
69
  {
@@ -57,6 +75,15 @@ module Netfira::WebConnect
57
75
  ]
58
76
  end
59
77
 
78
+ def sanitize_for_json(data)
79
+ case data
80
+ when String then data.encode Encoding::UTF_8 rescue '<Invalid UTF-8>'
81
+ when Hash then data.map { |k, v| [k, sanitize_for_json(v)] }.to_h
82
+ when Array then data.map { |v| sanitize_for_json v }
83
+ else data
84
+ end
85
+ end
86
+
60
87
  end
61
88
  end
62
89
 
@@ -1,5 +1,8 @@
1
1
  module Netfira::WebConnect
2
2
  class RackApp::Action
3
+ include RackApp::Exceptions::HttpExceptions
4
+
5
+ VALID_BASE64 = %r`^([a-z\d+/]{4})*([a-z\d+/]{4}|[a-z\d+/]{3}=|[a-z\d+/]{2}==)$`i
3
6
 
4
7
  def import_env(env)
5
8
  @env = env
@@ -78,8 +81,20 @@ module Netfira::WebConnect
78
81
  # Input
79
82
  if put? or post?
80
83
  @input = request.body
81
- @input = StringIO.new(@input.read.unpack('m').first) if env['CONTENT_ENCODING'] == 'base64'
82
- @input = JSON.parse @input.read if request.media_type == 'application/json'
84
+
85
+ # Decode base64
86
+ if (env['HTTP_CONTENT_ENCODING'] || env['CONTENT_ENCODING'] || '').downcase == 'base64'
87
+ input = @input.read.gsub(/\s+/, '')
88
+ raise BadRequest, 'Invalid base64 in request body' unless input.length % 4 == 0 && input =~ VALID_BASE64
89
+ @input = StringIO.new(input.unpack('m').first)
90
+ end
91
+
92
+ # Unserialize JSON
93
+ begin
94
+ @input = JSON.parse @input.read, quirks_mode: true if request.media_type == 'application/json'
95
+ rescue JSON::ParserError => error
96
+ raise BadRequest.new('Invalid JSON in request body', details: error.message.sub(/^\d+:\s*/, ''))
97
+ end
83
98
  end
84
99
 
85
100
  end
@@ -18,6 +18,21 @@ module Netfira::WebConnect
18
18
  define_method(:"#{verb}?") { self.verb.to_s == verb }
19
19
  end
20
20
 
21
+ # This method restricts request verbs (symbols) and input types (classes)
22
+ def allow(*args)
23
+
24
+ # Restrict verbs
25
+ verbs = args.select { |x| Symbol === x }
26
+ unless verbs.empty? || verbs.include?(verb)
27
+ raise MethodNotAllowed.new("The #{verb.to_s.upcase} verb is not allowed", allowed: verbs.map{ |v| v.to_s.upcase })
28
+ end
29
+
30
+ # Restrict input type
31
+ types = args.select { |x| Class === x }
32
+ unless types.empty? || types.find { |t| t === input }
33
+ raise BadRequest.new('Unexpected request body type', allowed: types.map { |t| t.name })
34
+ end
35
+ end
21
36
 
22
37
  end
23
38
  end
@@ -2,7 +2,7 @@ class Netfira::WebConnect::RackApp
2
2
  module Action::Version8
3
3
  class Checksums < Action
4
4
  def call
5
- raise MethodNotAllowed unless get?
5
+ allow :get
6
6
 
7
7
  klass = class_for_record_type(query_string['type'])
8
8
  checksums = klass.where(shop_id: shop.id).map{ |record| [record.origin_id, record.digest]}.to_h
@@ -3,7 +3,7 @@ class Netfira::WebConnect::RackApp
3
3
  class Commit < Action
4
4
 
5
5
  def call
6
- raise MethodNotAllowed unless verb == :put
6
+ allow :put, Hash
7
7
  dispatch_event :before, :commit, shop
8
8
  dispatch_event :around, :commit, shop do
9
9
  commit_records input['records'] if input['records']
@@ -2,7 +2,7 @@ class Netfira::WebConnect::RackApp
2
2
  module Action::Version8
3
3
  class Files < Action
4
4
  def call
5
- raise MethodNotAllowed unless post?
5
+ allow :post
6
6
  klass = class_for_record_type(path[0])
7
7
  raise BadRequest, "You can't upload files for that data type" unless klass < Netfira::WebConnect::Model::Record::FileRecord
8
8
 
@@ -4,10 +4,8 @@ module Netfira::WebConnect
4
4
  class Records < Action
5
5
 
6
6
  def call
7
- case verb
8
- when :delete then purge!
9
- else raise MethodNotAllowed
10
- end
7
+ allow :delete
8
+ purge!
11
9
  end
12
10
 
13
11
  private
@@ -2,6 +2,7 @@ class Netfira::WebConnect::RackApp
2
2
  module Action::Version8
3
3
  class Settings < Action
4
4
  def call
5
+ allow :put, :post, :get, :delete
5
6
  key = path && path.first
6
7
  if key
7
8
  handle_single key
@@ -55,6 +56,7 @@ class Netfira::WebConnect::RackApp
55
56
  end
56
57
 
57
58
  def update_multiple
59
+ allow Hash
58
60
  input.each do |key, value|
59
61
  shop.settings[key] = value.unpack('m').first
60
62
  end
@@ -6,6 +6,7 @@ class Netfira::WebConnect::RackApp
6
6
  SEARCH_PATH = [:public, :protected].map { |x| [x, WEB_BASE + x.to_s] }.to_h
7
7
 
8
8
  def call
9
+ allow :get
9
10
  raise NotFound unless path
10
11
  path = self.path.join '/'
11
12
  options = SEARCH_PATH.map do |access, dir|
@@ -14,7 +14,7 @@ module Netfira::WebConnect::RackApp::Exceptions
14
14
  def_delegators :'self.class', :status, :code, :category
15
15
 
16
16
  def initialize(message = nil, details = nil)
17
- super message
17
+ super message || self.class.name.demodulize.underscore.humanize
18
18
  @headers = self.class.headers.dup
19
19
  @details = details
20
20
  end
@@ -1,6 +1,6 @@
1
1
  module Netfira
2
2
  module WebConnect
3
- VERSION = '0.4.10'
3
+ VERSION = '0.4.11'
4
4
  PLATFORM_AND_VERSION = 'Rack/' << VERSION
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.10
4
+ version: 0.4.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil E. Pearson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-18 00:00:00.000000000 Z
12
+ date: 2014-08-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord