baidu-sdk 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +1 -0
- data/Gemfile +17 -0
- data/Guardfile +6 -0
- data/HISTORY.md +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +161 -0
- data/Rakefile +4 -0
- data/baidu-pcs.gemspec +24 -0
- data/lib/baidu/configure.rb +27 -0
- data/lib/baidu/core.rb +19 -0
- data/lib/baidu/errors/error.rb +22 -0
- data/lib/baidu/oauth.rb +11 -0
- data/lib/baidu/oauth/client.rb +66 -0
- data/lib/baidu/oauth/flow/base.rb +44 -0
- data/lib/baidu/oauth/flow/code.rb +69 -0
- data/lib/baidu/oauth/flow/device.rb +75 -0
- data/lib/baidu/pcs.rb +19 -0
- data/lib/baidu/pcs/client.rb +1090 -0
- data/lib/baidu/session.rb +36 -0
- data/lib/baidu/support/cacert.pem +37 -0
- data/lib/baidu/support/request.rb +127 -0
- data/lib/baidu/support/util.rb +67 -0
- data/lib/baidu/version.rb +5 -0
- data/spec/baidu/core_spec.rb +20 -0
- data/spec/baidu/oauth/client_spec.rb +199 -0
- data/spec/baidu/pcs/client_spec.rb +878 -0
- data/spec/baidu/session_spec.rb +27 -0
- data/spec/baidu/support/request_spec.rb +58 -0
- data/spec/baidu/support/util_spec.rb +48 -0
- data/spec/fixtures/add_task.json +1 -0
- data/spec/fixtures/cancel_task.json +3 -0
- data/spec/fixtures/copy.json +7 -0
- data/spec/fixtures/delete.json +3 -0
- data/spec/fixtures/diff.json +17 -0
- data/spec/fixtures/empty.json +1 -0
- data/spec/fixtures/get_token_code.json +8 -0
- data/spec/fixtures/get_token_device.json +8 -0
- data/spec/fixtures/list.json +11 -0
- data/spec/fixtures/list_task_0.json +1 -0
- data/spec/fixtures/list_task_1.json +1 -0
- data/spec/fixtures/listrecycle.json +23 -0
- data/spec/fixtures/logo.png +0 -0
- data/spec/fixtures/meta.json +11 -0
- data/spec/fixtures/mkdir.json +7 -0
- data/spec/fixtures/move.json +8 -0
- data/spec/fixtures/query_task_0.json +24 -0
- data/spec/fixtures/query_task_1.json +22 -0
- data/spec/fixtures/quota.json +5 -0
- data/spec/fixtures/rapidupload.json +10 -0
- data/spec/fixtures/refresh_token.json +8 -0
- data/spec/fixtures/restore.json +1 -0
- data/spec/fixtures/search.json +11 -0
- data/spec/fixtures/stream_list.json +16 -0
- data/spec/fixtures/streaming.m3u8 +5 -0
- data/spec/fixtures/upload.json +9 -0
- data/spec/fixtures/upload_block.json +4 -0
- data/spec/fixtures/user_and_device_code.json +8 -0
- data/spec/spec_helper.rb +66 -0
- metadata +169 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Baidu
|
4
|
+
class Session
|
5
|
+
# 用户身份验证和授权的凭证
|
6
|
+
# @return [String]
|
7
|
+
attr_accessor :access_token
|
8
|
+
# 用于刷新 Access Token 的 Refresh Token,并不是所有应用都会返回该参数(10年的有效期)
|
9
|
+
# @return [String]
|
10
|
+
attr_accessor :refresh_token
|
11
|
+
# Access Token 最终的访问范围,即用户实际授予的权限列表
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :scope
|
14
|
+
# 基于 http 调用 Open API 时所需要的 Session Key
|
15
|
+
# @return [String]
|
16
|
+
attr_accessor :session_key
|
17
|
+
# 基于 http 调用 Open API 时计算参数签名用的签名密钥
|
18
|
+
# @return [String]
|
19
|
+
attr_accessor :session_secret
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# 根据 Hash 数据创建一个新的 +Session+ 实例
|
23
|
+
# @param [Hash] hash 包含 Session 所需数据的 Hash
|
24
|
+
# @return [Session]
|
25
|
+
def from(hash)
|
26
|
+
session = Session.new
|
27
|
+
session.access_token = hash[:access_token]
|
28
|
+
session.refresh_token = hash[:refresh_token]
|
29
|
+
session.scope = hash[:scope]
|
30
|
+
session.session_key = hash[:session_key]
|
31
|
+
session.session_secret = hash[:session_secret]
|
32
|
+
session
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
VeriSign Class 3 International Server CA - G3
|
2
|
+
=============================================
|
3
|
+
-----BEGIN CERTIFICATE-----
|
4
|
+
MIIGKTCCBRGgAwIBAgIQZBvoIM4CCBPzLU0tldZ+ZzANBgkqhkiG9w0BAQUFADCB
|
5
|
+
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
|
6
|
+
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
|
7
|
+
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
|
8
|
+
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
|
9
|
+
aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBvDEL
|
10
|
+
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
|
11
|
+
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
|
12
|
+
aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMtVmVy
|
13
|
+
aVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMIIBIjAN
|
14
|
+
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdacYvAV9IGaQQhZjxOdF8mfUdza
|
15
|
+
sVLv/+NB3eDfxCjG4615HycQmLi7IJfBKERBD+qpqFLPTU4bi7u1xHbZzFYG7rNV
|
16
|
+
ICreFY1xy1TIbxfNiQDk3P/hwB9ocenHKS5+vDv85burJlSLZpDN9pK5MSSAvJ5s
|
17
|
+
1fx+0uFLjNxC+kRLX/gYtS4w9D0SmNNiBXNUppyiHb5SgzoHRsQ7AlYhv/JRT9Cm
|
18
|
+
mTnprqU/iZucff5NYAclIPe712mDK4KTQzfZg0EbawurSmaET0qO3n40mY5o1so5
|
19
|
+
BptMs5pITRNGtFghBMT7oE2sLktiEuP7TfbJUQABH/weaoEqOOC5T9YtRQIDAQAB
|
20
|
+
o4ICFTCCAhEwEgYDVR0TAQH/BAgwBgEB/wIBADBwBgNVHSAEaTBnMGUGC2CGSAGG
|
21
|
+
+EUBBxcDMFYwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9j
|
22
|
+
cHMwKgYIKwYBBQUHAgIwHhocaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTAO
|
23
|
+
BgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
|
24
|
+
Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDov
|
25
|
+
L2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwNAYDVR0lBC0wKwYIKwYBBQUH
|
26
|
+
AwEGCCsGAQUFBwMCBglghkgBhvhCBAEGCmCGSAGG+EUBCAEwNAYIKwYBBQUHAQEE
|
27
|
+
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wNAYDVR0f
|
28
|
+
BC0wKzApoCegJYYjaHR0cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy1nNS5jcmww
|
29
|
+
KAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFZlcmlTaWduTVBLSS0yLTcwHQYDVR0O
|
30
|
+
BBYEFNebfNgioBX33a1fzimbWMO8RgC1MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ
|
31
|
+
80M5+gKvMzEzMA0GCSqGSIb3DQEBBQUAA4IBAQBxtX1zUkrd1000Ky6vlEalSVAC
|
32
|
+
T/gvF3DyE9wfIYaqwk98NzzURniuXXhv0bpavBCrWDbFjGIVRWAXIeLVQqh3oVXY
|
33
|
+
QwRR9m66SOZdTLdE0z6k1dYzmp8N5tdOlkSVWmzWoxZTDphDzqS4w2Z6BVxiEOgb
|
34
|
+
Ett9LnZQ/9/XaxvMisxx+rNAVnwzeneUW/ULU/sOX7xo+68q7jA3eRaTJX9NEP9X
|
35
|
+
+79uOzMh3nnchhdZLUNkt6Zmh+q8lkYZGoaLb9e3SQBb26O/KZru99MzrqP0nkzK
|
36
|
+
XmnUG623kHdq2FlveasB+lXwiiFm5WVu/XzT3x7rfj8GkPsZC9MGAht4Q5mo
|
37
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Baidu
|
4
|
+
module Support
|
5
|
+
module Request
|
6
|
+
include Baidu::Support
|
7
|
+
|
8
|
+
# 最多重定向次数
|
9
|
+
MAX_REDIRECT_LIMIT = 10
|
10
|
+
|
11
|
+
# 发送 GET 请求
|
12
|
+
#
|
13
|
+
# @param [String] path
|
14
|
+
# @param [Hash] query 自动清理 value 为 nil 的数据
|
15
|
+
# @option options [String] :site
|
16
|
+
# @option options [Boolean] :raw 直接返回 response.body
|
17
|
+
# @option options [Hash] :headers
|
18
|
+
# @yield [segment] 可选,如果提供 block,则以流的方式获取内容
|
19
|
+
def get(path, query={}, options={}, &block)
|
20
|
+
url = build_url path, query, options[:site]
|
21
|
+
req = Net::HTTP::Get.new(url, options[:headers])
|
22
|
+
if block_given?
|
23
|
+
request(req) do |resp|
|
24
|
+
resp.read_body &block
|
25
|
+
end
|
26
|
+
else
|
27
|
+
request(req, nil, options[:raw])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# 发送 POST 请求
|
32
|
+
#
|
33
|
+
# @param [String] path
|
34
|
+
# @param [Hash] query 自动清理 value 为 nil 的数据
|
35
|
+
# @param [Hash] body 自动清理 value 为 nil 的数据,可以包含响应 +#read+ 的对象,如:+File+
|
36
|
+
# @option options [String] :site
|
37
|
+
def post(path, query={}, body={}, options={})
|
38
|
+
uri = build_url path, query, options[:site]
|
39
|
+
Util.clean_params(body)
|
40
|
+
if body.select{ |_, v| v.respond_to? :read }.empty?
|
41
|
+
req = Net::HTTP::Post.new uri
|
42
|
+
req.body = (body.empty? ? nil : Util.encode_params(body))
|
43
|
+
else
|
44
|
+
require 'net/http/post/multipart'
|
45
|
+
body.each { |k, v| body[k] = UploadIO.new v, 'application/octet-stream' if v.respond_to? :read }
|
46
|
+
req = Net::HTTP::Post::Multipart.new uri, body
|
47
|
+
end
|
48
|
+
request req
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def request(req, body=nil, raw=false, limit=0, &block)
|
54
|
+
uri = URI(req.path)
|
55
|
+
http = Net::HTTP.new uri.host, uri.port
|
56
|
+
# trick for 1.9 support, just use req.uri for ruby version 2
|
57
|
+
path_uri = URI(uri.path)
|
58
|
+
path_uri.query = uri.query
|
59
|
+
req.instance_variable_set(:@path, path_uri.to_s)
|
60
|
+
# end trick
|
61
|
+
http.set_debug_output $stdout if Baidu.debug
|
62
|
+
http.use_ssl = uri.scheme == 'https'
|
63
|
+
if http.use_ssl?
|
64
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
65
|
+
http.cert_store = OpenSSL::X509::Store.new
|
66
|
+
http.cert_store.set_default_paths
|
67
|
+
http.cert_store.add_file File.expand_path('../cacert.pem', __FILE__)
|
68
|
+
end
|
69
|
+
|
70
|
+
req['User-Agent'] = "UnofficialRubySDK/baidu-sdk/#{Baidu::VERSION}"
|
71
|
+
|
72
|
+
if block_given?
|
73
|
+
# To avoid read_body read called twice
|
74
|
+
return http.request req, body, &block
|
75
|
+
else
|
76
|
+
resp = http.request req, body
|
77
|
+
resp_body = resp.body
|
78
|
+
|
79
|
+
# when raw, return quickly without JSON parse
|
80
|
+
return resp_body if resp.is_a?(Net::HTTPSuccess) && raw
|
81
|
+
|
82
|
+
resp_hash = begin
|
83
|
+
JSON.parse(resp_body, symbolize_names: true) unless resp_body.nil?
|
84
|
+
rescue
|
85
|
+
nil
|
86
|
+
end || {}
|
87
|
+
|
88
|
+
case resp
|
89
|
+
when Net::HTTPSuccess
|
90
|
+
return resp_hash
|
91
|
+
when Net::HTTPRedirection
|
92
|
+
# Process redirection
|
93
|
+
limit += 1
|
94
|
+
return process_redirect resp['Location'], raw, limit
|
95
|
+
end
|
96
|
+
|
97
|
+
# error
|
98
|
+
err = case resp
|
99
|
+
when Net::HTTPUnauthorized then Baidu::Errors::AuthError
|
100
|
+
when Net::HTTPClientError then Baidu::Errors::ClientError
|
101
|
+
when Net::HTTPServerError then Baidu::Errors::ServerError
|
102
|
+
else Baidu::Errors::Error
|
103
|
+
end
|
104
|
+
|
105
|
+
code = resp_hash.nil? ? resp.code : (resp_hash[:error_code] || resp_hash[:error])
|
106
|
+
msg = resp_hash.nil? ? resp.msg : (resp_hash[:error_msg] || resp_hash[:error_description])
|
107
|
+
raise err.new(msg, code, resp)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_url(path, query, site)
|
112
|
+
uri = URI(site || @site)
|
113
|
+
uri.path = path
|
114
|
+
unless Util.blank? query
|
115
|
+
Util.clean_params query
|
116
|
+
uri.query = Util.encode_params(query)
|
117
|
+
end
|
118
|
+
uri.to_s
|
119
|
+
end
|
120
|
+
|
121
|
+
def process_redirect(url, raw, limit)
|
122
|
+
raise Baidu::Errors::Error.new('Too many redirects') if limit > MAX_REDIRECT_LIMIT
|
123
|
+
request(Net::HTTP::Get.new(url), nil, raw, limit)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Baidu
|
4
|
+
module Support
|
5
|
+
module Util
|
6
|
+
class << self
|
7
|
+
# Check whether +obj+ is blank or not
|
8
|
+
# @example
|
9
|
+
# blank?(' ') #true
|
10
|
+
# blank?('i ') #false
|
11
|
+
# blank?(nil) #true
|
12
|
+
# blank?(true) #false
|
13
|
+
# blank?(false) #true
|
14
|
+
# blank?({}) #true
|
15
|
+
#
|
16
|
+
# @param [Object] obj
|
17
|
+
def blank?(obj)
|
18
|
+
case obj
|
19
|
+
when String then /[^[:space:]]/ !~ obj
|
20
|
+
when NilClass then true
|
21
|
+
when TrueClass then false
|
22
|
+
when FalseClass then true
|
23
|
+
else obj.respond_to?(:empty?) ? obj.empty? : !obj
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Encode params to www form style
|
28
|
+
# @example
|
29
|
+
# encode_params({first: 'Lonre', last: 'Wang'})
|
30
|
+
# => 'first=Lonre&last=Wang'
|
31
|
+
# @param [Hash] params
|
32
|
+
# @return [String]
|
33
|
+
def encode_params(params)
|
34
|
+
raise ArgumentError, 'require Hash instance' unless params.is_a? Hash
|
35
|
+
URI::encode_www_form params
|
36
|
+
end
|
37
|
+
|
38
|
+
# Delete object which value is +nil+ from params
|
39
|
+
# @example
|
40
|
+
# clean_params({first: 'Lonre', middle: nil, last: 'Wang'})
|
41
|
+
# => {first: 'Lonre', last: 'Wang'}
|
42
|
+
# @param [Hash] params
|
43
|
+
# @return [Hash]
|
44
|
+
def clean_params(params)
|
45
|
+
raise ArgumentError, 'require Hash instance' unless params.is_a? Hash
|
46
|
+
unless blank? params
|
47
|
+
params.delete_if { |k, v| v.nil? }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Change +"\\ ? | " > < : "*+ to +"_"+, multi "/" to one "/"
|
52
|
+
# @example
|
53
|
+
# edit_path(" .hello///path<f:aa/go.zip. ")
|
54
|
+
# => "hello/path_f_aa/go.zip"
|
55
|
+
# @return [String]
|
56
|
+
def edit_path(path)
|
57
|
+
return nil if path.nil?
|
58
|
+
path = path.gsub(/\/+/, '/')
|
59
|
+
path = path.gsub(/\A[\s\.]*/, '')
|
60
|
+
path = path.gsub(/[\s\.]*\z/, '')
|
61
|
+
path = path.gsub(/[\\\|\?"><:\*]/, '_')
|
62
|
+
path
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Baidu do
|
6
|
+
describe '.config' do
|
7
|
+
before do
|
8
|
+
Baidu.config {}
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'has default debug config' do
|
12
|
+
expect(Baidu.debug).to be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets debug config to true' do
|
16
|
+
Baidu.config { |c| c.debug = true }
|
17
|
+
expect(Baidu.debug).to be_true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'baidu/oauth'
|
5
|
+
|
6
|
+
describe Baidu::OAuth::Client do
|
7
|
+
let(:authorization_endpoint) { 'https://openapi.baidu.com/oauth/2.0/authorize' }
|
8
|
+
let(:device_endpoint) { 'https://openapi.baidu.com/oauth/2.0/device/code' }
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
Baidu.config do |c|
|
12
|
+
c.client_id = 'ci'
|
13
|
+
c.client_secret = 'cs'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
@client = Baidu::OAuth::Client.new do |config|
|
19
|
+
config.access_token = 'at'
|
20
|
+
config.refresh_token = 'rt'
|
21
|
+
config.session_key = 'sk'
|
22
|
+
config.session_secret = 'ss'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context '.initialize' do
|
27
|
+
it 'assigns right config' do
|
28
|
+
expect(@client.client_id).to eq('ci')
|
29
|
+
expect(@client.client_secret).to eq('cs')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'overwrites client_id and client_secret' do
|
33
|
+
@client = Baidu::OAuth::Client.new('ci2', 'cs2')
|
34
|
+
expect(@client.client_id).to eq('ci2')
|
35
|
+
expect(@client.client_secret).to eq('cs2')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not touch endpoint' do
|
39
|
+
expect(Baidu::OAuth::SITE).to eq('https://openapi.baidu.com')
|
40
|
+
expect(Baidu::OAuth::AUTHORIZATION_ENDPOINT).to eq('/oauth/2.0/authorize')
|
41
|
+
expect(Baidu::OAuth::TOKEN_ENDPOINT).to eq('/oauth/2.0/token')
|
42
|
+
expect(@client.instance_variable_get('@site')).to eq('https://openapi.baidu.com')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context '#authorize_url' do
|
47
|
+
it 'generates "Authorization Code" authorize url' do
|
48
|
+
url = @client.code_flow.authorize_url('oob')
|
49
|
+
expect(url).to eq("#{authorization_endpoint}?response_type=code&display=page&" \
|
50
|
+
"client_id=ci&redirect_uri=oob")
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'generates "Authorization Code" authorize url with params' do
|
54
|
+
url = @client.code_flow.authorize_url('http://www.example.com/oauth_redirect',
|
55
|
+
scope: 'email', state: 'xyz', display: 'tv',
|
56
|
+
force_login: 1, confirm_login: 1)
|
57
|
+
expect(url).to eq("#{authorization_endpoint}?response_type=code&display=tv&" \
|
58
|
+
"scope=email&state=xyz&force_login=1&confirm_login=1&client_id=ci&" \
|
59
|
+
"redirect_uri=http%3A%2F%2Fwww.example.com%2Foauth_redirect")
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises error when using device flow' do
|
63
|
+
expect {
|
64
|
+
@client.device_flow.authorize_url
|
65
|
+
}.to raise_error(NoMethodError, 'no such method in device flow')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context '#user_and_device_code' do
|
70
|
+
|
71
|
+
it 'requests user and device code' do
|
72
|
+
stub_get(:oauth, '/oauth/2.0/device/code', client_id: 'ci', response_type: 'device_code').
|
73
|
+
to_return(status: 200, body: ft('user_and_device_code.json'))
|
74
|
+
@client.device_flow.user_and_device_code
|
75
|
+
a_get(:oauth, '/oauth/2.0/device/code', client_id: 'ci', response_type: 'device_code').
|
76
|
+
should have_been_made
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'requests user and device code with scope' do
|
80
|
+
stub_get(:oauth, '/oauth/2.0/device/code', client_id: 'ci',
|
81
|
+
response_type: 'device_code', scope: 'basic netdisk').
|
82
|
+
to_return(status: 200, body: ft('user_and_device_code.json'))
|
83
|
+
@client.device_flow.user_and_device_code 'basic netdisk'
|
84
|
+
a_get(:oauth, '/oauth/2.0/device/code', client_id: 'ci',
|
85
|
+
response_type: 'device_code', scope: 'basic netdisk').
|
86
|
+
should have_been_made
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'responses user and device code' do
|
90
|
+
stub_get(:oauth, '/oauth/2.0/device/code', client_id: 'ci', response_type: 'device_code').
|
91
|
+
to_return(status: 200, body: ft('user_and_device_code.json'))
|
92
|
+
result = @client.device_flow.user_and_device_code
|
93
|
+
expect(result).to be_instance_of(Hash)
|
94
|
+
expect(result).to have_key(:device_code)
|
95
|
+
expect(result).to have_key(:user_code)
|
96
|
+
expect(result).to have_key(:verification_url)
|
97
|
+
expect(result).to have_key(:qrcode_url)
|
98
|
+
expect(result).to have_key(:expires_in)
|
99
|
+
expect(result).to have_key(:interval)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context '#get_token' do
|
104
|
+
context 'with code flow' do
|
105
|
+
before do
|
106
|
+
stub_post(:oauth, '/oauth/2.0/token',
|
107
|
+
grant_type: 'authorization_code',
|
108
|
+
code: 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
|
109
|
+
client_id: 'ci', client_secret: 'cs',
|
110
|
+
redirect_uri: 'http://www.example.com/oauth_redirect').
|
111
|
+
to_return(status: 200, body: ft('get_token_code.json'))
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'requests access tokey' do
|
115
|
+
@client.code_flow.get_token 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
|
116
|
+
'http://www.example.com/oauth_redirect'
|
117
|
+
a_post(:oauth, '/oauth/2.0/token',
|
118
|
+
grant_type: 'authorization_code',
|
119
|
+
code: 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
|
120
|
+
client_id: 'ci', client_secret: 'cs',
|
121
|
+
redirect_uri: 'http://www.example.com/oauth_redirect').should have_been_made
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'responses access token' do
|
125
|
+
result = @client.code_flow.get_token 'ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn',
|
126
|
+
'http://www.example.com/oauth_redirect'
|
127
|
+
expect(result).to be_instance_of(Baidu::Session)
|
128
|
+
expect(result).to respond_to(:access_token)
|
129
|
+
expect(result).to respond_to(:refresh_token)
|
130
|
+
expect(result).to respond_to(:scope)
|
131
|
+
expect(result).to respond_to(:session_key)
|
132
|
+
expect(result).to respond_to(:session_secret)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with device flow' do
|
137
|
+
before do
|
138
|
+
stub_post(:oauth, '/oauth/2.0/token', grant_type: 'device_token',
|
139
|
+
code: 'a82hjs723h72h3a82hjs723h72h3vb', client_id: 'ci', client_secret: 'cs').
|
140
|
+
to_return(status: 200, body: ft('get_token_device.json'))
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'requests access tokey' do
|
144
|
+
@client.device_flow.get_token 'a82hjs723h72h3a82hjs723h72h3vb'
|
145
|
+
a_post(:oauth, '/oauth/2.0/token', grant_type: 'device_token',
|
146
|
+
code: 'a82hjs723h72h3a82hjs723h72h3vb',
|
147
|
+
client_id: 'ci', client_secret: 'cs').should have_been_made
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'responses access token' do
|
151
|
+
result = @client.device_flow.get_token 'a82hjs723h72h3a82hjs723h72h3vb'
|
152
|
+
expect(result).to be_instance_of(Baidu::Session)
|
153
|
+
expect(result).to respond_to(:access_token)
|
154
|
+
expect(result).to respond_to(:refresh_token)
|
155
|
+
expect(result).to respond_to(:scope)
|
156
|
+
expect(result).to respond_to(:session_key)
|
157
|
+
expect(result).to respond_to(:session_secret)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context '#refresh_token' do
|
163
|
+
before do
|
164
|
+
stub_post(:oauth, '/oauth/2.0/token', grant_type: 'refresh_token',
|
165
|
+
refresh_token: '2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328',
|
166
|
+
client_id: 'ci', client_secret: 'cs').
|
167
|
+
to_return(status: 200, body: ft('refresh_token.json'))
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'requests access token by refresh token' do
|
171
|
+
@client.refresh('2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328')
|
172
|
+
a_post(:oauth, '/oauth/2.0/token', grant_type: 'refresh_token',
|
173
|
+
refresh_token: '2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328',
|
174
|
+
client_id: 'ci', client_secret: 'cs').should have_been_made
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'requests access token by refresh token with params' do
|
178
|
+
stub_post(:oauth, '/oauth/2.0/token', grant_type: 'refresh_token',
|
179
|
+
refresh_token: '2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328',
|
180
|
+
scope: 'basic netdisk', client_id: 'ci', client_secret: 'cs').
|
181
|
+
to_return(status: 200, body: ft('refresh_token.json'))
|
182
|
+
@client.refresh('2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328',
|
183
|
+
scope: 'basic netdisk')
|
184
|
+
a_post(:oauth, '/oauth/2.0/token', grant_type: 'refresh_token',
|
185
|
+
refresh_token: '2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328',
|
186
|
+
scope: 'basic netdisk', client_id: 'ci', client_secret: 'cs').should have_been_made
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'responses access token by refresh token' do
|
190
|
+
result = @client.refresh('2.af3d55f8615fdfd9edb7c4b5ebdc3e32.604800.1293440400-2346678-124328')
|
191
|
+
expect(result).to be_instance_of(Baidu::Session)
|
192
|
+
expect(result).to respond_to(:access_token)
|
193
|
+
expect(result).to respond_to(:refresh_token)
|
194
|
+
expect(result).to respond_to(:scope)
|
195
|
+
expect(result).to respond_to(:session_key)
|
196
|
+
expect(result).to respond_to(:session_secret)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|