mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-14 08:42:51 +02:00
pomerium-cli: add support for a custom browser command (#2617)
This commit is contained in:
parent
efffe57bf0
commit
a7442b1498
8 changed files with 58 additions and 17 deletions
|
@ -16,6 +16,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
addBrowserFlags(kubernetesExecCredentialCmd)
|
||||||
addTLSFlags(kubernetesExecCredentialCmd)
|
addTLSFlags(kubernetesExecCredentialCmd)
|
||||||
kubernetesCmd.AddCommand(kubernetesExecCredentialCmd)
|
kubernetesCmd.AddCommand(kubernetesExecCredentialCmd)
|
||||||
kubernetesCmd.AddCommand(kubernetesFlushCredentialsCmd)
|
kubernetesCmd.AddCommand(kubernetesFlushCredentialsCmd)
|
||||||
|
@ -61,7 +62,9 @@ var kubernetesExecCredentialCmd = &cobra.Command{
|
||||||
tlsConfig = getTLSConfig()
|
tlsConfig = getTLSConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
ac := authclient.New(authclient.WithTLSConfig(tlsConfig))
|
ac := authclient.New(
|
||||||
|
authclient.WithBrowserCommand(browserOptions.command),
|
||||||
|
authclient.WithTLSConfig(tlsConfig))
|
||||||
rawJWT, err := ac.GetJWT(context.Background(), serverURL)
|
rawJWT, err := ac.GetJWT(context.Background(), serverURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatalf("%s", err)
|
fatalf("%s", err)
|
||||||
|
|
|
@ -57,3 +57,13 @@ func getTLSConfig() *tls.Config {
|
||||||
}
|
}
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var browserOptions struct {
|
||||||
|
command string
|
||||||
|
}
|
||||||
|
|
||||||
|
func addBrowserFlags(cmd *cobra.Command) {
|
||||||
|
flags := cmd.Flags()
|
||||||
|
flags.StringVar(&browserOptions.command, "browser-cmd", "",
|
||||||
|
"custom browser command to run when opening a URL")
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ var tcpCmd = &cobra.Command{
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tun := tcptunnel.New(
|
tun := tcptunnel.New(
|
||||||
|
tcptunnel.WithBrowserCommand(browserOptions.command),
|
||||||
tcptunnel.WithDestinationHost(dstHost),
|
tcptunnel.WithDestinationHost(dstHost),
|
||||||
tcptunnel.WithProxyHost(pomeriumURL.Host),
|
tcptunnel.WithProxyHost(pomeriumURL.Host),
|
||||||
tcptunnel.WithTLSConfig(tlsConfig),
|
tcptunnel.WithTLSConfig(tlsConfig),
|
||||||
|
|
|
@ -9,14 +9,12 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/skratchdot/open-golang/open"
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
var openBrowser = open.Run
|
|
||||||
|
|
||||||
// An AuthClient retrieves an authentication JWT via the Pomerium login API.
|
// An AuthClient retrieves an authentication JWT via the Pomerium login API.
|
||||||
type AuthClient struct {
|
type AuthClient struct {
|
||||||
cfg *config
|
cfg *config
|
||||||
|
@ -141,5 +139,11 @@ func (client *AuthClient) runOpenBrowser(ctx context.Context, li net.Listener, s
|
||||||
return fmt.Errorf("failed to read login url: %w", err)
|
return fmt.Errorf("failed to read login url: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return openBrowser(string(bs))
|
err = client.cfg.open(string(bs))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open browser url: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "Your browser has been opened to visit:\n\n%s\n\n", string(bs))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,8 @@ func TestAuthClient(t *testing.T) {
|
||||||
_ = srv.Serve(li)
|
_ = srv.Serve(li)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
origOpenBrowser := openBrowser
|
ac := New()
|
||||||
defer func() {
|
ac.cfg.open = func(input string) error {
|
||||||
openBrowser = origOpenBrowser
|
|
||||||
}()
|
|
||||||
openBrowser = func(input string) error {
|
|
||||||
u, err := url.Parse(input)
|
u, err := url.Parse(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -64,7 +61,6 @@ func TestAuthClient(t *testing.T) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ac := New()
|
|
||||||
rawJWT, err := ac.GetJWT(ctx, &url.URL{
|
rawJWT, err := ac.GetJWT(ctx, &url.URL{
|
||||||
Scheme: "http",
|
Scheme: "http",
|
||||||
Host: li.Addr().String(),
|
Host: li.Addr().String(),
|
||||||
|
|
|
@ -2,14 +2,18 @@ package authclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
||||||
|
"github.com/skratchdot/open-golang/open"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
|
open func(rawURL string) error
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfig(options ...Option) *config {
|
func getConfig(options ...Option) *config {
|
||||||
cfg := new(config)
|
cfg := new(config)
|
||||||
|
WithBrowserCommand("")(cfg)
|
||||||
for _, o := range options {
|
for _, o := range options {
|
||||||
o(cfg)
|
o(cfg)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +23,19 @@ func getConfig(options ...Option) *config {
|
||||||
// An Option modifies the config.
|
// An Option modifies the config.
|
||||||
type Option func(*config)
|
type Option func(*config)
|
||||||
|
|
||||||
|
// WithBrowserCommand returns an option to configure the browser command.
|
||||||
|
func WithBrowserCommand(browserCommand string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
if browserCommand == "" {
|
||||||
|
cfg.open = open.Run
|
||||||
|
} else {
|
||||||
|
cfg.open = func(rawURL string) error {
|
||||||
|
return open.RunWith(rawURL, browserCommand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithTLSConfig returns an option to configure the tls config.
|
// WithTLSConfig returns an option to configure the tls config.
|
||||||
func WithTLSConfig(tlsConfig *tls.Config) Option {
|
func WithTLSConfig(tlsConfig *tls.Config) Option {
|
||||||
return func(cfg *config) {
|
return func(cfg *config) {
|
||||||
|
|
|
@ -9,10 +9,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
jwtCache cliutil.JWTCache
|
jwtCache cliutil.JWTCache
|
||||||
dstHost string
|
dstHost string
|
||||||
proxyHost string
|
proxyHost string
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
|
browserConfig string
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfig(options ...Option) *config {
|
func getConfig(options ...Option) *config {
|
||||||
|
@ -32,6 +33,13 @@ func getConfig(options ...Option) *config {
|
||||||
// An Option modifies the config.
|
// An Option modifies the config.
|
||||||
type Option func(*config)
|
type Option func(*config)
|
||||||
|
|
||||||
|
// WithBrowserCommand returns an option to configure the browser command.
|
||||||
|
func WithBrowserCommand(browserCommand string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.browserConfig = browserCommand
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithDestinationHost returns an option to configure the destination host.
|
// WithDestinationHost returns an option to configure the destination host.
|
||||||
func WithDestinationHost(dstHost string) Option {
|
func WithDestinationHost(dstHost string) Option {
|
||||||
return func(cfg *config) {
|
return func(cfg *config) {
|
||||||
|
|
|
@ -30,8 +30,10 @@ type Tunnel struct {
|
||||||
func New(options ...Option) *Tunnel {
|
func New(options ...Option) *Tunnel {
|
||||||
cfg := getConfig(options...)
|
cfg := getConfig(options...)
|
||||||
return &Tunnel{
|
return &Tunnel{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
auth: authclient.New(authclient.WithTLSConfig(cfg.tlsConfig)),
|
auth: authclient.New(
|
||||||
|
authclient.WithBrowserCommand(cfg.browserConfig),
|
||||||
|
authclient.WithTLSConfig(cfg.tlsConfig)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue