basic authentication support for 'zrok copy' and friends (#438)

This commit is contained in:
Michael Quigley 2024-01-11 13:40:45 -05:00
parent f39a09efdf
commit 9567c0ac57
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
8 changed files with 67 additions and 19 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/openziti/zrok/tui" "github.com/openziti/zrok/tui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"net/url" "net/url"
"os"
) )
func init() { func init() {
@ -15,8 +16,9 @@ func init() {
} }
type copyCommand struct { type copyCommand struct {
cmd *cobra.Command cmd *cobra.Command
sync bool sync bool
basicAuth string
} }
func newCopyCommand() *copyCommand { func newCopyCommand() *copyCommand {
@ -29,10 +31,15 @@ func newCopyCommand() *copyCommand {
command := &copyCommand{cmd: cmd} command := &copyCommand{cmd: cmd}
cmd.Run = command.run cmd.Run = command.run
cmd.Flags().BoolVarP(&command.sync, "sync", "s", false, "Only copy modified files (one-way synchronize)") cmd.Flags().BoolVarP(&command.sync, "sync", "s", false, "Only copy modified files (one-way synchronize)")
cmd.Flags().StringVarP(&command.basicAuth, "basic-auth", "a", "", "Basic authentication <username:password>")
return command return command
} }
func (cmd *copyCommand) run(_ *cobra.Command, args []string) { func (cmd *copyCommand) run(_ *cobra.Command, args []string) {
if cmd.basicAuth == "" {
cmd.basicAuth = os.Getenv("ZROK_DRIVES_BASIC_AUTH")
}
sourceUrl, err := url.Parse(args[0]) sourceUrl, err := url.Parse(args[0])
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("invalid source '%v'", args[0]), err) tui.Error(fmt.Sprintf("invalid source '%v'", args[0]), err)
@ -82,11 +89,11 @@ func (cmd *copyCommand) run(_ *cobra.Command, args []string) {
} }
}() }()
source, err := sync.TargetForURL(sourceUrl, root) source, err := sync.TargetForURL(sourceUrl, root, cmd.basicAuth)
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("error creating target for '%v'", sourceUrl), err) tui.Error(fmt.Sprintf("error creating target for '%v'", sourceUrl), err)
} }
target, err := sync.TargetForURL(targetUrl, root) target, err := sync.TargetForURL(targetUrl, root, cmd.basicAuth)
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err) tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err)
} }

View File

@ -18,7 +18,8 @@ func init() {
} }
type lsCommand struct { type lsCommand struct {
cmd *cobra.Command cmd *cobra.Command
basicAuth string
} }
func newLsCommand() *lsCommand { func newLsCommand() *lsCommand {
@ -30,10 +31,15 @@ func newLsCommand() *lsCommand {
} }
command := &lsCommand{cmd: cmd} command := &lsCommand{cmd: cmd}
cmd.Run = command.run cmd.Run = command.run
cmd.Flags().StringVarP(&command.basicAuth, "basic-auth", "a", "", "Basic authentication <username:password>")
return command return command
} }
func (cmd *lsCommand) run(_ *cobra.Command, args []string) { func (cmd *lsCommand) run(_ *cobra.Command, args []string) {
if cmd.basicAuth == "" {
cmd.basicAuth = os.Getenv("ZROK_DRIVES_BASIC_AUTH")
}
targetUrl, err := url.Parse(args[0]) targetUrl, err := url.Parse(args[0])
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err) tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err)
@ -47,7 +53,7 @@ func (cmd *lsCommand) run(_ *cobra.Command, args []string) {
tui.Error("error loading root", err) tui.Error("error loading root", err)
} }
target, err := sync.TargetForURL(targetUrl, root) target, err := sync.TargetForURL(targetUrl, root, cmd.basicAuth)
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err) tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err)
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/openziti/zrok/tui" "github.com/openziti/zrok/tui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"net/url" "net/url"
"os"
) )
func init() { func init() {
@ -14,7 +15,8 @@ func init() {
} }
type mdCommand struct { type mdCommand struct {
cmd *cobra.Command cmd *cobra.Command
basicAuth string
} }
func newMdCommand() *mdCommand { func newMdCommand() *mdCommand {
@ -26,10 +28,15 @@ func newMdCommand() *mdCommand {
} }
command := &mdCommand{cmd: cmd} command := &mdCommand{cmd: cmd}
cmd.Run = command.run cmd.Run = command.run
cmd.Flags().StringVarP(&command.basicAuth, "basic-auth", "a", "", "Basic authentication <username:password>")
return command return command
} }
func (cmd *mdCommand) run(_ *cobra.Command, args []string) { func (cmd *mdCommand) run(_ *cobra.Command, args []string) {
if cmd.basicAuth == "" {
cmd.basicAuth = os.Getenv("ZROK_DRIVES_BASIC_AUTH")
}
targetUrl, err := url.Parse(args[0]) targetUrl, err := url.Parse(args[0])
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err) tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err)
@ -43,7 +50,7 @@ func (cmd *mdCommand) run(_ *cobra.Command, args []string) {
tui.Error("error loading root", err) tui.Error("error loading root", err)
} }
target, err := sync.TargetForURL(targetUrl, root) target, err := sync.TargetForURL(targetUrl, root, cmd.basicAuth)
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err) tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err)
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/openziti/zrok/tui" "github.com/openziti/zrok/tui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"net/url" "net/url"
"os"
) )
func init() { func init() {
@ -14,7 +15,8 @@ func init() {
} }
type mvCommand struct { type mvCommand struct {
cmd *cobra.Command cmd *cobra.Command
basicAuth string
} }
func newMvCommand() *mvCommand { func newMvCommand() *mvCommand {
@ -26,10 +28,15 @@ func newMvCommand() *mvCommand {
} }
command := &mvCommand{cmd: cmd} command := &mvCommand{cmd: cmd}
cmd.Run = command.run cmd.Run = command.run
cmd.Flags().StringVarP(&command.basicAuth, "basic-auth", "a", "", "Basic authentication <username:password>")
return command return command
} }
func (cmd *mvCommand) run(_ *cobra.Command, args []string) { func (cmd *mvCommand) run(_ *cobra.Command, args []string) {
if cmd.basicAuth == "" {
cmd.basicAuth = os.Getenv("ZROK_DRIVES_BASIC_AUTH")
}
targetUrl, err := url.Parse(args[0]) targetUrl, err := url.Parse(args[0])
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err) tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err)
@ -43,7 +50,7 @@ func (cmd *mvCommand) run(_ *cobra.Command, args []string) {
tui.Error("error loading root", err) tui.Error("error loading root", err)
} }
target, err := sync.TargetForURL(targetUrl, root) target, err := sync.TargetForURL(targetUrl, root, cmd.basicAuth)
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err) tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err)
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/openziti/zrok/tui" "github.com/openziti/zrok/tui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"net/url" "net/url"
"os"
) )
func init() { func init() {
@ -14,7 +15,8 @@ func init() {
} }
type rmCommand struct { type rmCommand struct {
cmd *cobra.Command cmd *cobra.Command
basicAuth string
} }
func newRmCommand() *rmCommand { func newRmCommand() *rmCommand {
@ -26,10 +28,15 @@ func newRmCommand() *rmCommand {
} }
command := &rmCommand{cmd: cmd} command := &rmCommand{cmd: cmd}
cmd.Run = command.run cmd.Run = command.run
cmd.Flags().StringVarP(&command.basicAuth, "basic-auth", "a", "", "Basic authentication <username:password>")
return command return command
} }
func (cmd *rmCommand) run(_ *cobra.Command, args []string) { func (cmd *rmCommand) run(_ *cobra.Command, args []string) {
if cmd.basicAuth == "" {
cmd.basicAuth = os.Getenv("ZROK_DRIVES_BASIC_AUTH")
}
targetUrl, err := url.Parse(args[0]) targetUrl, err := url.Parse(args[0])
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err) tui.Error(fmt.Sprintf("invalid target '%v'", args[0]), err)
@ -43,7 +50,7 @@ func (cmd *rmCommand) run(_ *cobra.Command, args []string) {
tui.Error("error loading root", err) tui.Error("error loading root", err)
} }
target, err := sync.TargetForURL(targetUrl, root) target, err := sync.TargetForURL(targetUrl, root, cmd.basicAuth)
if err != nil { if err != nil {
tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err) tui.Error(fmt.Sprintf("error creating target for '%v'", targetUrl), err)
} }

View File

@ -4,9 +4,10 @@ import (
"github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/environment/env_core"
"github.com/pkg/errors" "github.com/pkg/errors"
"net/url" "net/url"
"strings"
) )
func TargetForURL(url *url.URL, root env_core.Root) (Target, error) { func TargetForURL(url *url.URL, root env_core.Root, basicAuth string) (Target, error) {
switch url.Scheme { switch url.Scheme {
case "file": case "file":
return NewFilesystemTarget(&FilesystemTargetConfig{Root: url.Path}), nil return NewFilesystemTarget(&FilesystemTargetConfig{Root: url.Path}), nil
@ -15,7 +16,17 @@ func TargetForURL(url *url.URL, root env_core.Root) (Target, error) {
return NewZrokTarget(&ZrokTargetConfig{URL: url, Root: root}) return NewZrokTarget(&ZrokTargetConfig{URL: url, Root: root})
case "http", "https": case "http", "https":
return NewWebDAVTarget(&WebDAVTargetConfig{URL: url, Username: "", Password: ""}) var username string
var password string
if basicAuth != "" {
authTokens := strings.Split(basicAuth, ":")
if len(authTokens) != 2 {
return nil, errors.Errorf("invalid basic authentication (expect 'username:password')")
}
username = authTokens[0]
password = authTokens[1]
}
return NewWebDAVTarget(&WebDAVTargetConfig{URL: url, Username: username, Password: password})
default: default:
return nil, errors.Errorf("unknown URL scheme '%v'", url.Scheme) return nil, errors.Errorf("unknown URL scheme '%v'", url.Scheme)

View File

@ -24,7 +24,12 @@ type WebDAVTarget struct {
} }
func NewWebDAVTarget(cfg *WebDAVTargetConfig) (*WebDAVTarget, error) { func NewWebDAVTarget(cfg *WebDAVTargetConfig) (*WebDAVTarget, error) {
dc, err := davClient.NewClient(http.DefaultClient, cfg.URL.String()) var httpClient davClient.HTTPClient
httpClient = http.DefaultClient
if cfg.Username != "" || cfg.Password != "" {
httpClient = davClient.HTTPClientWithBasicAuth(httpClient, cfg.Username, cfg.Password)
}
dc, err := davClient.NewClient(httpClient, cfg.URL.String())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -17,10 +17,8 @@ import (
) )
type ZrokTargetConfig struct { type ZrokTargetConfig struct {
URL *url.URL URL *url.URL
Username string Root env_core.Root
Password string
Root env_core.Root
} }
type ZrokTarget struct { type ZrokTarget struct {