feat(driver): Added support for safe unlocking logic

- Added safe file unlocking logic in `driver.go`, returning an error if unlocking fails.
- Introduced the `safeBoxUnlocked` variable of type `sync.Map` to record the IDs of unlocked files.
- Enhanced error handling logic to automatically attempt to unlock safe files and re-retrieve the file list.
- Added the `IsLock` field to file types in `types.go` to identify whether they are safe files.
- Added a constant definition for the `SafeBoxUnlock` interface address in `util.go`.
- Added the `unlockSafeBox` method to unlock a safe with a specified file ID via the API.
- Optimized the file retrieval logic to automatically call the unlock method when the safe is locked.
pull/9311/head
okatu-loli 2025-09-05 19:17:00 +08:00
parent 42f6c61503
commit d6f002a133
3 changed files with 49 additions and 2 deletions

View File

@ -6,6 +6,8 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"strconv"
"strings"
"sync" "sync"
"time" "time"
@ -28,7 +30,8 @@ import (
type Pan123 struct { type Pan123 struct {
model.Storage model.Storage
Addition Addition
apiRateLimit sync.Map apiRateLimit sync.Map
safeBoxUnlocked sync.Map
} }
func (d *Pan123) Config() driver.Config { func (d *Pan123) Config() driver.Config {
@ -52,9 +55,26 @@ func (d *Pan123) Drop(ctx context.Context) error {
} }
func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
if f, ok := dir.(File); ok && f.IsLock == 1 {
if err := d.unlockSafeBox(f.FileId); err != nil {
return nil, err
}
}
files, err := d.getFiles(ctx, dir.GetID(), dir.GetName()) files, err := d.getFiles(ctx, dir.GetID(), dir.GetName())
if err != nil { if err != nil {
return nil, err msg := strings.ToLower(err.Error())
if strings.Contains(msg, "safe box") || strings.Contains(err.Error(), "保险箱") {
if id, e := strconv.ParseInt(dir.GetID(), 10, 64); e == nil {
if e = d.unlockSafeBox(id); e == nil {
files, err = d.getFiles(ctx, dir.GetID(), dir.GetName())
} else {
return nil, e
}
}
}
if err != nil {
return nil, err
}
} }
return utils.SliceConvert(files, func(src File) (model.Obj, error) { return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return src, nil return src, nil

View File

@ -20,6 +20,7 @@ type File struct {
Etag string `json:"Etag"` Etag string `json:"Etag"`
S3KeyFlag string `json:"S3KeyFlag"` S3KeyFlag string `json:"S3KeyFlag"`
DownloadUrl string `json:"DownloadUrl"` DownloadUrl string `json:"DownloadUrl"`
IsLock int `json:"IsLock"`
} }
func (f File) CreateTime() time.Time { func (f File) CreateTime() time.Time {

View File

@ -43,6 +43,7 @@ const (
S3Auth = MainApi + "/file/s3_upload_object/auth" S3Auth = MainApi + "/file/s3_upload_object/auth"
UploadCompleteV2 = MainApi + "/file/upload_complete/v2" UploadCompleteV2 = MainApi + "/file/upload_complete/v2"
S3Complete = MainApi + "/file/s3_complete_multipart_upload" S3Complete = MainApi + "/file/s3_complete_multipart_upload"
SafeBoxUnlock = MainApi + "/restful/goapi/v1/file/safe_box/auth/unlockbox"
//AuthKeySalt = "8-8D$sL8gPjom7bk#cY" //AuthKeySalt = "8-8D$sL8gPjom7bk#cY"
) )
@ -238,6 +239,22 @@ do:
return body, nil return body, nil
} }
func (d *Pan123) unlockSafeBox(fileId int64) error {
if _, ok := d.safeBoxUnlocked.Load(fileId); ok {
return nil
}
data := base.Json{"password": d.SafePassword}
url := fmt.Sprintf("%s?fileId=%d", SafeBoxUnlock, fileId)
_, err := d.Request(url, http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, nil)
if err != nil {
return err
}
d.safeBoxUnlocked.Store(fileId, true)
return nil
}
func (d *Pan123) getFiles(ctx context.Context, parentId string, name string) ([]File, error) { func (d *Pan123) getFiles(ctx context.Context, parentId string, name string) ([]File, error) {
page := 1 page := 1
total := 0 total := 0
@ -267,6 +284,15 @@ func (d *Pan123) getFiles(ctx context.Context, parentId string, name string) ([]
req.SetQueryParams(query) req.SetQueryParams(query)
}, &resp) }, &resp)
if err != nil { if err != nil {
msg := strings.ToLower(err.Error())
if strings.Contains(msg, "safe box") || strings.Contains(err.Error(), "保险箱") {
if fid, e := strconv.ParseInt(parentId, 10, 64); e == nil {
if e = d.unlockSafeBox(fid); e == nil {
return d.getFiles(ctx, parentId, name)
}
return nil, e
}
}
return nil, err return nil, err
} }
log.Debug(string(_res)) log.Debug(string(_res))