Skip to content

Commit

Permalink
feat(123&123share): 添加扫码登录
Browse files Browse the repository at this point in the history
  • Loading branch information
Three-taile-dragon authored and xrgzs committed Nov 16, 2024
1 parent 4a6c760 commit dc1bfe5
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 16 deletions.
6 changes: 4 additions & 2 deletions drivers/123/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
)

type Addition struct {
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
Username string `json:"username"`
Password string `json:"password"`
UseQrCodeLogin bool `json:"use_qr_code_login"`
UniID string `json:"uni_id"`
driver.RootID
//OrderBy string `json:"order_by" type:"select" options:"file_id,file_name,size,update_at" default:"file_name"`
//OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
Expand Down
18 changes: 18 additions & 0 deletions drivers/123/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,21 @@ type S3PreSignedURLs struct {
PreSignedUrls map[string]string `json:"presignedUrls"`
} `json:"data"`
}

type QrCodeGenerateResp struct {
Data struct {
UniID string `json:"uniID"`
Url string `json:"url"`
} `json:"data"`
}

type QrCodeResultResp struct {
Data struct {
Expire time.Time `json:"expire"`
LoginType int `json:"login_type"`
RefreshTokenExpireTime int `json:"refresh_token_expire_time"`
Token string `json:"token"`
LoginStatus int `json:"loginStatus"`
ScanPlatform int `json:"scanPlatform"`
} `json:"data"`
}
78 changes: 76 additions & 2 deletions drivers/123/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package _123

import (
"context"
"encoding/base64"
"errors"
"fmt"
"github.com/alist-org/alist/v3/internal/op"
"github.com/google/uuid"
"github.com/skip2/go-qrcode"
"hash/crc32"
"math"
"math/rand"
Expand Down Expand Up @@ -45,6 +48,8 @@ const (
UploadCompleteV2 = MainApi + "/file/upload_complete/v2"
S3Complete = MainApi + "/file/s3_complete_multipart_upload"
//AuthKeySalt = "8-8D$sL8gPjom7bk#cY"
QrcodeGenerate = MainApi + "/user/qr-code/generate"
QrcodeResult = MainApi + "/user/qr-code/result"
)

const (
Expand Down Expand Up @@ -171,6 +176,69 @@ func (d *Pan123) login() error {
// return &authKey, nil
//}

func (d *Pan123) loginByQrCode() error {
if d.Addition.UniID == "" {
uniID, err := d.generateQrCode()
if uniID == "" && err != nil {
return err
} else {
// 保存 uniID 用于 二维码登录
d.Addition.UniID = uniID
op.MustSaveDriverStorage(d)
return err
}
} else {
token, err := d.getTokenByUniID()
if token == "" && err != nil {
return err
} else {
d.Addition.AccessToken = token
op.MustSaveDriverStorage(d)
return err
}
}
}

func (d *Pan123) generateQrCode() (string, error) {
var resp QrCodeGenerateResp
_, err := d.request(QrcodeGenerate, http.MethodGet, nil, &resp)
if err != nil {
return "", err
}
// 拼接二维码链接
qrUrl := fmt.Sprintf(resp.Data.Url+"?uniID=%s", resp.Data.UniID+"&source=123pan&type=login")
// 生成二维码
qrBytes, _ := qrcode.Encode(qrUrl, qrcode.Medium, 256)
base64Bytes := base64.StdEncoding.EncodeToString(qrBytes)
// 展示二维码
qrTemplate := `
<body>
<img src="data:image/jpeg;base64,%s"/>
<a target="_blank" href="%s">Or Click Here</a>
</body>`
qrPage := fmt.Sprintf(qrTemplate, base64Bytes, qrUrl)
return resp.Data.UniID, fmt.Errorf("need verify: \n%s", qrPage)
}

func (d *Pan123) getTokenByUniID() (string, error) {
var resp QrCodeResultResp
_, err := d.request(QrcodeResult, http.MethodGet, func(req *resty.Request) {
req.SetQueryParam("uniID", d.Addition.UniID)
}, &resp)
if err != nil {
return "", err
}

if resp.Data.LoginStatus == 4 {
return "", errors.New("uniID expired")
} else if resp.Data.Token == "" && resp.Data.LoginStatus == 0 {
return "", errors.New("wait for scan qrcode")
}

return resp.Data.Token, nil

}

func (d *Pan123) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeaders(map[string]string{
Expand Down Expand Up @@ -213,13 +281,19 @@ func (d *Pan123) request(url string, method string, callback base.ReqCallback, r
}
body := res.Body()
code := utils.Json.Get(body, "code").ToInt()
if code != 0 {
if code == 401 {
if code != 0 && code != 200 {
if code == 401 && d.Addition.UseQrCodeLogin == false {
err := d.login()
if err != nil {
return nil, err
}
return d.request(url, method, callback, resp)
} else if code == 401 && d.Addition.UseQrCodeLogin == true {
err := d.loginByQrCode()
if err != nil {
return nil, err
}
return d.request(url, method, callback, resp)
}
return nil, errors.New(jsoniter.Get(body, "message").ToString())
}
Expand Down
9 changes: 6 additions & 3 deletions drivers/123_share/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ func (d *Pan123Share) GetAddition() driver.Additional {
}

func (d *Pan123Share) Init(ctx context.Context) error {
// TODO login / refresh token
//op.MustSaveDriverStorage(d)
// TODO refresh token
// 拼接UserAgent
if d.PlatformType == "android" {
d.params.UserAgent = AndroidUserAgentPrefix + "(" + d.OsVersion + ";" + d.DeviceName + " " + d.DeiveType + ")"
Expand All @@ -56,10 +55,14 @@ func (d *Pan123Share) Init(ctx context.Context) error {
d.params.DeviceName = d.DeviceName
d.params.DeviceType = d.DeiveType

return nil
_, err := d.request(UserInfo, http.MethodGet, nil, nil)
return err
}

func (d *Pan123Share) Drop(ctx context.Context) error {
_, _ = d.request(Logout, http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{})
}, nil)
return nil
}

Expand Down
8 changes: 6 additions & 2 deletions drivers/123_share/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import (
)

type Addition struct {
ShareKey string `json:"sharekey" required:"true"`
SharePwd string `json:"sharepassword"`
Username string `json:"username"`
Password string `json:"password"`
UseQrCodeLogin bool `json:"use_qr_code_login"`
UniID string `json:"uni_id"`
ShareKey string `json:"sharekey" required:"true"`
SharePwd string `json:"sharepassword"`
driver.RootID
//OrderBy string `json:"order_by" type:"select" options:"file_name,size,update_at" default:"file_name"`
//OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
Expand Down
18 changes: 18 additions & 0 deletions drivers/123_share/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,21 @@ type Files struct {
// DownloadUrl string `json:"DownloadUrl"`
// } `json:"data"`
//}

type QrCodeGenerateResp struct {
Data struct {
UniID string `json:"uniID"`
Url string `json:"url"`
} `json:"data"`
}

type QrCodeResultResp struct {
Data struct {
Expire time.Time `json:"expire"`
LoginType int `json:"login_type"`
RefreshTokenExpireTime int `json:"refresh_token_expire_time"`
Token string `json:"token"`
LoginStatus int `json:"loginStatus"`
ScanPlatform int `json:"scanPlatform"`
} `json:"data"`
}
Loading

0 comments on commit dc1bfe5

Please sign in to comment.