mirror of
https://github.com/sigcn/pg.git
synced 2025-10-28 05:31:26 +08:00
pgcli/vpn: remove oidc provider selector
This commit is contained in:
@@ -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
2
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
|
||||
|
||||
9
go.sum
9
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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user