open_qq 3.0.1 → 3.0.2
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.
- data/MIT-LICENSE +0 -0
- data/README.md +36 -3
- data/Rakefile +0 -0
- data/lib/generators/open_qq/install_generator.rb +0 -0
- data/lib/generators/templates/open_qq.yml +0 -0
- data/lib/open_qq/error.rb +0 -0
- data/lib/open_qq/gateway.rb +20 -10
- data/lib/open_qq/rails/action_controller.rb +32 -0
- data/lib/open_qq/railtie.rb +7 -1
- data/lib/open_qq/request.rb +0 -0
- data/lib/open_qq/signature.rb +12 -0
- data/lib/open_qq/version.rb +1 -1
- data/lib/open_qq.rb +18 -2
- data/test/benchmark.rb +0 -0
- data/test/open_qq/error_test.rb +0 -0
- data/test/open_qq/gateway_test.rb +8 -0
- data/test/open_qq/request_test.rb +0 -0
- data/test/open_qq/signature_test.rb +24 -0
- data/test/open_qq_test.rb +23 -2
- data/test/test_helper.rb +0 -0
- metadata +4 -3
data/MIT-LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ gem install open_qq
|
|
11
11
|
|
12
12
|
## 使用
|
13
13
|
|
14
|
-
|
14
|
+
使用非常简单,传入应用的`appid`, `appkey`和环境地址`env`
|
15
15
|
|
16
16
|
```ruby
|
17
17
|
require 'rubygems'
|
@@ -19,6 +19,9 @@ require 'open_qq'
|
|
19
19
|
|
20
20
|
OpenQq.setup(:appid => '123', :appkey => '456', :env => 'http://119.147.19.43')
|
21
21
|
|
22
|
+
# 或者https
|
23
|
+
OpenQq.setup(:appid => '123', :appkey => '456', :env => 'https://119.147.19.43')
|
24
|
+
|
22
25
|
# get请求
|
23
26
|
user_info = OpenQq.get('/v3/user/get_info', :openid => '111',:openkey => '222')
|
24
27
|
|
@@ -42,7 +45,7 @@ puts user_info
|
|
42
45
|
```ruby
|
43
46
|
options = {:appid => 'newappid', :appkey => 'newappkey', :env => 'http://newenv'}
|
44
47
|
|
45
|
-
user_info = OpenQq.
|
48
|
+
user_info = OpenQq.call('/v3/user/get_info', options) do |request|
|
46
49
|
|
47
50
|
request.get {:openid => '111',:openkey => '222'}
|
48
51
|
|
@@ -55,6 +58,29 @@ user_info.nickname
|
|
55
58
|
# => 'foo'
|
56
59
|
```
|
57
60
|
|
61
|
+
回调协议签名验证
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
params = {openid: 'test001', appid: '33758', sig: 'VvKwcaMqUNpKhx0XfCvOqPRiAnU%3D'}
|
65
|
+
OpenQq.verify_callback_sig(:get, '/cgi-bin/temp.py', params)
|
66
|
+
# => true or false
|
67
|
+
|
68
|
+
#指定特定的appkey
|
69
|
+
OpenQq.verify_callback_sig(:get, '/cgi-bin/temp.py', params, 'xxxxxx')
|
70
|
+
|
71
|
+
# 在rails中使用
|
72
|
+
class OpenQqController < ApplicationController
|
73
|
+
include OpenQq::Rails::ActionController
|
74
|
+
|
75
|
+
def index
|
76
|
+
if verify_callback_sig
|
77
|
+
...do something
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
```
|
83
|
+
|
58
84
|
## 在rails中使用
|
59
85
|
|
60
86
|
首先在Gemfile中添加
|
@@ -107,4 +133,11 @@ puts sig # 与联调结果比对
|
|
107
133
|
* 测试基本覆盖,可以下载下来执行`rake`
|
108
134
|
* bug反馈[Issue](https://github.com/zires/open_qq/issues)
|
109
135
|
|
110
|
-
|
136
|
+
## Changelog
|
137
|
+
|
138
|
+
* 2012/09/11
|
139
|
+
增加对https的支持
|
140
|
+
支持支付回调协议签名验证
|
141
|
+
|
142
|
+
|
143
|
+
## This project rocks and uses MIT-LICENSE.
|
data/Rakefile
CHANGED
File without changes
|
File without changes
|
File without changes
|
data/lib/open_qq/error.rb
CHANGED
File without changes
|
data/lib/open_qq/gateway.rb
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
require 'open_qq/signature'
|
8
8
|
require 'open_qq/error'
|
9
9
|
require 'ostruct'
|
10
|
-
require 'net/
|
10
|
+
require 'net/https'
|
11
11
|
|
12
12
|
module OpenQq
|
13
13
|
class Gateway
|
@@ -18,7 +18,11 @@ module OpenQq
|
|
18
18
|
|
19
19
|
# @param [String] appid
|
20
20
|
# @param [String] appkey
|
21
|
-
# @param [String] env
|
21
|
+
# @param [String] env 调用的环境地址
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# OpenQq::Gateway.new('1111', '2222', 'http://119.147.19.43')
|
25
|
+
# OpenQq::Gateway.new('1111', '2222', 'https://openapi.tencentyun.com')
|
22
26
|
def initialize(appid, appkey, env)
|
23
27
|
@appid = appid
|
24
28
|
@appkey = appkey
|
@@ -30,6 +34,11 @@ module OpenQq
|
|
30
34
|
@env = env
|
31
35
|
uri = URI.parse(env)
|
32
36
|
@http = Net::HTTP.new(uri.host, uri.port)
|
37
|
+
# HTTPS
|
38
|
+
if uri.scheme == "https"
|
39
|
+
@http.use_ssl = true
|
40
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
41
|
+
end
|
33
42
|
end
|
34
43
|
|
35
44
|
# @param [String] url which api you want to call
|
@@ -46,28 +55,33 @@ module OpenQq
|
|
46
55
|
# user_info = gateway.get('/v3/user/get_info', {:openid => '11'}, {:raw => true} )
|
47
56
|
# user_info.nickname # => '{"nickname":"foo"}'
|
48
57
|
#
|
49
|
-
# @return (
|
58
|
+
# @return (see #call)
|
50
59
|
def get(url, params = {}, options = {})
|
51
|
-
parsed_params = each_pair_escape( wrap(:get, url, params) ).map{|k,v| "#{k}=#{v}"}.join('&')
|
60
|
+
parsed_params = Gateway.each_pair_escape( wrap(:get, url, params) ).map{|k,v| "#{k}=#{v}"}.join('&')
|
52
61
|
get_request = Net::HTTP::Get.new("#{url}?#{parsed_params}")
|
53
62
|
self.call( get_request, options.merge(:format => params[:format]) )
|
54
63
|
end
|
55
64
|
|
56
65
|
# @param (see #get)
|
57
66
|
#
|
58
|
-
# @return (
|
67
|
+
# @return (see #call)
|
59
68
|
def post(url, params = {}, options = {})
|
60
69
|
post_request = Net::HTTP::Post.new(url)
|
61
70
|
post_request.set_form_data wrap(:post, url, params)
|
62
71
|
self.call( post_request, options.merge(:format => params[:format]) )
|
63
72
|
end
|
64
73
|
|
74
|
+
# wrap `http_method`, `url`, `params` together
|
65
75
|
def wrap(http_method, url, params)
|
66
76
|
params = params.merge(:appid => @appid)
|
67
|
-
params[:sig] = signature( "#{@appkey}&", make_source(http_method.to_s.upcase, url, params) )
|
77
|
+
params[:sig] = Gateway.signature( "#{@appkey}&", Gateway.make_source(http_method.to_s.upcase, url, params) )
|
68
78
|
params
|
69
79
|
end
|
70
80
|
|
81
|
+
class << self
|
82
|
+
include Signature
|
83
|
+
end
|
84
|
+
|
71
85
|
protected
|
72
86
|
|
73
87
|
# Call the request and format the output
|
@@ -87,9 +101,5 @@ module OpenQq
|
|
87
101
|
OpenStruct.new( JSON.parse(response.body) )
|
88
102
|
end
|
89
103
|
|
90
|
-
private
|
91
|
-
|
92
|
-
include Signature
|
93
|
-
|
94
104
|
end
|
95
105
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# --
|
4
|
+
# @author zires
|
5
|
+
# @email zshuaibin@gmail.com
|
6
|
+
#
|
7
|
+
module OpenQq
|
8
|
+
module Rails
|
9
|
+
module ActionController
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
private
|
13
|
+
# @example
|
14
|
+
# class OpenQqController < ApplicationController
|
15
|
+
# include OpenQq::Rails::ActionController
|
16
|
+
#
|
17
|
+
# def index
|
18
|
+
# if verify_callback_sig
|
19
|
+
# ...do something
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# @return [Boolean]
|
24
|
+
def verify_callback_sig(key = nil)
|
25
|
+
logger.debug "Appkey: #{key ||= OpenQq.appkey} method: #{request.method} url: #{request.fullpath.split("?")[0]}"
|
26
|
+
logger.debug "params: #{params.slice!(:action, :controller).inspect}"
|
27
|
+
OpenQq.verify_callback_sig(request.method, request.fullpath.split("?")[0], params.slice!(:action, :controller), key)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/open_qq/railtie.rb
CHANGED
data/lib/open_qq/request.rb
CHANGED
File without changes
|
data/lib/open_qq/signature.rb
CHANGED
@@ -28,5 +28,17 @@ module OpenQq
|
|
28
28
|
"#{http_method}&#{url_escape(url)}&#{escape_opt}"
|
29
29
|
end
|
30
30
|
|
31
|
+
def make_callback_source(http_method, url, options)
|
32
|
+
escape_opt = options.sort_by{|k,v| k.to_s}.map do |kv|
|
33
|
+
value = URI.escape(kv.last, /[^0-9a-zA-Z!*()]/)
|
34
|
+
"#{kv.first}=#{value}"
|
35
|
+
end.join('&')
|
36
|
+
"#{http_method}&#{url_escape(url)}&#{url_escape(escape_opt)}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def verify_sig(sig, key, http_method, url, options)
|
40
|
+
sig == url_escape( signature(key, make_callback_source(http_method, url, options)) )
|
41
|
+
end
|
42
|
+
|
31
43
|
end
|
32
44
|
end
|
data/lib/open_qq/version.rb
CHANGED
data/lib/open_qq.rb
CHANGED
@@ -23,10 +23,10 @@ module OpenQq
|
|
23
23
|
delegate :appid, :appkey, :env, :get, :post, :wrap, :to => :@gateway
|
24
24
|
|
25
25
|
# @example
|
26
|
-
# OpenQq.
|
26
|
+
# OpenQq.call('/v3/user/get_info', { :appid => 123 }) do |request|
|
27
27
|
# request.get({:openid => '111'})
|
28
28
|
# end
|
29
|
-
def
|
29
|
+
def call(url, options)
|
30
30
|
request = OpenQq::Request.new(options.with_indifferent_access)
|
31
31
|
if block_given?
|
32
32
|
yield request
|
@@ -35,6 +35,22 @@ module OpenQq
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
alias start call
|
39
|
+
|
40
|
+
# @example
|
41
|
+
# params = {openid: 'test001', appid: '33758', sig: 'VvKwcaMqUNpKhx0XfCvOqPRiAnU%3D'}
|
42
|
+
# OpenQq.verify_callback_sig(:get, '/cgi-bin/temp.py', params)
|
43
|
+
# #diffenert key
|
44
|
+
# OpenQq.verify_callback_sig(:get, '/cgi-bin/temp.py', params, 'xxxxxx')
|
45
|
+
#
|
46
|
+
# @return [Boolean]
|
47
|
+
def verify_callback_sig(http_method, url, params, key = nil)
|
48
|
+
key ||= appkey
|
49
|
+
params = params.dup
|
50
|
+
sig = params.delete('sig') || params.delete(:sig)
|
51
|
+
Gateway.verify_sig(sig, "#{key}&", http_method.to_s.upcase, url, params)
|
52
|
+
end
|
53
|
+
|
38
54
|
end
|
39
55
|
end
|
40
56
|
|
data/test/benchmark.rb
CHANGED
File without changes
|
data/test/open_qq/error_test.rb
CHANGED
File without changes
|
@@ -50,4 +50,12 @@ class OpenQq::GatewayTest < MiniTest::Unit::TestCase
|
|
50
50
|
assert_equal 2001, gateway.get('/v3/user/get_info', params).ret
|
51
51
|
end
|
52
52
|
|
53
|
+
def test_https_request
|
54
|
+
gateway = OpenQq::Gateway.new(@appid, @appkey, 'https://119.147.19.43')
|
55
|
+
http = gateway.instance_variable_get(:@http)
|
56
|
+
assert_equal 443, http.port
|
57
|
+
assert_equal '119.147.19.43', http.address
|
58
|
+
assert http.use_ssl?
|
59
|
+
end
|
60
|
+
|
53
61
|
end
|
File without changes
|
@@ -44,4 +44,28 @@ class OpenQq::SignatureTest < MiniTest::Unit::TestCase
|
|
44
44
|
assert_equal( 'o/nGo1QkVEiiN6Bqn/fRJtEJwLc=', @foo.signature("#{@appkey}&", source) )
|
45
45
|
end
|
46
46
|
|
47
|
+
#测试用例通过http://wiki.open.qq.com/wiki/回调发货URL的协议说明_V3获得
|
48
|
+
def test_make_callback_source
|
49
|
+
params = 'openid=test001&appid=33758&ts=1328855301&payitem=323003*8*1&token=53227955F80B805B50FFB511E5AD51E025360&billno=-APPDJT18700-20120210-1428215572&version=v3&zoneid=1&providetype=0&amt=80&payamt_coins=20&pubacct_payamt_coins=10'
|
50
|
+
options = {}
|
51
|
+
params.split('&').each do |param|
|
52
|
+
param = param.split('=')
|
53
|
+
options[param.first] = param.last
|
54
|
+
end
|
55
|
+
expect = 'GET&%2Fcgi-bin%2Ftemp.py&amt%3D80%26appid%3D33758%26billno%3D%252DAPPDJT18700%252D20120210%252D1428215572%26openid%3Dtest001%26payamt_coins%3D20%26payitem%3D323003%2A8%2A1%26providetype%3D0%26pubacct_payamt_coins%3D10%26token%3D53227955F80B805B50FFB511E5AD51E025360%26ts%3D1328855301%26version%3Dv3%26zoneid%3D1'
|
56
|
+
assert_equal expect, @foo.make_callback_source(:GET, '/cgi-bin/temp.py', options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_verify_sig
|
60
|
+
key = '12345f9a47df4d1eaeb3bad9a7e54321&'
|
61
|
+
sig = 'VvKwcaMqUNpKhx0XfCvOqPRiAnU%3D'
|
62
|
+
params = 'openid=test001&appid=33758&ts=1328855301&payitem=323003*8*1&token=53227955F80B805B50FFB511E5AD51E025360&billno=-APPDJT18700-20120210-1428215572&version=v3&zoneid=1&providetype=0&amt=80&payamt_coins=20&pubacct_payamt_coins=10'
|
63
|
+
options = {}
|
64
|
+
params.split('&').each do |param|
|
65
|
+
param = param.split('=')
|
66
|
+
options[param.first] = param.last
|
67
|
+
end
|
68
|
+
assert @foo.verify_sig(sig, key, :GET, '/cgi-bin/temp.py', options), 'Verify sig failure'
|
69
|
+
end
|
70
|
+
|
47
71
|
end
|
data/test/open_qq_test.rb
CHANGED
@@ -13,7 +13,7 @@ class OpenQqTest < MiniTest::Unit::TestCase
|
|
13
13
|
|
14
14
|
def teardown
|
15
15
|
# Need setup back for the rest test
|
16
|
-
OpenQq.setup{|c| c.appid = 12345}
|
16
|
+
OpenQq.setup{|c| c.appid = 12345;c.appkey ='228bf094169a40a3bd188ba37ebe8723'}
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_OpenQq_is_a_module
|
@@ -74,11 +74,32 @@ class OpenQqTest < MiniTest::Unit::TestCase
|
|
74
74
|
assert_equal 2001, OpenQq.get('/v3/user/get_info', params).ret
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
77
|
+
def test_call_wont_change_get_and_post_method
|
78
|
+
params = { :openid => 1111, 'openkey' => '2222', :pf => :pengyou, :format => 'json' }
|
79
|
+
respond = OpenQq.call('/v3/user/get_info', @options){|r| r.get(params) }
|
80
|
+
assert_equal 'foo', OpenQq.get('/v3/user/get_info', params).nickname
|
81
|
+
assert_equal 'foo', respond.nickname
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_call_has_alise_method_start
|
78
85
|
params = { :openid => 1111, 'openkey' => '2222', :pf => :pengyou, :format => 'json' }
|
79
86
|
respond = OpenQq.start('/v3/user/get_info', @options){|r| r.get(params) }
|
80
87
|
assert_equal 'foo', OpenQq.get('/v3/user/get_info', params).nickname
|
81
88
|
assert_equal 'foo', respond.nickname
|
82
89
|
end
|
83
90
|
|
91
|
+
def test_verify_callback_sig
|
92
|
+
key = '12345f9a47df4d1eaeb3bad9a7e54321'
|
93
|
+
params = 'openid=test001&appid=33758&ts=1328855301&payitem=323003*8*1&token=53227955F80B805B50FFB511E5AD51E025360&billno=-APPDJT18700-20120210-1428215572&version=v3&zoneid=1&providetype=0&amt=80&payamt_coins=20&pubacct_payamt_coins=10'
|
94
|
+
options = {:sig => 'VvKwcaMqUNpKhx0XfCvOqPRiAnU%3D'}
|
95
|
+
params.split('&').each do |param|
|
96
|
+
param = param.split('=')
|
97
|
+
options[param.first] = param.last
|
98
|
+
end
|
99
|
+
assert OpenQq.verify_callback_sig(:GET, '/cgi-bin/temp.py', options, key), 'Verify sig failure 1'
|
100
|
+
OpenQq.setup{|c| c.appkey = key }
|
101
|
+
assert OpenQq.verify_callback_sig(:GET, '/cgi-bin/temp.py', options), 'Verify sig failure 2'
|
102
|
+
assert OpenQq.verify_callback_sig(:get, '/cgi-bin/temp.py', options), 'Verify sig failure 3'
|
103
|
+
end
|
104
|
+
|
84
105
|
end
|
data/test/test_helper.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: open_qq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -107,7 +107,7 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
-
description:
|
110
|
+
description: 腾讯开放平台ruby版SDK(v3版本)http://open.qq.com/
|
111
111
|
email:
|
112
112
|
- zshuaibin@gmail.com
|
113
113
|
executables: []
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- lib/generators/templates/open_qq.yml
|
119
119
|
- lib/open_qq/error.rb
|
120
120
|
- lib/open_qq/gateway.rb
|
121
|
+
- lib/open_qq/rails/action_controller.rb
|
121
122
|
- lib/open_qq/railtie.rb
|
122
123
|
- lib/open_qq/request.rb
|
123
124
|
- lib/open_qq/signature.rb
|