From cc3b8a4cff8fc3c7ee2730a741c942d08da6c476 Mon Sep 17 00:00:00 2001 From: MadDogOwner Date: Thu, 13 Nov 2025 10:11:13 +0800 Subject: [PATCH 1/6] feat(onedrive): support create share link for download Signed-off-by: MadDogOwner --- drivers/onedrive/driver.go | 25 +++++++++++++------- drivers/onedrive/meta.go | 1 + drivers/onedrive/util.go | 48 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/drivers/onedrive/driver.go b/drivers/onedrive/driver.go index e01c1f7c1..76e1bee3a 100644 --- a/drivers/onedrive/driver.go +++ b/drivers/onedrive/driver.go @@ -105,16 +105,25 @@ func (d *Onedrive) List(ctx context.Context, dir model.Obj, args model.ListArgs) } func (d *Onedrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { - f, err := d.GetFile(file.GetPath()) - if err != nil { - return nil, err - } - if f.File == nil { - return nil, errs.NotFile + var u string + var err error + if d.CreateShareLink { + u, err = d.createLink(file.GetPath()) + if err != nil { + return nil, err + } + } else { + f, err := d.GetFile(file.GetPath()) + if err != nil { + return nil, err + } + if f.File == nil { + return nil, errs.NotFile + } + u = f.Url } - u := f.Url if d.CustomHost != "" { - _u, err := url.Parse(f.Url) + _u, err := url.Parse(u) if err != nil { return nil, err } diff --git a/drivers/onedrive/meta.go b/drivers/onedrive/meta.go index 4fd505b9c..83d6aa8d5 100644 --- a/drivers/onedrive/meta.go +++ b/drivers/onedrive/meta.go @@ -20,6 +20,7 @@ type Addition struct { CustomHost string `json:"custom_host" help:"Custom host for onedrive download link"` DisableDiskUsage bool `json:"disable_disk_usage" default:"false"` EnableDirectUpload bool `json:"enable_direct_upload" default:"false" help:"Enable direct upload from client to OneDrive"` + CreateShareLink bool `json:"create_share_link" default:"false" help:"Create share link for file download"` } var config = driver.Config{ diff --git a/drivers/onedrive/util.go b/drivers/onedrive/util.go index ad300af44..6b1b1ce08 100644 --- a/drivers/onedrive/util.go +++ b/drivers/onedrive/util.go @@ -6,7 +6,9 @@ import ( "fmt" "io" "net/http" + "net/url" stdpath "path" + "strings" "time" "github.com/OpenListTeam/OpenList/v4/drivers/base" @@ -185,6 +187,52 @@ func (d *Onedrive) GetFile(path string) (*File, error) { return &file, err } +func (d *Onedrive) createLink(path string) (string, error) { + api := d.GetMetaUrl(false, path) + "/createLink" + data := base.Json{ + "type": "view", + "scope": "anonymous", + } + var resp struct { + Link struct { + WebUrl string `json:"webUrl"` + } `json:"link"` + } + _, err := d.Request(api, http.MethodPost, func(req *resty.Request) { + req.SetBody(data) + }, &resp) + if err != nil { + return "", err + } + + p, err := url.Parse(resp.Link.WebUrl) + if err != nil { + return "", err + } + q := p.Query() + + if p.Host == "1drv.ms" { + // For personal, do some transformations + // https://1drv.ms/u/c/{user}/{share}?e=xxxx -> + // https://my.microsoftpersonalcontent.com/personal/{user}/_layouts/15/download.aspx?share={share} + paths := strings.Split(p.Path, "/") + if len(paths) < 4 || paths[2] == "" || paths[3] == "" { + return "", fmt.Errorf("invalid onedrive short link") + } + user := paths[2] + share := paths[3] + p.Scheme = "https" + p.Host = "my.microsoftpersonalcontent.com" + p.Path = fmt.Sprintf("/personal/%s/_layouts/15/download.aspx", user) + q = url.Values{} + q.Set("share", share) + } else { + q.Set("download", "1") + } + p.RawQuery = q.Encode() + return p.String(), nil +} + func (d *Onedrive) upSmall(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) error { filepath := stdpath.Join(dstDir.GetPath(), stream.GetName()) // 1. upload new file From 0d912beb7d675118a41f776aaabb2d8913345e73 Mon Sep 17 00:00:00 2001 From: MadDogOwner Date: Thu, 13 Nov 2025 10:19:46 +0800 Subject: [PATCH 2/6] feat(onedrive): add expiration duration for link Signed-off-by: MadDogOwner --- drivers/onedrive/driver.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/onedrive/driver.go b/drivers/onedrive/driver.go index 76e1bee3a..17552d667 100644 --- a/drivers/onedrive/driver.go +++ b/drivers/onedrive/driver.go @@ -7,6 +7,7 @@ import ( "net/url" "path" "sync" + "time" "github.com/OpenListTeam/OpenList/v4/drivers/base" "github.com/OpenListTeam/OpenList/v4/internal/driver" @@ -107,12 +108,15 @@ func (d *Onedrive) List(ctx context.Context, dir model.Obj, args model.ListArgs) func (d *Onedrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { var u string var err error + var duration time.Duration if d.CreateShareLink { + duration = 365 * 24 * time.Hour // cache 1 year u, err = d.createLink(file.GetPath()) if err != nil { return nil, err } } else { + duration = 5 * time.Minute // cache 5 min f, err := d.GetFile(file.GetPath()) if err != nil { return nil, err @@ -131,7 +135,8 @@ func (d *Onedrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs u = _u.String() } return &model.Link{ - URL: u, + URL: u, + Expiration: &duration, }, nil } From 51339b77025cab63439b54780a8ecfa0b2ffb1d0 Mon Sep 17 00:00:00 2001 From: MadDogOwner Date: Thu, 13 Nov 2025 10:39:57 +0800 Subject: [PATCH 3/6] fix(onedrive): fix path parsing for personal OneDrive short links Signed-off-by: MadDogOwner --- drivers/onedrive/util.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/onedrive/util.go b/drivers/onedrive/util.go index 6b1b1ce08..9143112e3 100644 --- a/drivers/onedrive/util.go +++ b/drivers/onedrive/util.go @@ -213,14 +213,14 @@ func (d *Onedrive) createLink(path string) (string, error) { if p.Host == "1drv.ms" { // For personal, do some transformations - // https://1drv.ms/u/c/{user}/{share}?e=xxxx -> + // https://1drv.ms/t/c/{user}/{share} -> // https://my.microsoftpersonalcontent.com/personal/{user}/_layouts/15/download.aspx?share={share} paths := strings.Split(p.Path, "/") - if len(paths) < 4 || paths[2] == "" || paths[3] == "" { + if len(paths) < 5 || paths[3] == "" || paths[4] == "" { return "", fmt.Errorf("invalid onedrive short link") } - user := paths[2] - share := paths[3] + user := paths[3] + share := paths[4] p.Scheme = "https" p.Host = "my.microsoftpersonalcontent.com" p.Path = fmt.Sprintf("/personal/%s/_layouts/15/download.aspx", user) From f2d1c282dc8b901c2be1ad3391882e348b7d3092 Mon Sep 17 00:00:00 2001 From: MadDogOwner Date: Thu, 20 Nov 2025 12:24:39 +0800 Subject: [PATCH 4/6] fix(onedrive): use download.aspx for all Signed-off-by: MadDogOwner --- drivers/onedrive/util.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/onedrive/util.go b/drivers/onedrive/util.go index 9143112e3..c4b94e5b6 100644 --- a/drivers/onedrive/util.go +++ b/drivers/onedrive/util.go @@ -209,10 +209,10 @@ func (d *Onedrive) createLink(path string) (string, error) { if err != nil { return "", err } - q := p.Query() - + // Do some transformations + q := url.Values{} if p.Host == "1drv.ms" { - // For personal, do some transformations + // For personal // https://1drv.ms/t/c/{user}/{share} -> // https://my.microsoftpersonalcontent.com/personal/{user}/_layouts/15/download.aspx?share={share} paths := strings.Split(p.Path, "/") @@ -221,13 +221,22 @@ func (d *Onedrive) createLink(path string) (string, error) { } user := paths[3] share := paths[4] - p.Scheme = "https" p.Host = "my.microsoftpersonalcontent.com" p.Path = fmt.Sprintf("/personal/%s/_layouts/15/download.aspx", user) - q = url.Values{} + q.Set("share", share) + } else if strings.Contains(p.Host, ".sharepoint.com") { + // https://{tenant}-my.sharepoint.com/:u:/g/personal/{user_email}/{share} + // https://{tenant}-my.sharepoint.com/personal/{user_email}/_layouts/15/download.aspx?share={share} + paths := strings.Split(p.Path, "/") + if len(paths) < 6 || paths[5] == "" { + return "", fmt.Errorf("invalid onedrive sharepoint link") + } + user := paths[4] + share := paths[5] + p.Path = fmt.Sprintf("/personal/%s/_layouts/15/download.aspx", user) q.Set("share", share) } else { - q.Set("download", "1") + return "", fmt.Errorf("unsupported onedrive link host: %s", p.Host) } p.RawQuery = q.Encode() return p.String(), nil From 55dc8565c30e27665dcdb35568b5e3e044d3bce9 Mon Sep 17 00:00:00 2001 From: MadDogOwner Date: Sat, 17 Jan 2026 14:06:52 +0800 Subject: [PATCH 5/6] feat(onedrive): create share link for redirect only Signed-off-by: MadDogOwner --- drivers/onedrive/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/onedrive/driver.go b/drivers/onedrive/driver.go index 17552d667..82ad8517c 100644 --- a/drivers/onedrive/driver.go +++ b/drivers/onedrive/driver.go @@ -109,7 +109,7 @@ func (d *Onedrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs var u string var err error var duration time.Duration - if d.CreateShareLink { + if d.CreateShareLink && args.Redirect { duration = 365 * 24 * time.Hour // cache 1 year u, err = d.createLink(file.GetPath()) if err != nil { From 69e60172be488706716a5d7883fed858c7ed7b42 Mon Sep 17 00:00:00 2001 From: MadDogOwner Date: Sat, 17 Jan 2026 14:13:20 +0800 Subject: [PATCH 6/6] fix(onedrive): remove default cache duration for link expiration Signed-off-by: MadDogOwner --- drivers/onedrive/driver.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/onedrive/driver.go b/drivers/onedrive/driver.go index 82ad8517c..bef334ede 100644 --- a/drivers/onedrive/driver.go +++ b/drivers/onedrive/driver.go @@ -116,7 +116,6 @@ func (d *Onedrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs return nil, err } } else { - duration = 5 * time.Minute // cache 5 min f, err := d.GetFile(file.GetPath()) if err != nil { return nil, err @@ -134,9 +133,14 @@ func (d *Onedrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs _u.Host = d.CustomHost u = _u.String() } + if duration > 0 { + return &model.Link{ + URL: u, + Expiration: &duration, + }, nil + } return &model.Link{ - URL: u, - Expiration: &duration, + URL: u, }, nil }