pgcli/vpn: remove oidc provider selector

This commit is contained in:
rkonfj
2024-07-04 20:02:48 +08:00
parent f6fa476a03
commit ab8ea6e59e
6 changed files with 45 additions and 38 deletions

View File

@@ -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)

2
go.mod
View File

@@ -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

9
go.sum
View File

@@ -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=

View File

@@ -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
}

View File

@@ -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, `<meta name="viewport" content="width=device-width, initial-scale=1.0">`)
fmt.Fprintf(w, `<style>body{font-size: 18px;line-height: 26px;margin: 0;padding: 10px}</style>`)
if len(providers) == 0 {
fmt.Fprintf(w, `OIDC not configured yet`)
return
}
fmt.Fprintf(w, `<b>Select an account to authenticate: </b><br />`)
for provider := range providers {
fmt.Fprintf(w, `<a href="//%s%s?state=%s">%s</a><br />`,
cmp.Or(r.Header.Get("host"), r.Host), path.Join(r.URL.Path, provider), state, provider)
}
}

View File

@@ -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