Skip to content

Commit

Permalink
tests for admin, update protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
FZambia committed Oct 30, 2024
1 parent d1e0ed6 commit 162ccf6
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 6 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/FZambia/eagle v0.1.0
github.com/FZambia/statik v0.1.2-0.20180217151304-b9f012bb2a1b
github.com/centrifugal/centrifuge v0.33.5-0.20241026095149-106d43f21426
github.com/centrifugal/protocol v0.13.5-0.20241030063749-f2e17f373602
github.com/centrifugal/protocol v0.13.5-0.20241030080628-ab8a125839c1
github.com/cristalhq/jwt/v5 v5.4.0
github.com/go-viper/mapstructure/v2 v2.1.0
github.com/gobwas/glob v0.2.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/centrifugal/centrifuge v0.33.5-0.20241026095149-106d43f21426 h1:g5zZaCr/BybYgq8Nqrnrvqvb3jGGO/Dloil3cFGzzbg=
github.com/centrifugal/centrifuge v0.33.5-0.20241026095149-106d43f21426/go.mod h1:Ck+7H3eVwoeyabKcj3L55oSunaORIOGPAIVB5xrQyGU=
github.com/centrifugal/protocol v0.13.5-0.20241030063749-f2e17f373602 h1:GdltAOXAFqR9i/q/DWbGzWFXv6x5ff/oPgZFuwlIZFQ=
github.com/centrifugal/protocol v0.13.5-0.20241030063749-f2e17f373602/go.mod h1:7V5vI30VcoxJe4UD87xi7bOsvI0bmEhvbQuMjrFM2L4=
github.com/centrifugal/protocol v0.13.5-0.20241030080628-ab8a125839c1 h1:itkwGpNchf1X8djN+S90koPptcnxzRGh2atzdw6ZZtc=
github.com/centrifugal/protocol v0.13.5-0.20241030080628-ab8a125839c1/go.mod h1:7V5vI30VcoxJe4UD87xi7bOsvI0bmEhvbQuMjrFM2L4=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
Expand Down
1 change: 0 additions & 1 deletion internal/admin/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func (s *Handler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
}

func (s *Handler) adminSecureTokenAuth(h http.Handler) http.Handler {

secret := s.config.Secret
insecure := s.config.Insecure

Expand Down
166 changes: 166 additions & 0 deletions internal/admin/handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package admin

import (
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

"github.com/centrifugal/centrifuge"
"github.com/stretchr/testify/require"
)

// TestNewHandler ensures NewHandler sets up routes and proxy handling correctly.
func TestNewHandler(t *testing.T) {
node := &centrifuge.Node{}
cfg := Config{HandlerPrefix: "/prefix", WebProxyAddress: "", WebPath: ""}
handler := NewHandler(node, nil, cfg)
require.NotNil(t, handler)
require.NotNil(t, handler.mux)

// Validate settings route is registered.
req := httptest.NewRequest("GET", "/prefix/admin/settings", nil)
resp := httptest.NewRecorder()
handler.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
}

// TestSettingsHandler checks the settingsHandler returns correct settings.
func TestSettingsHandler(t *testing.T) {
config := Config{Insecure: true}
handler := &Handler{config: config}
req := httptest.NewRequest("GET", "/admin/settings", nil)
resp := httptest.NewRecorder()

handler.settingsHandler(resp, req)
require.Equal(t, http.StatusOK, resp.Code)

var response map[string]any
err := json.NewDecoder(resp.Body).Decode(&response)
require.NoError(t, err)
require.Equal(t, "oss", response["edition"])
require.Equal(t, config.Insecure, response["insecure"])
}

// TestAuthHandler_NoPasswordOrSecret tests authHandler error when password or secret is missing.
func TestAuthHandler_NoPasswordOrSecret(t *testing.T) {
config := Config{Password: "", Secret: ""}
handler := &Handler{config: config}
req := httptest.NewRequest("POST", "/admin/auth", nil)
resp := httptest.NewRecorder()

handler.authHandler(resp, req)
require.Equal(t, http.StatusBadRequest, resp.Code)
}

// TestAuthHandler_ValidPassword tests authHandler token generation with valid password.
func TestAuthHandler_ValidPassword(t *testing.T) {
config := Config{Password: "test-password", Secret: "test-secret"}
handler := &Handler{config: config}
form := url.Values{}
form.Add("password", "test-password")
req := httptest.NewRequest("POST", "/admin/auth", strings.NewReader(form.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp := httptest.NewRecorder()

handler.authHandler(resp, req)
require.Equal(t, http.StatusOK, resp.Code)

var response map[string]string
err := json.NewDecoder(resp.Body).Decode(&response)
require.NoError(t, err)
require.NotEmpty(t, response["token"])
}

// TestAuthHandler_InvalidPassword tests authHandler rejection with invalid password.
func TestAuthHandler_InvalidPassword(t *testing.T) {
config := Config{Password: "test-password", Secret: "test-secret"}
handler := &Handler{config: config}
form := url.Values{}
form.Add("password", "wrong-password")
req := httptest.NewRequest("POST", "/admin/auth", strings.NewReader(form.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp := httptest.NewRecorder()

handler.authHandler(resp, req)
require.Equal(t, http.StatusBadRequest, resp.Code)
}

// TestAdminSecureTokenAuth_InsecureMode tests adminSecureTokenAuth allows request in insecure mode.
func TestAdminSecureTokenAuth_InsecureMode(t *testing.T) {
config := Config{Insecure: true}
handler := &Handler{config: config}

// Mocked handler that should be invoked
finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})

authHandler := handler.adminSecureTokenAuth(finalHandler)
req := httptest.NewRequest("GET", "/admin/api", nil)
resp := httptest.NewRecorder()

authHandler.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
}

// TestAdminSecureTokenAuth_MissingToken tests adminSecureTokenAuth rejection when token is missing.
func TestAdminSecureTokenAuth_MissingToken(t *testing.T) {
config := Config{Secret: "test-secret"}
handler := &Handler{config: config}

// Mocked handler that should not be invoked
finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})

authHandler := handler.adminSecureTokenAuth(finalHandler)
req := httptest.NewRequest("GET", "/admin/api", nil)
resp := httptest.NewRecorder()

authHandler.ServeHTTP(resp, req)
require.Equal(t, http.StatusUnauthorized, resp.Code)
}

// TestAdminSecureTokenAuth_ValidToken tests adminSecureTokenAuth with valid token.
func TestAdminSecureTokenAuth_ValidToken(t *testing.T) {
config := Config{Secret: "test-secret"}
handler := &Handler{config: config}

// Mocked handler that should be invoked
finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})

// Generate a valid token
token, err := generateSecureAdminToken("test-secret")
require.NoError(t, err)

authHandler := handler.adminSecureTokenAuth(finalHandler)
req := httptest.NewRequest("GET", "/admin/api?token="+token, nil)
resp := httptest.NewRecorder()

authHandler.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
}

// TestAdminSecureTokenAuth_InvalidToken tests adminSecureTokenAuth rejection with invalid token.
func TestAdminSecureTokenAuth_InvalidToken(t *testing.T) {
config := Config{Secret: "test-secret"}
handler := &Handler{config: config}

// Mocked handler that should not be invoked.
finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Fail(t, "final handler should not be invoked")
w.WriteHeader(http.StatusOK)
})

authHandler := handler.adminSecureTokenAuth(finalHandler)
req := httptest.NewRequest("GET", "/admin/api?token=invalid-token", nil)
resp := httptest.NewRecorder()

authHandler.ServeHTTP(resp, req)
require.Equal(t, http.StatusUnauthorized, resp.Code)
}
4 changes: 2 additions & 2 deletions internal/wt/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ func (s *Handler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

var decoder protocol.StreamCommandDecoder
if protoType == centrifuge.ProtocolTypeJSON {
decoder = protocol.GetStreamCommandDecoder(protocol.TypeJSON, stream, s.config.MessageSizeLimit)
decoder = protocol.GetStreamCommandDecoderLimited(protocol.TypeJSON, stream, int64(s.config.MessageSizeLimit))
defer protocol.PutStreamCommandDecoder(protocol.TypeJSON, decoder)
} else {
decoder = protocol.NewProtobufStreamCommandDecoder(stream, s.config.MessageSizeLimit)
decoder = protocol.NewProtobufStreamCommandDecoder(stream, int64(s.config.MessageSizeLimit))
defer protocol.PutStreamCommandDecoder(protocol.TypeProtobuf, decoder)
}

Expand Down

0 comments on commit 162ccf6

Please sign in to comment.