baidu-sdk 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|