mirror of
https://github.com/fatedier/frp.git
synced 2026-04-29 04:29:11 +08:00
auth/oidc: fix eager token fetch at startup, add validation and e2e tests (#5234)
This commit is contained in:
@@ -1,14 +1,120 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/fatedier/frp/pkg/config/source"
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
)
|
||||
|
||||
type failingConnector struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *failingConnector) Open() error {
|
||||
return c.err
|
||||
}
|
||||
|
||||
func (c *failingConnector) Connect() (net.Conn, error) {
|
||||
return nil, c.err
|
||||
}
|
||||
|
||||
func (c *failingConnector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getFreeTCPPort(t *testing.T) int {
|
||||
t.Helper()
|
||||
|
||||
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("listen on ephemeral port: %v", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
return ln.Addr().(*net.TCPAddr).Port
|
||||
}
|
||||
|
||||
func TestRunStopsStartedComponentsOnInitialLoginFailure(t *testing.T) {
|
||||
port := getFreeTCPPort(t)
|
||||
agg := source.NewAggregator(source.NewConfigSource())
|
||||
|
||||
svr, err := NewService(ServiceOptions{
|
||||
Common: &v1.ClientCommonConfig{
|
||||
LoginFailExit: lo.ToPtr(true),
|
||||
WebServer: v1.WebServerConfig{
|
||||
Addr: "127.0.0.1",
|
||||
Port: port,
|
||||
},
|
||||
},
|
||||
ConfigSourceAggregator: agg,
|
||||
ConnectorCreator: func(context.Context, *v1.ClientCommonConfig) Connector {
|
||||
return &failingConnector{err: errors.New("login boom")}
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("new service: %v", err)
|
||||
}
|
||||
|
||||
err = svr.Run(context.Background())
|
||||
if err == nil {
|
||||
t.Fatal("expected run error, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "login boom") {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if svr.webServer != nil {
|
||||
t.Fatal("expected web server to be cleaned up after initial login failure")
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
|
||||
if err != nil {
|
||||
t.Fatalf("expected admin port to be released: %v", err)
|
||||
}
|
||||
_ = ln.Close()
|
||||
}
|
||||
|
||||
func TestNewServiceDoesNotLeakAdminListenerOnAuthBuildFailure(t *testing.T) {
|
||||
port := getFreeTCPPort(t)
|
||||
agg := source.NewAggregator(source.NewConfigSource())
|
||||
|
||||
_, err := NewService(ServiceOptions{
|
||||
Common: &v1.ClientCommonConfig{
|
||||
Auth: v1.AuthClientConfig{
|
||||
Method: v1.AuthMethodOIDC,
|
||||
OIDC: v1.AuthOIDCClientConfig{
|
||||
TokenEndpointURL: "://bad",
|
||||
},
|
||||
},
|
||||
WebServer: v1.WebServerConfig{
|
||||
Addr: "127.0.0.1",
|
||||
Port: port,
|
||||
},
|
||||
},
|
||||
ConfigSourceAggregator: agg,
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected new service error, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "auth.oidc.tokenEndpointURL") {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
|
||||
if err != nil {
|
||||
t.Fatalf("expected admin port to remain free: %v", err)
|
||||
}
|
||||
_ = ln.Close()
|
||||
}
|
||||
|
||||
func TestUpdateConfigSourceRollsBackReloadCommonOnReplaceAllFailure(t *testing.T) {
|
||||
prevCommon := &v1.ClientCommonConfig{User: "old-user"}
|
||||
newCommon := &v1.ClientCommonConfig{User: "new-user"}
|
||||
|
||||
Reference in New Issue
Block a user