mirror of
https://github.com/fatedier/frp.git
synced 2025-12-14 03:55:47 +00:00
add tokenSource support for auth configuration (#4865)
This commit is contained in:
217
test/e2e/v1/basic/token_source.go
Normal file
217
test/e2e/v1/basic/token_source.go
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright 2025 The frp Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package basic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
|
||||
"github.com/fatedier/frp/test/e2e/framework"
|
||||
"github.com/fatedier/frp/test/e2e/framework/consts"
|
||||
"github.com/fatedier/frp/test/e2e/pkg/port"
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("[Feature: TokenSource]", func() {
|
||||
f := framework.NewDefaultFramework()
|
||||
|
||||
ginkgo.Describe("File-based token loading", func() {
|
||||
ginkgo.It("should work with file tokenSource", func() {
|
||||
// Create a temporary token file
|
||||
tmpDir := f.TempDirectory
|
||||
tokenFile := filepath.Join(tmpDir, "test_token")
|
||||
tokenContent := "test-token-123"
|
||||
|
||||
err := os.WriteFile(tokenFile, []byte(tokenContent), 0o600)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
serverConf := consts.DefaultServerConfig
|
||||
clientConf := consts.DefaultClientConfig
|
||||
|
||||
portName := port.GenName("TCP")
|
||||
|
||||
// Server config with tokenSource
|
||||
serverConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
`, tokenFile)
|
||||
|
||||
// Client config with matching token
|
||||
clientConf += fmt.Sprintf(`
|
||||
auth.token = "%s"
|
||||
|
||||
[[proxies]]
|
||||
name = "tcp"
|
||||
type = "tcp"
|
||||
localPort = {{ .%s }}
|
||||
remotePort = {{ .%s }}
|
||||
`, tokenContent, framework.TCPEchoServerPort, portName)
|
||||
|
||||
f.RunProcesses([]string{serverConf}, []string{clientConf})
|
||||
|
||||
framework.NewRequestExpect(f).PortName(portName).Ensure()
|
||||
})
|
||||
|
||||
ginkgo.It("should work with client tokenSource", func() {
|
||||
// Create a temporary token file
|
||||
tmpDir := f.TempDirectory
|
||||
tokenFile := filepath.Join(tmpDir, "client_token")
|
||||
tokenContent := "client-token-456"
|
||||
|
||||
err := os.WriteFile(tokenFile, []byte(tokenContent), 0o600)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
serverConf := consts.DefaultServerConfig
|
||||
clientConf := consts.DefaultClientConfig
|
||||
|
||||
portName := port.GenName("TCP")
|
||||
|
||||
// Server config with matching token
|
||||
serverConf += fmt.Sprintf(`
|
||||
auth.token = "%s"
|
||||
`, tokenContent)
|
||||
|
||||
// Client config with tokenSource
|
||||
clientConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
|
||||
[[proxies]]
|
||||
name = "tcp"
|
||||
type = "tcp"
|
||||
localPort = {{ .%s }}
|
||||
remotePort = {{ .%s }}
|
||||
`, tokenFile, framework.TCPEchoServerPort, portName)
|
||||
|
||||
f.RunProcesses([]string{serverConf}, []string{clientConf})
|
||||
|
||||
framework.NewRequestExpect(f).PortName(portName).Ensure()
|
||||
})
|
||||
|
||||
ginkgo.It("should work with both server and client tokenSource", func() {
|
||||
// Create temporary token files
|
||||
tmpDir := f.TempDirectory
|
||||
serverTokenFile := filepath.Join(tmpDir, "server_token")
|
||||
clientTokenFile := filepath.Join(tmpDir, "client_token")
|
||||
tokenContent := "shared-token-789"
|
||||
|
||||
err := os.WriteFile(serverTokenFile, []byte(tokenContent), 0o600)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
err = os.WriteFile(clientTokenFile, []byte(tokenContent), 0o600)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
serverConf := consts.DefaultServerConfig
|
||||
clientConf := consts.DefaultClientConfig
|
||||
|
||||
portName := port.GenName("TCP")
|
||||
|
||||
// Server config with tokenSource
|
||||
serverConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
`, serverTokenFile)
|
||||
|
||||
// Client config with tokenSource
|
||||
clientConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
|
||||
[[proxies]]
|
||||
name = "tcp"
|
||||
type = "tcp"
|
||||
localPort = {{ .%s }}
|
||||
remotePort = {{ .%s }}
|
||||
`, clientTokenFile, framework.TCPEchoServerPort, portName)
|
||||
|
||||
f.RunProcesses([]string{serverConf}, []string{clientConf})
|
||||
|
||||
framework.NewRequestExpect(f).PortName(portName).Ensure()
|
||||
})
|
||||
|
||||
ginkgo.It("should fail with mismatched tokens", func() {
|
||||
// Create temporary token files with different content
|
||||
tmpDir := f.TempDirectory
|
||||
serverTokenFile := filepath.Join(tmpDir, "server_token")
|
||||
clientTokenFile := filepath.Join(tmpDir, "client_token")
|
||||
|
||||
err := os.WriteFile(serverTokenFile, []byte("server-token"), 0o600)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
err = os.WriteFile(clientTokenFile, []byte("client-token"), 0o600)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
serverConf := consts.DefaultServerConfig
|
||||
clientConf := consts.DefaultClientConfig
|
||||
|
||||
portName := port.GenName("TCP")
|
||||
|
||||
// Server config with tokenSource
|
||||
serverConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
`, serverTokenFile)
|
||||
|
||||
// Client config with different tokenSource
|
||||
clientConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
|
||||
[[proxies]]
|
||||
name = "tcp"
|
||||
type = "tcp"
|
||||
localPort = {{ .%s }}
|
||||
remotePort = {{ .%s }}
|
||||
`, clientTokenFile, framework.TCPEchoServerPort, portName)
|
||||
|
||||
f.RunProcesses([]string{serverConf}, []string{clientConf})
|
||||
|
||||
// This should fail due to token mismatch - the client should not be able to connect
|
||||
// We expect the request to fail because the proxy tunnel is not established
|
||||
framework.NewRequestExpect(f).PortName(portName).ExpectError(true).Ensure()
|
||||
})
|
||||
|
||||
ginkgo.It("should fail with non-existent token file", func() {
|
||||
// This test verifies that server fails to start when tokenSource points to non-existent file
|
||||
// We'll verify this by checking that the configuration loading itself fails
|
||||
|
||||
// Create a config that references a non-existent file
|
||||
tmpDir := f.TempDirectory
|
||||
nonExistentFile := filepath.Join(tmpDir, "non_existent_token")
|
||||
|
||||
serverConf := consts.DefaultServerConfig
|
||||
|
||||
// Server config with non-existent tokenSource file
|
||||
serverConf += fmt.Sprintf(`
|
||||
auth.tokenSource.type = "file"
|
||||
auth.tokenSource.file.path = "%s"
|
||||
`, nonExistentFile)
|
||||
|
||||
// The test expectation is that this will fail during the RunProcesses call
|
||||
// because the server cannot load the configuration due to missing token file
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// Expected: server should fail to start due to missing file
|
||||
ginkgo.By(fmt.Sprintf("Server correctly failed to start: %v", r))
|
||||
}
|
||||
}()
|
||||
|
||||
// This should cause a panic or error during server startup
|
||||
f.RunProcesses([]string{serverConf}, []string{})
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user