mirror of https://github.com/rclone/rclone.git
webdav: add --webdav-bearer-token-command - fixes #2380
This can be used with oidc-agent to get a bearer token
This commit is contained in:
parent
19ae053168
commit
c642531a1e
|
@ -15,6 +15,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -80,17 +81,22 @@ func init() {
|
||||||
}, {
|
}, {
|
||||||
Name: "bearer_token",
|
Name: "bearer_token",
|
||||||
Help: "Bearer token instead of user/pass (eg a Macaroon)",
|
Help: "Bearer token instead of user/pass (eg a Macaroon)",
|
||||||
|
}, {
|
||||||
|
Name: "bearer_token_command",
|
||||||
|
Help: "Command to run to get a bearer token",
|
||||||
|
Advanced: true,
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options defines the configuration for this backend
|
// Options defines the configuration for this backend
|
||||||
type Options struct {
|
type Options struct {
|
||||||
URL string `config:"url"`
|
URL string `config:"url"`
|
||||||
Vendor string `config:"vendor"`
|
Vendor string `config:"vendor"`
|
||||||
User string `config:"user"`
|
User string `config:"user"`
|
||||||
Pass string `config:"pass"`
|
Pass string `config:"pass"`
|
||||||
BearerToken string `config:"bearer_token"`
|
BearerToken string `config:"bearer_token"`
|
||||||
|
BearerTokenCommand string `config:"bearer_token_command"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fs represents a remote webdav
|
// Fs represents a remote webdav
|
||||||
|
@ -330,7 +336,12 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
if opt.User != "" || opt.Pass != "" {
|
if opt.User != "" || opt.Pass != "" {
|
||||||
f.srv.SetUserPass(opt.User, opt.Pass)
|
f.srv.SetUserPass(opt.User, opt.Pass)
|
||||||
} else if opt.BearerToken != "" {
|
} else if opt.BearerToken != "" {
|
||||||
f.srv.SetHeader("Authorization", "BEARER "+opt.BearerToken)
|
f.setBearerToken(opt.BearerToken)
|
||||||
|
} else if f.opt.BearerTokenCommand != "" {
|
||||||
|
err = f.fetchAndSetBearerToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f.srv.SetErrorHandler(errorHandler)
|
f.srv.SetErrorHandler(errorHandler)
|
||||||
err = f.setQuirks(opt.Vendor)
|
err = f.setQuirks(opt.Vendor)
|
||||||
|
@ -360,6 +371,49 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sets the BearerToken up
|
||||||
|
func (f *Fs) setBearerToken(token string) {
|
||||||
|
f.opt.BearerToken = token
|
||||||
|
f.srv.SetHeader("Authorization", "BEARER "+token)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch the bearer token using the command
|
||||||
|
func (f *Fs) fetchBearerToken(cmd string) (string, error) {
|
||||||
|
var (
|
||||||
|
args = strings.Split(cmd, " ")
|
||||||
|
stdout bytes.Buffer
|
||||||
|
stderr bytes.Buffer
|
||||||
|
c = exec.Command(args[0], args[1:]...)
|
||||||
|
)
|
||||||
|
c.Stdout = &stdout
|
||||||
|
c.Stderr = &stderr
|
||||||
|
var (
|
||||||
|
err = c.Run()
|
||||||
|
stdoutString = strings.TrimSpace(stdout.String())
|
||||||
|
stderrString = strings.TrimSpace(stderr.String())
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
if stderrString == "" {
|
||||||
|
stderrString = stdoutString
|
||||||
|
}
|
||||||
|
return "", errors.Wrapf(err, "failed to get bearer token using %q: %s", f.opt.BearerTokenCommand, stderrString)
|
||||||
|
}
|
||||||
|
return stdoutString, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch the bearer token and set it if successful
|
||||||
|
func (f *Fs) fetchAndSetBearerToken() error {
|
||||||
|
if f.opt.BearerTokenCommand == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
token, err := f.fetchBearerToken(f.opt.BearerTokenCommand)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.setBearerToken(token)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// setQuirks adjusts the Fs for the vendor passed in
|
// setQuirks adjusts the Fs for the vendor passed in
|
||||||
func (f *Fs) setQuirks(vendor string) error {
|
func (f *Fs) setQuirks(vendor string) error {
|
||||||
switch vendor {
|
switch vendor {
|
||||||
|
|
Loading…
Reference in New Issue