Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
hexbee
Cloudreve
提交
0d2e3cc7
C
Cloudreve
项目概览
hexbee
/
Cloudreve
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Cloudreve
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0d2e3cc7
编写于
1月 22, 2020
作者:
H
HFO4
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Test: Onedrive.OAuth
上级
d3f132de
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
405 addition
and
28 deletion
+405
-28
pkg/filesystem/driver/onedrive/api.go
pkg/filesystem/driver/onedrive/api.go
+27
-21
pkg/filesystem/driver/onedrive/client.go
pkg/filesystem/driver/onedrive/client.go
+6
-1
pkg/filesystem/driver/onedrive/client_test.go
pkg/filesystem/driver/onedrive/client_test.go
+7
-0
pkg/filesystem/driver/onedrive/oauth_test.go
pkg/filesystem/driver/onedrive/oauth_test.go
+365
-0
pkg/filesystem/driver/oss/callback_test.go
pkg/filesystem/driver/oss/callback_test.go
+0
-5
pkg/filesystem/upload.go
pkg/filesystem/upload.go
+0
-1
未找到文件。
pkg/filesystem/driver/onedrive/api.go
浏览文件 @
0d2e3cc7
...
...
@@ -197,27 +197,33 @@ func (client *Client) Upload(ctx context.Context, dst string, size int, file io.
chunkNum
++
}
for
i
:=
0
;
i
<
chunkNum
;
i
++
{
// 分块
// TODO 取消上传
chunkSize
:=
int
(
ChunkSize
)
if
size
-
offset
<
chunkSize
{
chunkSize
=
size
-
offset
}
chunk
:=
Chunk
{
Offset
:
offset
,
ChunkSize
:
chunkSize
,
Total
:
size
,
Reader
:
&
io
.
LimitedReader
{
R
:
file
,
N
:
int64
(
chunkSize
),
},
}
// 上传
_
,
err
:=
client
.
UploadChunk
(
ctx
,
uploadURL
,
&
chunk
)
if
err
!=
nil
{
return
err
select
{
case
<-
ctx
.
Done
()
:
util
.
Log
()
.
Debug
(
"OneDrive 客户端取消"
)
return
ErrClientCanceled
default
:
// 分块
chunkSize
:=
int
(
ChunkSize
)
if
size
-
offset
<
chunkSize
{
chunkSize
=
size
-
offset
}
chunk
:=
Chunk
{
Offset
:
offset
,
ChunkSize
:
chunkSize
,
Total
:
size
,
Reader
:
&
io
.
LimitedReader
{
R
:
file
,
N
:
int64
(
chunkSize
),
},
}
// 上传
_
,
err
:=
client
.
UploadChunk
(
ctx
,
uploadURL
,
&
chunk
)
if
err
!=
nil
{
return
err
}
offset
+=
chunkSize
}
offset
+=
chunkSize
}
return
nil
}
...
...
@@ -274,7 +280,7 @@ func (client *Client) Delete(ctx context.Context, dst []string) ([]string, error
// 取得删除失败的文件
failed
:=
getDeleteFailed
(
&
deleteRes
)
if
len
(
failed
)
!=
0
{
return
failed
,
errors
.
New
(
"无法删除文件"
)
return
failed
,
ErrDeleteFile
}
return
failed
,
nil
}
...
...
pkg/filesystem/driver/onedrive/client.go
浏览文件 @
0d2e3cc7
...
...
@@ -8,8 +8,13 @@ import (
var
(
// ErrAuthEndpoint 无法解析授权端点地址
ErrAuthEndpoint
=
errors
.
New
(
"无法解析授权端点地址"
)
ErrAuthEndpoint
=
errors
.
New
(
"无法解析授权端点地址"
)
// ErrInvalidRefreshToken 上传策略无有效的RefreshToken
ErrInvalidRefreshToken
=
errors
.
New
(
"上传策略无有效的RefreshToken"
)
// ErrDeleteFile 无法删除文件
ErrDeleteFile
=
errors
.
New
(
"无法删除文件"
)
// ErrClientCanceled 客户端取消操作
ErrClientCanceled
=
errors
.
New
(
"客户端取消操作"
)
)
// Client OneDrive客户端
...
...
pkg/filesystem/driver/onedrive/client_test.go
0 → 100644
浏览文件 @
0d2e3cc7
package
onedrive
import
"testing"
func
TestNewClient
(
t
*
testing
.
T
)
{
}
pkg/filesystem/driver/onedrive/oauth_test.go
0 → 100644
浏览文件 @
0d2e3cc7
package
onedrive
import
(
"context"
"database/sql"
"errors"
"github.com/DATA-DOG/go-sqlmock"
model
"github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/cache"
"github.com/HFO4/cloudreve/pkg/request"
"github.com/jinzhu/gorm"
"github.com/stretchr/testify/assert"
testMock
"github.com/stretchr/testify/mock"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"testing"
"time"
)
var
mock
sqlmock
.
Sqlmock
// TestMain 初始化数据库Mock
func
TestMain
(
m
*
testing
.
M
)
{
var
db
*
sql
.
DB
var
err
error
db
,
mock
,
err
=
sqlmock
.
New
()
if
err
!=
nil
{
panic
(
"An error was not expected when opening a stub database connection"
)
}
model
.
DB
,
_
=
gorm
.
Open
(
"mysql"
,
db
)
defer
db
.
Close
()
m
.
Run
()
}
func
TestGetOAuthEndpoint
(
t
*
testing
.
T
)
{
asserts
:=
assert
.
New
(
t
)
// URL解析失败
{
client
:=
Client
{
Endpoints
:
&
Endpoints
{
OAuthURL
:
string
([]
byte
{
0x7f
}),
},
}
res
:=
client
.
getOAuthEndpoint
()
asserts
.
Nil
(
res
)
}
{
testCase
:=
[]
struct
{
OAuthURL
string
token
string
auth
string
isChina
bool
}{
{
OAuthURL
:
"http://login.live.com"
,
token
:
"https://login.live.com/oauth20_token.srf"
,
auth
:
"https://login.live.com/oauth20_authorize.srf"
,
isChina
:
false
,
},
{
OAuthURL
:
"http://login.chinacloudapi.cn"
,
token
:
"https://login.chinacloudapi.cn/common/oauth2/v2.0/token"
,
auth
:
"https://login.chinacloudapi.cn/common/oauth2/v2.0/authorize"
,
isChina
:
true
,
},
{
OAuthURL
:
"other"
,
token
:
"https://login.microsoftonline.com/common/oauth2/v2.0/token"
,
auth
:
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
,
isChina
:
false
,
},
}
for
i
,
testCase
:=
range
testCase
{
client
:=
Client
{
Endpoints
:
&
Endpoints
{
OAuthURL
:
testCase
.
OAuthURL
,
},
}
res
:=
client
.
getOAuthEndpoint
()
asserts
.
Equal
(
testCase
.
token
,
res
.
token
.
String
(),
"Test Case #%d"
,
i
)
asserts
.
Equal
(
testCase
.
auth
,
res
.
authorize
.
String
(),
"Test Case #%d"
,
i
)
asserts
.
Equal
(
testCase
.
isChina
,
client
.
Endpoints
.
isInChina
,
"Test Case #%d"
,
i
)
}
}
}
func
TestClient_OAuthURL
(
t
*
testing
.
T
)
{
asserts
:=
assert
.
New
(
t
)
client
:=
Client
{
ClientID
:
"client_id"
,
Redirect
:
"http://cloudreve.org/callback"
,
Endpoints
:
&
Endpoints
{},
}
client
.
Endpoints
.
OAuthEndpoints
=
client
.
getOAuthEndpoint
()
res
,
err
:=
url
.
Parse
(
client
.
OAuthURL
(
context
.
Background
(),
[]
string
{
"scope1"
,
"scope2"
}))
asserts
.
NoError
(
err
)
query
:=
res
.
Query
()
asserts
.
Equal
(
"client_id"
,
query
.
Get
(
"client_id"
))
asserts
.
Equal
(
"scope1 scope2"
,
query
.
Get
(
"scope"
))
asserts
.
Equal
(
client
.
Redirect
,
query
.
Get
(
"redirect_uri"
))
}
type
ClientMock
struct
{
testMock
.
Mock
}
func
(
m
ClientMock
)
Request
(
method
,
target
string
,
body
io
.
Reader
,
opts
...
request
.
Option
)
*
request
.
Response
{
args
:=
m
.
Called
(
method
,
target
,
body
,
opts
)
return
args
.
Get
(
0
)
.
(
*
request
.
Response
)
}
type
mockReader
string
func
(
r
mockReader
)
Read
(
b
[]
byte
)
(
int
,
error
)
{
return
0
,
errors
.
New
(
"read error"
)
}
func
TestClient_ObtainToken
(
t
*
testing
.
T
)
{
asserts
:=
assert
.
New
(
t
)
client
:=
Client
{
Endpoints
:
&
Endpoints
{},
ClientID
:
"ClientID"
,
ClientSecret
:
"ClientSecret"
,
Redirect
:
"Redirect"
,
}
client
.
Endpoints
.
OAuthEndpoints
=
client
.
getOAuthEndpoint
()
// 刷新Token 成功
{
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
nil
,
Response
:
&
http
.
Response
{
StatusCode
:
200
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
`{"access_token":"i am token"}`
)),
},
})
client
.
Request
=
clientMock
res
,
err
:=
client
.
ObtainToken
(
context
.
Background
())
clientMock
.
AssertExpectations
(
t
)
asserts
.
NoError
(
err
)
asserts
.
NotNil
(
res
)
asserts
.
Equal
(
"i am token"
,
res
.
AccessToken
)
}
// 重新获取 无法发送请求
{
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
errors
.
New
(
"error"
),
})
client
.
Request
=
clientMock
res
,
err
:=
client
.
ObtainToken
(
context
.
Background
(),
WithCode
(
"code"
))
clientMock
.
AssertExpectations
(
t
)
asserts
.
Error
(
err
)
asserts
.
Nil
(
res
)
}
// 刷新Token 无法获取响应正文
{
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
nil
,
Response
:
&
http
.
Response
{
StatusCode
:
200
,
Body
:
ioutil
.
NopCloser
(
mockReader
(
""
)),
},
})
client
.
Request
=
clientMock
res
,
err
:=
client
.
ObtainToken
(
context
.
Background
())
clientMock
.
AssertExpectations
(
t
)
asserts
.
Error
(
err
)
asserts
.
Nil
(
res
)
asserts
.
Equal
(
"read error"
,
err
.
Error
())
}
// 刷新Token OneDrive返回错误
{
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
nil
,
Response
:
&
http
.
Response
{
StatusCode
:
400
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
`{"error":"i am error"}`
)),
},
})
client
.
Request
=
clientMock
res
,
err
:=
client
.
ObtainToken
(
context
.
Background
())
clientMock
.
AssertExpectations
(
t
)
asserts
.
Error
(
err
)
asserts
.
Nil
(
res
)
asserts
.
Equal
(
""
,
err
.
Error
())
}
// 刷新Token OneDrive未知响应
{
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
nil
,
Response
:
&
http
.
Response
{
StatusCode
:
400
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
`???`
)),
},
})
client
.
Request
=
clientMock
res
,
err
:=
client
.
ObtainToken
(
context
.
Background
())
clientMock
.
AssertExpectations
(
t
)
asserts
.
Error
(
err
)
asserts
.
Nil
(
res
)
}
}
func
TestClient_UpdateCredential
(
t
*
testing
.
T
)
{
asserts
:=
assert
.
New
(
t
)
client
:=
Client
{
Policy
:
&
model
.
Policy
{
Model
:
gorm
.
Model
{
ID
:
257
}},
Endpoints
:
&
Endpoints
{},
ClientID
:
"TestClient_UpdateCredential"
,
ClientSecret
:
"ClientSecret"
,
Redirect
:
"Redirect"
,
Credential
:
&
Credential
{},
}
client
.
Endpoints
.
OAuthEndpoints
=
client
.
getOAuthEndpoint
()
// 无有效的RefreshToken
{
err
:=
client
.
UpdateCredential
(
context
.
Background
())
asserts
.
Equal
(
ErrInvalidRefreshToken
,
err
)
client
.
Credential
=
nil
err
=
client
.
UpdateCredential
(
context
.
Background
())
asserts
.
Equal
(
ErrInvalidRefreshToken
,
err
)
}
// 成功
{
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
nil
,
Response
:
&
http
.
Response
{
StatusCode
:
200
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
`{"expires_in":3600,"refresh_token":"new_refresh_token","access_token":"i am token"}`
)),
},
})
client
.
Request
=
clientMock
client
.
Credential
=
&
Credential
{
RefreshToken
:
"old_refresh_token"
,
}
mock
.
ExpectBegin
()
mock
.
ExpectExec
(
"UPDATE(.+)"
)
.
WillReturnResult
(
sqlmock
.
NewResult
(
1
,
1
))
mock
.
ExpectCommit
()
err
:=
client
.
UpdateCredential
(
context
.
Background
())
clientMock
.
AssertExpectations
(
t
)
asserts
.
NoError
(
mock
.
ExpectationsWereMet
())
asserts
.
NoError
(
err
)
cacheRes
,
ok
:=
cache
.
Get
(
"onedrive_TestClient_UpdateCredential"
)
asserts
.
True
(
ok
)
cacheCredential
:=
cacheRes
.
(
Credential
)
asserts
.
Equal
(
"new_refresh_token"
,
cacheCredential
.
RefreshToken
)
asserts
.
Equal
(
"i am token"
,
cacheCredential
.
AccessToken
)
}
// OneDrive返回错误
{
cache
.
Deletes
([]
string
{
"TestClient_UpdateCredential"
},
"onedrive_"
)
clientMock
:=
ClientMock
{}
clientMock
.
On
(
"Request"
,
"POST"
,
client
.
Endpoints
.
OAuthEndpoints
.
token
.
String
(),
testMock
.
Anything
,
testMock
.
Anything
,
)
.
Return
(
&
request
.
Response
{
Err
:
nil
,
Response
:
&
http
.
Response
{
StatusCode
:
400
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
`{"error":"error"}`
)),
},
})
client
.
Request
=
clientMock
client
.
Credential
=
&
Credential
{
RefreshToken
:
"old_refresh_token"
,
}
err
:=
client
.
UpdateCredential
(
context
.
Background
())
clientMock
.
AssertExpectations
(
t
)
asserts
.
Error
(
err
)
}
// 从缓存中获取
{
cache
.
Set
(
"onedrive_TestClient_UpdateCredential"
,
Credential
{
ExpiresIn
:
time
.
Now
()
.
Add
(
time
.
Duration
(
10
)
*
time
.
Second
)
.
Unix
(),
AccessToken
:
"AccessToken"
,
RefreshToken
:
"RefreshToken"
,
},
0
)
client
.
Credential
=
&
Credential
{
RefreshToken
:
"old_refresh_token"
,
}
err
:=
client
.
UpdateCredential
(
context
.
Background
())
asserts
.
NoError
(
err
)
asserts
.
Equal
(
"AccessToken"
,
client
.
Credential
.
AccessToken
)
asserts
.
Equal
(
"RefreshToken"
,
client
.
Credential
.
RefreshToken
)
}
// 无需重新获取
{
client
.
Credential
=
&
Credential
{
RefreshToken
:
"old_refresh_token"
,
AccessToken
:
"AccessToken2"
,
ExpiresIn
:
time
.
Now
()
.
Add
(
time
.
Duration
(
10
)
*
time
.
Second
)
.
Unix
(),
}
err
:=
client
.
UpdateCredential
(
context
.
Background
())
asserts
.
NoError
(
err
)
asserts
.
Equal
(
"AccessToken2"
,
client
.
Credential
.
AccessToken
)
}
}
pkg/filesystem/driver/oss/callback_test.go
浏览文件 @
0d2e3cc7
...
...
@@ -185,8 +185,3 @@ C0fTXv+nvlmklvkcolvpvXLTjaxUHR3W9LXxQ2EHXAJfCB+6H2YF1k8CAwEAAQ==
asserts
.
Error
(
VerifyCallbackSignature
(
&
r
))
}
}
///api/v3/callback/oss/TnXx5E5VyfJUyM1UdkdDu1rtnJ34EbmH
//{"name":"2f7b2ccf30e9270ea920f1ab8a4037a546a2f0d5.jpg","source_name":"1/1_hFRtDLgM_2f7b2ccf30e9270ea920f1ab8a4037a546a2f0d5.jpg","size":114020,"pic_info":"810,539"}
// aHR0cHM6Ly9nb3NzcHVibGljLmFsaWNkbi5jb20vY2FsbGJhY2tfcHViX2tleV92MS5wZW0=
// e5LwzwTkP9AFAItT4YzvdJOHd0Y0wqTMWhsV/h5SG90JYGAmMd+8LQyj96R+9qUfJWjMt6suuUh7LaOryR87Dw==
pkg/filesystem/upload.go
浏览文件 @
0d2e3cc7
...
...
@@ -116,7 +116,6 @@ func (fs *FileSystem) CancelUpload(ctx context.Context, path string, file FileHe
}
else
{
reqContext
=
ctx
.
Value
(
fsctx
.
HTTPCtx
)
.
(
context
.
Context
)
}
defer
fs
.
Recycle
()
select
{
case
<-
reqContext
.
Done
()
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录