mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-11 10:18:50 +00:00
Enhance configuration validation for nodes and gateways, implementing strict YAML decoding to reject unknown fields. Added comprehensive validation checks for node types, listen addresses, database settings, and discovery parameters. Updated README with configuration validation details and examples.
This commit is contained in:
parent
279c03df82
commit
60affaec5c
@ -8,14 +8,21 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
|
||||
|
||||
### Added
|
||||
|
||||
- Added validation for yaml files
|
||||
- Added authenticaiton command on cli
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated readme
|
||||
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
|
||||
- Regular nodes rqlite not starting
|
||||
|
||||
## [0.51.2] - 2025-09-26
|
||||
|
||||
### Added
|
||||
|
||||
2
Makefile
2
Makefile
@ -21,7 +21,7 @@ test-e2e:
|
||||
|
||||
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports
|
||||
|
||||
VERSION := 0.51.3-beta
|
||||
VERSION := 0.51.4-beta
|
||||
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
||||
|
||||
145
cmd/cli/main.go
145
cmd/cli/main.go
@ -76,6 +76,8 @@ func main() {
|
||||
handleConnect(args[0])
|
||||
case "peer-id":
|
||||
handlePeerID()
|
||||
case "auth":
|
||||
handleAuth(args)
|
||||
case "help", "--help", "-h":
|
||||
showHelp()
|
||||
|
||||
@ -289,6 +291,145 @@ func handlePubSub(args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleAuth(args []string) {
|
||||
if len(args) == 0 {
|
||||
showAuthHelp()
|
||||
return
|
||||
}
|
||||
|
||||
subcommand := args[0]
|
||||
switch subcommand {
|
||||
case "login":
|
||||
handleAuthLogin()
|
||||
case "logout":
|
||||
handleAuthLogout()
|
||||
case "whoami":
|
||||
handleAuthWhoami()
|
||||
case "status":
|
||||
handleAuthStatus()
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown auth command: %s\n", subcommand)
|
||||
showAuthHelp()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func handleAuthLogin() {
|
||||
gatewayURL := auth.GetDefaultGatewayURL()
|
||||
fmt.Printf("🔐 Authenticating with gateway at: %s\n", gatewayURL)
|
||||
|
||||
// Use the wallet authentication flow
|
||||
creds, err := auth.PerformWalletAuthentication(gatewayURL)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Authentication failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Save credentials to file
|
||||
if err := auth.SaveCredentialsForDefaultGateway(creds); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Failed to save credentials: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
credsPath, _ := auth.GetCredentialsPath()
|
||||
fmt.Printf("✅ Authentication successful!\n")
|
||||
fmt.Printf("📁 Credentials saved to: %s\n", credsPath)
|
||||
fmt.Printf("🎯 Wallet: %s\n", creds.Wallet)
|
||||
fmt.Printf("🏢 Namespace: %s\n", creds.Namespace)
|
||||
}
|
||||
|
||||
func handleAuthLogout() {
|
||||
if err := auth.ClearAllCredentials(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Failed to clear credentials: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("✅ Logged out successfully - all credentials have been cleared")
|
||||
}
|
||||
|
||||
func handleAuthWhoami() {
|
||||
store, err := auth.LoadCredentials()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Failed to load credentials: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gatewayURL := auth.GetDefaultGatewayURL()
|
||||
creds, exists := store.GetCredentialsForGateway(gatewayURL)
|
||||
|
||||
if !exists || !creds.IsValid() {
|
||||
fmt.Println("❌ Not authenticated - run 'network-cli auth login' to authenticate")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("✅ Authenticated")
|
||||
fmt.Printf(" Wallet: %s\n", creds.Wallet)
|
||||
fmt.Printf(" Namespace: %s\n", creds.Namespace)
|
||||
fmt.Printf(" Issued At: %s\n", creds.IssuedAt.Format("2006-01-02 15:04:05"))
|
||||
if !creds.ExpiresAt.IsZero() {
|
||||
fmt.Printf(" Expires At: %s\n", creds.ExpiresAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
if !creds.LastUsedAt.IsZero() {
|
||||
fmt.Printf(" Last Used: %s\n", creds.LastUsedAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
if creds.Plan != "" {
|
||||
fmt.Printf(" Plan: %s\n", creds.Plan)
|
||||
}
|
||||
}
|
||||
|
||||
func handleAuthStatus() {
|
||||
store, err := auth.LoadCredentials()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Failed to load credentials: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gatewayURL := auth.GetDefaultGatewayURL()
|
||||
creds, exists := store.GetCredentialsForGateway(gatewayURL)
|
||||
|
||||
fmt.Println("🔐 Authentication Status")
|
||||
fmt.Printf(" Gateway URL: %s\n", gatewayURL)
|
||||
|
||||
if !exists || creds == nil {
|
||||
fmt.Println(" Status: ❌ Not authenticated")
|
||||
return
|
||||
}
|
||||
|
||||
if !creds.IsValid() {
|
||||
fmt.Println(" Status: ⚠️ Credentials expired")
|
||||
if !creds.ExpiresAt.IsZero() {
|
||||
fmt.Printf(" Expired At: %s\n", creds.ExpiresAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(" Status: ✅ Authenticated")
|
||||
fmt.Printf(" Wallet: %s\n", creds.Wallet)
|
||||
fmt.Printf(" Namespace: %s\n", creds.Namespace)
|
||||
if !creds.ExpiresAt.IsZero() {
|
||||
fmt.Printf(" Expires: %s\n", creds.ExpiresAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
if !creds.LastUsedAt.IsZero() {
|
||||
fmt.Printf(" Last Used: %s\n", creds.LastUsedAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
}
|
||||
|
||||
func showAuthHelp() {
|
||||
fmt.Printf("🔐 Authentication Commands\n\n")
|
||||
fmt.Printf("Usage: network-cli auth <subcommand>\n\n")
|
||||
fmt.Printf("Subcommands:\n")
|
||||
fmt.Printf(" login - Authenticate with wallet\n")
|
||||
fmt.Printf(" logout - Clear stored credentials\n")
|
||||
fmt.Printf(" whoami - Show current authentication status\n")
|
||||
fmt.Printf(" status - Show detailed authentication info\n\n")
|
||||
fmt.Printf("Examples:\n")
|
||||
fmt.Printf(" network-cli auth login\n")
|
||||
fmt.Printf(" network-cli auth whoami\n")
|
||||
fmt.Printf(" network-cli auth status\n")
|
||||
fmt.Printf(" network-cli auth logout\n\n")
|
||||
fmt.Printf("Environment Variables:\n")
|
||||
fmt.Printf(" DEBROS_GATEWAY_URL - Gateway URL (default: http://localhost:6001)\n")
|
||||
}
|
||||
|
||||
func ensureAuthenticated() *auth.Credentials {
|
||||
gatewayURL := auth.GetDefaultGatewayURL()
|
||||
|
||||
@ -440,6 +581,7 @@ func showHelp() {
|
||||
fmt.Printf("Usage: network-cli <command> [args...]\n\n")
|
||||
fmt.Printf("🔐 Authentication: Commands requiring authentication will automatically prompt for wallet connection.\n\n")
|
||||
fmt.Printf("Commands:\n")
|
||||
fmt.Printf(" auth <subcommand> 🔐 Authentication management (login, logout, whoami, status)\n")
|
||||
fmt.Printf(" health - Check network health\n")
|
||||
fmt.Printf(" peers - List connected peers\n")
|
||||
fmt.Printf(" status - Show network status\n")
|
||||
@ -457,10 +599,13 @@ func showHelp() {
|
||||
fmt.Printf(" -t, --timeout <duration> - Operation timeout (default: 30s)\n")
|
||||
fmt.Printf(" --production - Connect to production bootstrap peers\n\n")
|
||||
fmt.Printf("Authentication:\n")
|
||||
fmt.Printf(" Use 'network-cli auth login' to authenticate with your wallet\n")
|
||||
fmt.Printf(" Commands marked with 🔐 will automatically prompt for wallet authentication\n")
|
||||
fmt.Printf(" if no valid credentials are found. You can manage multiple wallets and\n")
|
||||
fmt.Printf(" choose between them during the authentication flow.\n\n")
|
||||
fmt.Printf("Examples:\n")
|
||||
fmt.Printf(" network-cli auth login\n")
|
||||
fmt.Printf(" network-cli auth whoami\n")
|
||||
fmt.Printf(" network-cli health\n")
|
||||
fmt.Printf(" network-cli peer-id\n")
|
||||
fmt.Printf(" network-cli peer-id --format json\n")
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
// ValidateConfig performs comprehensive validation of gateway configuration.
|
||||
@ -35,7 +34,7 @@ func (c *Config) ValidateConfig() []error {
|
||||
for i, peer := range c.BootstrapPeers {
|
||||
path := fmt.Sprintf("gateway.bootstrap_peers[%d]", i)
|
||||
|
||||
ma, err := multiaddr.NewMultiaddr(peer)
|
||||
_, err := multiaddr.NewMultiaddr(peer)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("%s: invalid multiaddr: %v; expected /ip{4,6}/.../tcp/<port>/p2p/<peerID>", path, err))
|
||||
continue
|
||||
@ -46,16 +45,16 @@ func (c *Config) ValidateConfig() []error {
|
||||
errs = append(errs, fmt.Errorf("%s: missing /p2p/<peerID> component; expected /ip{4,6}/.../tcp/<port>/p2p/<peerID>", path))
|
||||
}
|
||||
|
||||
// Try to extract TCP addr to validate port
|
||||
tcpAddr, err := manet.ToNetAddr(ma)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("%s: cannot convert to network address: %v", path, err))
|
||||
// Extract TCP port by parsing the multiaddr string directly
|
||||
tcpPortStr := extractTCPPort(peer)
|
||||
if tcpPortStr == "" {
|
||||
errs = append(errs, fmt.Errorf("%s: missing /tcp/<port> component; expected /ip{4,6}/.../tcp/<port>/p2p/<peerID>", path))
|
||||
continue
|
||||
}
|
||||
|
||||
tcpPort := tcpAddr.(*net.TCPAddr).Port
|
||||
if tcpPort < 1 || tcpPort > 65535 {
|
||||
errs = append(errs, fmt.Errorf("%s: invalid TCP port %d; port must be between 1 and 65535", path, tcpPort))
|
||||
tcpPort, err := strconv.Atoi(tcpPortStr)
|
||||
if err != nil || tcpPort < 1 || tcpPort > 65535 {
|
||||
errs = append(errs, fmt.Errorf("%s: invalid TCP port %s; port must be between 1 and 65535", path, tcpPortStr))
|
||||
}
|
||||
|
||||
if seenPeers[peer] {
|
||||
@ -115,3 +114,24 @@ func validateRQLiteDSN(dsn string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractTCPPort extracts the TCP port from a multiaddr string.
|
||||
// It assumes the multiaddr is in the format /ip{4,6}/.../tcp/<port>/p2p/<peerID>.
|
||||
func extractTCPPort(multiaddrStr string) string {
|
||||
// Find the last /tcp/ component
|
||||
lastTCPIndex := strings.LastIndex(multiaddrStr, "/tcp/")
|
||||
if lastTCPIndex == -1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Extract the port part after /tcp/
|
||||
portPart := multiaddrStr[lastTCPIndex+len("/tcp/"):]
|
||||
|
||||
// Find the first / component after the port part
|
||||
firstSlashIndex := strings.Index(portPart, "/")
|
||||
if firstSlashIndex == -1 {
|
||||
return portPart
|
||||
}
|
||||
|
||||
return portPart[:firstSlashIndex]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user