tonglian-ruby-sdk 0.2.0 → 0.3.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tonglian-ruby-sdk.rb +38 -12
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d110ad2c605228b2bcad375d09bdb1054e03f252880adff36ac6f573f3ed01df
4
- data.tar.gz: c116187cd8e449a0965694d7154acf6c0f22ea232f133f3590101255f3c96c26
3
+ metadata.gz: 34e702fea8cfb17cedcc44ca1c3cef1c047b43c35d96904b3e1dd07c5e8ada72
4
+ data.tar.gz: b432d9015bf5dba98ef5921f42b7e742d2440c42487d4919cce2d7cec24c67f0
5
5
  SHA512:
6
- metadata.gz: 017d35a06757cc2375cea897f41a3a8da499e77ae770e71b605e505b2b290d91558686305bd0119d930927d8614bd06e999e33b1c0c120bef9aef599281a37b5
7
- data.tar.gz: 17eb8000f9961dfb76dfe89199831a3364b4befed84973e2250c0145e2e9df15015dece33c01f6937ac79bf128849f0a050df90d4c84da29925721c6d9133e38
6
+ metadata.gz: b2e90a848ff85e07a0689df84c5eb07a6cf01426b7a6b23d4414cd51011306afc509b39557f1d321726a569abeb4453af05035e14ca0f99dfc6d85c58499d069
7
+ data.tar.gz: 520cc51c2a2a1933d377e16ec83cdbae62e756a2dc33d7defa744c244b0d061acfd7f3645e88fd2351c694cb3cbe38be0a448abe6254b2ec9aef0cc17ff75993
@@ -1,5 +1,7 @@
1
1
  # to avoid error when loading PKCS12 private key file
2
- ENV['OPENSSL_CONF'] = './add-openssl-provider.conf'
2
+ current_dir = File.dirname(__FILE__)
3
+ provider_conf = File.join(current_dir, 'add-openssl-provider.conf')
4
+ ENV['OPENSSL_CONF'] = provider_conf
3
5
 
4
6
  require 'openssl'
5
7
  require 'cgi'
@@ -33,7 +35,6 @@ module TonglianRubySdk
33
35
  data['sign'] = @signer.sign(data)
34
36
 
35
37
  url = URI(@api_end_point)
36
-
37
38
  http = Net::HTTP.new(url.host, url.port)
38
39
  http.use_ssl = true if @api_end_point.downcase.starts_with?('https') # Enable SSL for HTTPS
39
40
 
@@ -42,9 +43,9 @@ module TonglianRubySdk
42
43
  request.body = URI.encode_www_form(data)
43
44
  response = http.request(request)
44
45
 
45
- # Handle response
46
- puts response.code
47
- puts response.body
46
+ object = JSON.parse(response.body)
47
+ @signer.verify?(object) || raise('Invalid response signature!')
48
+ { 'code' => response.code, 'data' => object }
48
49
  end
49
50
 
50
51
  private
@@ -65,25 +66,26 @@ module TonglianRubySdk
65
66
  end
66
67
 
67
68
  def sign(params)
68
- str = make_sign_message(params)
69
+ message = make_sign_message(params)
69
70
  rsa = OpenSSL::PKey::RSA.new private_key
70
- Base64.strict_encode64(rsa.sign('sha1', str.force_encoding('UTF-8')))
71
+ Base64.strict_encode64(rsa.sign(OpenSSL::Digest.new('SHA256'), message))
71
72
  end
72
73
 
73
74
  def verify?(params, signature = nil)
74
75
  signature = params['sign'] if signature.nil? || signature.to_s.empty?
75
- str = make_sign_message(params)
76
+ params.delete('sign')
77
+ message = make_verify_message(params)
78
+
76
79
  public_file = File.open(@public_path)
77
80
  public_key = OpenSSL::X509::Certificate.new(public_file).public_key.export
78
81
  rsa = OpenSSL::PKey::RSA.new(public_key)
79
- rsa.verify('sha1', Base64.decode64(signature), str)
82
+ rsa.verify(OpenSSL::Digest.new('SHA256'), Base64.decode64(signature), message)
80
83
  end
81
84
 
82
85
  private
83
86
 
84
87
  def private_key
85
88
  return @private_key if @private_key
86
-
87
89
  private_file = File.open(@private_path)
88
90
  @private_key = OpenSSL::PKCS12.new(private_file, @private_passwd).key.export
89
91
  end
@@ -100,11 +102,35 @@ module TonglianRubySdk
100
102
  params.keys.sort.map do |k|
101
103
  next if %w[sign signType].include? k
102
104
  next if params[k].nil? || params[k].to_s.empty?
103
- #sorted_params.push("#{k}=#{CGI.escape(params[k])}")
105
+
104
106
  sorted_params.push("#{k}=#{params[k]}")
105
107
  end
106
108
 
107
- Base64.strict_encode64(Digest::MD5.hexdigest(sorted_params.join('&')))
109
+ flattened_params = sorted_params.join('&')
110
+ md5_digest = Digest::MD5.digest(flattened_params)
111
+ Base64.strict_encode64(md5_digest)
112
+ end
113
+
114
+ def make_verify_message(params)
115
+ params = sort_object(params)
116
+ flattened_params = params.to_json
117
+ Base64.strict_encode64(Digest::MD5.digest(flattened_params))
118
+ end
119
+
120
+ # In Ruby 3, a hash preserves the order the keys are inserted
121
+ # So we can make a 'sorted' hash and generate a sorted json later
122
+ def sort_object(obj)
123
+ result = nil
124
+ if obj.is_a? Hash
125
+ result = {}
126
+ obj.keys.sort.each { |k| result[k] = sort_object(obj[k]) }
127
+ elsif obj.is_a? Array
128
+ result = []
129
+ obj.sort.each { |k| result.push(k) }
130
+ else
131
+ result = obj
132
+ end
133
+ result
108
134
  end
109
135
  end
110
136
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tonglian-ruby-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yi Zhang