Skip to content

Commit

Permalink
fix(aliyundrive_open): add aliyundrive_tv auth
Browse files Browse the repository at this point in the history
  • Loading branch information
Three-taile-dragon committed Jul 20, 2024
1 parent 2b74999 commit 8a15810
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 2 deletions.
12 changes: 12 additions & 0 deletions drivers/aliyundrive_open/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ func (d *AliyundriveOpen) Init(ctx context.Context) error {
if d.DriveType == "" {
d.DriveType = "default"
}
if d.UseTVAuth && d.RefreshToken == "" {
if d.SID != "" {
// 查询 对应的 authCode --> 获取 access_token refresh_token
err := d.getRefreshTokenBySID()
if err != nil {
return err
}
} else {
// 发送 qcode 请求 获取 sid
return d.getSID()
}
}
res, err := d.request("/adrive/v1.0/user/getDriveInfo", http.MethodPost, nil)
if err != nil {
return err
Expand Down
4 changes: 3 additions & 1 deletion drivers/aliyundrive_open/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
type Addition struct {
DriveType string `json:"drive_type" type:"select" options:"default,resource,backup" default:"default"`
driver.RootID
RefreshToken string `json:"refresh_token" required:"true"`
RefreshToken string `json:"refresh_token"`
OrderBy string `json:"order_by" type:"select" options:"name,size,updated_at,created_at"`
OrderDirection string `json:"order_direction" type:"select" options:"ASC,DESC"`
OauthTokenURL string `json:"oauth_token_url" default:"https://api.nn.ci/alist/ali_open/token"`
Expand All @@ -19,6 +19,8 @@ type Addition struct {
InternalUpload bool `json:"internal_upload" help:"If you are using Aliyun ECS is located in Beijing, you can turn it on to boost the upload speed"`
LIVPDownloadFormat string `json:"livp_download_format" type:"select" options:"jpeg,mov" default:"jpeg"`
AccessToken string
UseTVAuth bool `json:"use_tv_auth"`
SID string `json:"sid"`
}

var config = driver.Config{
Expand Down
27 changes: 27 additions & 0 deletions drivers/aliyundrive_open/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,30 @@ type MoveOrCopyResp struct {
DriveID string `json:"drive_id"`
FileID string `json:"file_id"`
}

type SIDResp struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
QRCodeURL string `json:"qrCodeUrl"`
SID string `json:"sid"`
} `json:"data"`
}

type RefreshTokenSIDResp struct {
Status string `json:"status"`
AuthCode string `json:"authCode"`
}

type RefreshTokenAuthResp struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Code string `json:"code"`
Message string `json:"message"`
TokenType string `json:"token_type"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIN int `json:"expires_in"`
}
}
92 changes: 91 additions & 1 deletion drivers/aliyundrive_open/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,11 @@ func (d *AliyundriveOpen) requestReturnErrResp(uri, method string, callback base
isRetry := len(retry) > 0 && retry[0]
if e.Code != "" {
if !isRetry && (utils.SliceContains([]string{"AccessTokenInvalid", "AccessTokenExpired", "I400JD"}, e.Code) || d.AccessToken == "") {
err = d.refreshToken()
if d.UseTVAuth {
err = d.getRefreshTokenByTV(d.RefreshToken, true)
} else {
err = d.refreshToken()
}
if err != nil {
return nil, err, nil
}
Expand Down Expand Up @@ -176,3 +180,89 @@ func getNowTime() (time.Time, string) {
nowTimeStr := nowTime.Format("2006-01-02T15:04:05.000Z")
return nowTime, nowTimeStr
}

func (d *AliyundriveOpen) getSID() error {
url := "http://api.extscreen.com/aliyundrive/qrcode"
var resp SIDResp
_, err := base.RestyClient.R().
SetBody(base.Json{
"scopes": "user:base,file:all:read,file:all:write",
"width": 500,
"height": 500,
}).
SetResult(&resp).
Post(url)
if err != nil {
return err
}
d.SID = resp.Data.SID
op.MustSaveDriverStorage(d)
authURL := fmt.Sprintf("https://www.aliyundrive.com/o/oauth/authorize?sid=%s", resp.Data.SID)
return fmt.Errorf(`need verify: <a target="_blank" href="%s">Click Here</a>`, authURL)
}

func (d *AliyundriveOpen) getRefreshTokenBySID() error {
// 获取 authCode
authCode := ""
url := "https://openapi.alipan.com/oauth/qrcode/" + d.SID + "/status"
time.Sleep(time.Second) // 等待 阿里云盘那边更新SID状态
var resp RefreshTokenSIDResp
_, err := base.RestyClient.R().
SetResult(&resp).
Get(url)
if err != nil {
return err
}
if resp.Status != "LoginSuccess" {
return fmt.Errorf("failed to get auth code: %s", resp.Status)

} else {
authCode = resp.AuthCode
}
return d.getRefreshTokenByTV(authCode, false)
}

func (d *AliyundriveOpen) getRefreshTokenByTV(code string, isRefresh bool) error {
refresh, access, err := d._getRefreshTokenByTV(code, isRefresh)
for i := 0; i < 3; i++ {
if err == nil {
break
} else {
log.Errorf("[ali_open] failed to refresh token: %s", err)
}
refresh, access, err = d._getRefreshTokenByTV(code, isRefresh)
}
if err != nil {
return err
}
log.Infof("[ali_open] token exchange: %s -> %s", d.RefreshToken, refresh)
d.RefreshToken, d.AccessToken = refresh, access
op.MustSaveDriverStorage(d)
return nil
}

func (d *AliyundriveOpen) _getRefreshTokenByTV(code string, isRefresh bool) (refreshToken, accessToken string, err error) {
url := "http://api.extscreen.com/aliyundrive/token"
var resp RefreshTokenAuthResp
body := ""
if isRefresh {
body = fmt.Sprintf("refresh_token=%s", code)
} else {
body = fmt.Sprintf("code=%s", code)
}

res, err := base.RestyClient.R().
SetHeader("Content-Type", "application/x-www-form-urlencoded").
SetBody(body).
SetResult(&resp).
Post(url)
if err != nil {
return "", "", err
}

refresh, access := resp.Data.RefreshToken, resp.Data.AccessToken
if refresh == "" {
return "", "", fmt.Errorf("failed to refresh token: refresh token is empty, resp: %s", res.String())
}
return refresh, access, nil
}

0 comments on commit 8a15810

Please sign in to comment.