From ab8ea6e59e76f8fcc83705066ea0f5b9c50ea01c Mon Sep 17 00:00:00 2001 From: rkonfj Date: Thu, 4 Jul 2024 20:02:48 +0800 Subject: [PATCH] pgcli/vpn: remove oidc provider selector --- cmd/pgcli/vpn/vpn.go | 43 ++++++++++++++++---------------------- go.mod | 2 -- go.sum | 9 -------- peermap/network/network.go | 9 ++++++-- peermap/oidc/http.go | 18 ++++++++++++++++ peermap/peermap.go | 2 ++ 6 files changed, 45 insertions(+), 38 deletions(-) diff --git a/cmd/pgcli/vpn/vpn.go b/cmd/pgcli/vpn/vpn.go index f3058a0..c49572d 100644 --- a/cmd/pgcli/vpn/vpn.go +++ b/cmd/pgcli/vpn/vpn.go @@ -17,14 +17,12 @@ import ( "syscall" "time" - "github.com/manifoldco/promptui" "github.com/mdp/qrterminal/v3" "github.com/rkonfj/peerguard/disco" "github.com/rkonfj/peerguard/p2p" "github.com/rkonfj/peerguard/peer" "github.com/rkonfj/peerguard/peer/peermap" "github.com/rkonfj/peerguard/peermap/network" - "github.com/rkonfj/peerguard/peermap/oidc" "github.com/rkonfj/peerguard/vpn" "github.com/rkonfj/peerguard/vpn/iface" "github.com/spf13/cobra" @@ -60,6 +58,7 @@ func init() { Cmd.Flags().Float64("disco-challenges-backoff-rate", 1.65, "ping challenges backoff rate when disco") Cmd.Flags().Bool("pprof", false, "enable http pprof server") + Cmd.Flags().Bool("auth-qr", false, "display the QR code when authentication is required") Cmd.MarkFlagsOneRequired("ipv4", "ipv6") } @@ -140,6 +139,10 @@ func createConfig(cmd *cobra.Command) (cfg Config, err error) { if err != nil { return } + cfg.AuthQR, err = cmd.Flags().GetBool("auth-qr") + if err != nil { + return + } cfg.Server, err = cmd.Flags().GetString("server") if err != nil { return @@ -164,6 +167,7 @@ type Config struct { PrivateKey string SecretFile string Server string + AuthQR bool } type P2PVPN struct { @@ -307,33 +311,22 @@ func (v *P2PVPN) loginIfNecessary(ctx context.Context) (peer.SecretStore, error) } func (v *P2PVPN) requestNetworkSecret(ctx context.Context) (peer.NetworkSecret, error) { - prompt := promptui.Select{ - Label: "Select OpenID Connect Provider", - Items: []string{oidc.ProviderGoogle, oidc.ProviderGithub}, - HideHelp: true, - Templates: &promptui.SelectTemplates{ - Label: "🔑 {{.}}", - Active: "> {{.}}", - Selected: "{{green `✔`}} {{green .}} {{cyan `use the browser to open the following URL for authentication`}}", - }, - } - _, provider, err := prompt.Run() - if err != nil { - return peer.NetworkSecret{}, err - } - join, err := network.JoinOIDC(provider, v.Config.Server) + join, err := network.JoinOIDC("", v.Config.Server) if err != nil { slog.Error("JoinNetwork failed", "err", err) return peer.NetworkSecret{}, err } - fmt.Println("AuthURL:", join.AuthURL()) - qrterminal.GenerateWithConfig(join.AuthURL(), qrterminal.Config{ - Level: qrterminal.L, - Writer: os.Stdout, - BlackChar: qrterminal.WHITE, - WhiteChar: qrterminal.BLACK, - QuietZone: 1, - }) + fmt.Println("Open the following link to authenticate") + fmt.Println(join.AuthURL()) + if v.Config.AuthQR { + qrterminal.GenerateWithConfig(join.AuthURL(), qrterminal.Config{ + Level: qrterminal.L, + Writer: os.Stdout, + BlackChar: qrterminal.WHITE, + WhiteChar: qrterminal.BLACK, + QuietZone: 1, + }) + } ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) defer cancel() return join.Wait(ctx) diff --git a/go.mod b/go.mod index 377f97a..8b87121 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.22 require ( github.com/coreos/go-oidc/v3 v3.9.0 github.com/gorilla/websocket v1.5.1 - github.com/manifoldco/promptui v0.9.0 github.com/mdp/qrterminal/v3 v3.2.0 github.com/schollz/progressbar/v3 v3.14.2 github.com/spf13/cobra v1.8.0 @@ -23,7 +22,6 @@ require ( ) require ( - github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect diff --git a/go.sum b/go.sum index df337f0..90b35cd 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,3 @@ -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo= github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -23,8 +17,6 @@ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZH github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= -github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= -github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mdp/qrterminal/v3 v3.2.0 h1:qteQMXO3oyTK4IHwj2mWsKYYRBOp1Pj2WRYFYYNTCdk= github.com/mdp/qrterminal/v3 v3.2.0/go.mod h1:XGGuua4Lefrl7TLEsSONiD+UEjQXJZ4mPzF+gWYIJkk= @@ -61,7 +53,6 @@ golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/peermap/network/network.go b/peermap/network/network.go index 848623d..030bbae 100644 --- a/peermap/network/network.go +++ b/peermap/network/network.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/url" + "path" "github.com/rkonfj/peerguard/peer" "storj.io/common/base58" @@ -27,7 +28,7 @@ func (intent *JoinIntent) AuthURL() string { } func (intent *JoinIntent) Wait(ctx context.Context) (joined peer.NetworkSecret, err error) { - tokenURL := fmt.Sprintf("https://%s/network/token?state=%s", intent.peermap.Host, intent.state) + tokenURL := fmt.Sprintf("https://%s/oidc/secret?state=%s", intent.peermap.Host, intent.state) req, err := http.NewRequestWithContext(ctx, http.MethodGet, tokenURL, nil) if err != nil { return @@ -52,11 +53,15 @@ func JoinOIDC(oidcProvider, peermap string) (*JoinIntent, error) { if err != nil { return nil, err } + joinPath := "/oidc" + if oidcProvider != "" { + joinPath = path.Join(joinPath, oidcProvider) + } state := make([]byte, 12) rand.Read(state) return &JoinIntent{ state: base58.Encode(state), - authURL: fmt.Sprintf("https://%s/oidc/%s", peermapURL.Host, oidcProvider), + authURL: fmt.Sprintf("https://%s%s", peermapURL.Host, joinPath), peermap: peermapURL, }, nil } diff --git a/peermap/oidc/http.go b/peermap/oidc/http.go index 6c5bae6..4e84e65 100644 --- a/peermap/oidc/http.go +++ b/peermap/oidc/http.go @@ -1,11 +1,13 @@ package oidc import ( + "cmp" "context" "encoding/json" "errors" "fmt" "net/http" + "path" "sync" "time" @@ -59,3 +61,19 @@ func RedirectAuthURL(w http.ResponseWriter, r *http.Request) { authURL := provider.oAuthConfig.AuthCodeURL(r.URL.Query().Get("state")) http.Redirect(w, r, authURL, http.StatusFound) } + +func OIDCSelector(w http.ResponseWriter, r *http.Request) { + state := r.URL.Query().Get("state") + w.Header().Set("Content-Type", "text/html") + fmt.Fprintf(w, ``) + fmt.Fprintf(w, ``) + if len(providers) == 0 { + fmt.Fprintf(w, `OIDC not configured yet`) + return + } + fmt.Fprintf(w, `Select an account to authenticate:
`) + for provider := range providers { + fmt.Fprintf(w, `%s
`, + cmp.Or(r.Header.Get("host"), r.Host), path.Join(r.URL.Path, provider), state, provider) + } +} diff --git a/peermap/peermap.go b/peermap/peermap.go index 39f5123..1888721 100644 --- a/peermap/peermap.go +++ b/peermap/peermap.go @@ -781,6 +781,8 @@ func New(cfg Config) (*PeerMap, error) { mux.HandleFunc("PUT /pg/networks/{network}/meta", pm.HandlePutNetworkMeta) mux.HandleFunc("GET /network/token", oidc.HandleNotifyToken) + mux.HandleFunc("GET /oidc", oidc.OIDCSelector) + mux.HandleFunc("GET /oidc/secret", oidc.HandleNotifyToken) mux.HandleFunc("GET /oidc/{provider}", oidc.RedirectAuthURL) mux.HandleFunc("GET /oidc/authorize/{provider}", pm.HandleOIDCAuthorize) return &pm, nil