mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-10-06 12:09:07 +00:00
Improve gateway auth middleware to use internal auth context
Enforce GATEWAY_API_KEY in Makefile E2E test target Fix gateway E2E test payload reading to use io.ReadAll Remove deprecated multi-node test targets and cleanup Makefile comments
This commit is contained in:
parent
895f1d5dff
commit
03b3b38967
37
Makefile
37
Makefile
@ -5,9 +5,15 @@ test:
|
||||
@echo Running tests...
|
||||
go test -v $(TEST)
|
||||
|
||||
# Gateway-focused E2E tests assume gateway and nodes are already running
|
||||
# Configure via env:
|
||||
# GATEWAY_BASE_URL (default http://127.0.0.1:8080)
|
||||
# GATEWAY_API_KEY (required for auth-protected routes)
|
||||
.PHONY: test-e2e
|
||||
test-e2e:
|
||||
@echo Running E2E tests...
|
||||
@echo "Running gateway E2E tests (HTTP/WS only)..."
|
||||
@echo "Base URL: $${GATEWAY_BASE_URL:-http://127.0.0.1:8080}"
|
||||
@test -n "$$GATEWAY_API_KEY" || (echo "GATEWAY_API_KEY must be set" && exit 1)
|
||||
go test -v -tags e2e ./e2e
|
||||
|
||||
# Network - Distributed P2P Database System
|
||||
@ -37,11 +43,6 @@ clean:
|
||||
rm -rf data/
|
||||
@echo "Clean complete!"
|
||||
|
||||
# Run tests
|
||||
test:
|
||||
@echo "Running tests..."
|
||||
go test -v ./...
|
||||
|
||||
# Run bootstrap node (auto-selects identity and data dir)
|
||||
run-node:
|
||||
@echo "Starting bootstrap node with config..."
|
||||
@ -151,30 +152,6 @@ dev-setup: deps
|
||||
@mkdir -p data/test-bootstrap data/test-node1 data/test-node2
|
||||
@echo "Development setup complete!"
|
||||
|
||||
# Multi-node testing
|
||||
test-multinode: build
|
||||
@echo "🧪 Starting comprehensive multi-node test..."
|
||||
@chmod +x scripts/test-multinode.sh
|
||||
@./scripts/test-multinode.sh
|
||||
|
||||
test-peer-discovery: build
|
||||
@echo "🔍 Testing peer discovery (requires running nodes)..."
|
||||
@echo "Connected peers:"
|
||||
@./bin/network-cli peers --timeout 10s
|
||||
|
||||
test-replication: build
|
||||
@echo "🔄 Testing data replication (requires running nodes)..."
|
||||
@./bin/network-cli storage put "replication:test:$$(date +%s)" "Test data - $$(date)"
|
||||
@sleep 2
|
||||
@echo "Retrieving replicated data:"
|
||||
@./bin/network-cli storage list replication:test:
|
||||
|
||||
test-consensus: build
|
||||
@echo "🗄️ Testing database consensus (requires running nodes)..."
|
||||
@./bin/network-cli query "CREATE TABLE IF NOT EXISTS consensus_test (id INTEGER PRIMARY KEY, test_data TEXT, timestamp TEXT)"
|
||||
@./bin/network-cli query "INSERT INTO consensus_test (test_data, timestamp) VALUES ('Makefile test', '$$(date)')"
|
||||
@./bin/network-cli query "SELECT * FROM consensus_test ORDER BY id DESC LIMIT 5"
|
||||
|
||||
# Start development cluster (requires multiple terminals)
|
||||
dev-cluster:
|
||||
@echo "To start a development cluster, run these commands in separate terminals:"
|
||||
|
@ -3,11 +3,11 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -111,10 +111,9 @@ func TestGateway_Storage_PutGetListExistsDelete(t *testing.T) {
|
||||
if err != nil { t.Fatalf("get do: %v", err) }
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK { t.Fatalf("get status: %d", resp.StatusCode) }
|
||||
got := make([]byte, len(payload))
|
||||
n, _ := resp.Body.Read(got)
|
||||
if n == 0 || string(got[:n]) != string(payload[:n]) {
|
||||
t.Fatalf("payload mismatch: want %q got %q", string(payload), string(got[:n]))
|
||||
got, _ := io.ReadAll(resp.Body)
|
||||
if string(got) != string(payload) {
|
||||
t.Fatalf("payload mismatch: want %q got %q", string(payload), string(got))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.debros.io/DeBros/network/pkg/client"
|
||||
"git.debros.io/DeBros/network/pkg/logging"
|
||||
"git.debros.io/DeBros/network/pkg/storage"
|
||||
"go.uber.org/zap"
|
||||
@ -97,10 +98,11 @@ func (g *Gateway) authMiddleware(next http.Handler) http.Handler {
|
||||
|
||||
// Look up API key in DB and derive namespace
|
||||
db := g.client.Database()
|
||||
ctx := r.Context()
|
||||
// Use internal auth for DB validation (auth not established yet)
|
||||
internalCtx := client.WithInternalAuth(r.Context())
|
||||
// Join to namespaces to resolve name in one query
|
||||
q := "SELECT namespaces.name FROM api_keys JOIN namespaces ON api_keys.namespace_id = namespaces.id WHERE api_keys.key = ? LIMIT 1"
|
||||
res, err := db.Query(ctx, q, key)
|
||||
res, err := db.Query(internalCtx, q, key)
|
||||
if err != nil || res == nil || res.Count == 0 || len(res.Rows) == 0 || len(res.Rows[0]) == 0 {
|
||||
w.Header().Set("WWW-Authenticate", "Bearer error=\"invalid_token\"")
|
||||
writeError(w, http.StatusUnauthorized, "invalid API key")
|
||||
@ -122,9 +124,9 @@ func (g *Gateway) authMiddleware(next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
// Attach auth metadata to context for downstream use
|
||||
ctx = context.WithValue(ctx, ctxKeyAPIKey, key)
|
||||
ctx = storage.WithNamespace(ctx, ns)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
reqCtx := context.WithValue(r.Context(), ctxKeyAPIKey, key)
|
||||
reqCtx = storage.WithNamespace(reqCtx, ns)
|
||||
next.ServeHTTP(w, r.WithContext(reqCtx))
|
||||
})
|
||||
}
|
||||
|
||||
@ -224,14 +226,15 @@ func (g *Gateway) authorizationMiddleware(next http.Handler) http.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
// Check ownership in DB
|
||||
// Check ownership in DB using internal auth context
|
||||
db := g.client.Database()
|
||||
internalCtx := client.WithInternalAuth(ctx)
|
||||
// Ensure namespace exists and get id
|
||||
if _, err := db.Query(ctx, "INSERT OR IGNORE INTO namespaces(name) VALUES (?)", ns); err != nil {
|
||||
if _, err := db.Query(internalCtx, "INSERT OR IGNORE INTO namespaces(name) VALUES (?)", ns); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
nres, err := db.Query(ctx, "SELECT id FROM namespaces WHERE name = ? LIMIT 1", ns)
|
||||
nres, err := db.Query(internalCtx, "SELECT id FROM namespaces WHERE name = ? LIMIT 1", ns)
|
||||
if err != nil || nres == nil || nres.Count == 0 || len(nres.Rows) == 0 || len(nres.Rows[0]) == 0 {
|
||||
writeError(w, http.StatusForbidden, "namespace not found")
|
||||
return
|
||||
@ -239,7 +242,7 @@ func (g *Gateway) authorizationMiddleware(next http.Handler) http.Handler {
|
||||
nsID := nres.Rows[0][0]
|
||||
|
||||
q := "SELECT 1 FROM namespace_ownership WHERE namespace_id = ? AND owner_type = ? AND owner_id = ? LIMIT 1"
|
||||
res, err := db.Query(ctx, q, nsID, ownerType, ownerID)
|
||||
res, err := db.Query(internalCtx, q, nsID, ownerType, ownerID)
|
||||
if err != nil || res == nil || res.Count == 0 {
|
||||
writeError(w, http.StatusForbidden, "forbidden: not an owner of namespace")
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user