238 lines
5.8 KiB
Go
238 lines
5.8 KiB
Go
package auth
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestCookieSessionStore(t *testing.T) {
|
|
store := NewCookieSessionStore("test-secret-key", 3600)
|
|
|
|
t.Run("create and retrieve session", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
userID := "test-user-123"
|
|
err := store.CreateSession(w, r, userID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create session: %v", err)
|
|
}
|
|
|
|
// Get the cookie from the response
|
|
cookies := w.Result().Cookies()
|
|
if len(cookies) == 0 {
|
|
t.Fatal("Expected session cookie, got none")
|
|
}
|
|
|
|
// Create a new request with the cookie
|
|
r2 := httptest.NewRequest("GET", "/", nil)
|
|
for _, cookie := range cookies {
|
|
r2.AddCookie(cookie)
|
|
}
|
|
|
|
retrievedUserID, err := store.GetUserID(r2)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get user ID: %v", err)
|
|
}
|
|
|
|
if retrievedUserID != userID {
|
|
t.Errorf("Expected user ID %s, got %s", userID, retrievedUserID)
|
|
}
|
|
})
|
|
|
|
t.Run("get user ID without session", func(t *testing.T) {
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
_, err := store.GetUserID(r)
|
|
if err == nil {
|
|
t.Error("Expected error when getting user ID without session")
|
|
}
|
|
})
|
|
|
|
t.Run("destroy session", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
userID := "test-user-456"
|
|
err := store.CreateSession(w, r, userID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create session: %v", err)
|
|
}
|
|
|
|
// Get the cookie
|
|
cookies := w.Result().Cookies()
|
|
r2 := httptest.NewRequest("GET", "/", nil)
|
|
for _, cookie := range cookies {
|
|
r2.AddCookie(cookie)
|
|
}
|
|
|
|
// Destroy the session
|
|
w2 := httptest.NewRecorder()
|
|
err = store.DestroySession(w2, r2)
|
|
if err != nil {
|
|
t.Fatalf("Failed to destroy session: %v", err)
|
|
}
|
|
|
|
// Check that the cookie has MaxAge set to -1 (deletion marker)
|
|
destroyCookies := w2.Result().Cookies()
|
|
if len(destroyCookies) == 0 {
|
|
t.Fatal("Expected cookie with MaxAge=-1 for deletion")
|
|
}
|
|
|
|
foundDeleteCookie := false
|
|
for _, cookie := range destroyCookies {
|
|
if cookie.MaxAge == -1 {
|
|
foundDeleteCookie = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundDeleteCookie {
|
|
t.Error("Expected cookie with MaxAge=-1 to indicate deletion")
|
|
}
|
|
})
|
|
|
|
t.Run("update existing session", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
// Create initial session
|
|
userID1 := "user-1"
|
|
store.CreateSession(w, r, userID1)
|
|
|
|
cookies := w.Result().Cookies()
|
|
r2 := httptest.NewRequest("GET", "/", nil)
|
|
for _, cookie := range cookies {
|
|
r2.AddCookie(cookie)
|
|
}
|
|
|
|
// Update session with new user ID
|
|
w2 := httptest.NewRecorder()
|
|
userID2 := "user-2"
|
|
err := store.CreateSession(w2, r2, userID2)
|
|
if err != nil {
|
|
t.Fatalf("Failed to update session: %v", err)
|
|
}
|
|
|
|
// Verify new user ID
|
|
cookies2 := w2.Result().Cookies()
|
|
r3 := httptest.NewRequest("GET", "/", nil)
|
|
for _, cookie := range cookies2 {
|
|
r3.AddCookie(cookie)
|
|
}
|
|
|
|
retrievedUserID, err := store.GetUserID(r3)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get user ID: %v", err)
|
|
}
|
|
|
|
if retrievedUserID != userID2 {
|
|
t.Errorf("Expected user ID %s, got %s", userID2, retrievedUserID)
|
|
}
|
|
})
|
|
|
|
t.Run("validate session with valid session", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
userID := "test-user-789"
|
|
err := store.CreateSession(w, r, userID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create session: %v", err)
|
|
}
|
|
|
|
// Create request with session cookie
|
|
cookies := w.Result().Cookies()
|
|
r2 := httptest.NewRequest("GET", "/", nil)
|
|
for _, cookie := range cookies {
|
|
r2.AddCookie(cookie)
|
|
}
|
|
|
|
// Validate session
|
|
if !store.ValidateSession(r2) {
|
|
t.Error("Expected ValidateSession to return true for valid session")
|
|
}
|
|
})
|
|
|
|
t.Run("validate session without session", func(t *testing.T) {
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
// Validate session without any cookies
|
|
if store.ValidateSession(r) {
|
|
t.Error("Expected ValidateSession to return false for missing session")
|
|
}
|
|
})
|
|
|
|
t.Run("validate session after logout", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
userID := "test-user-logout"
|
|
err := store.CreateSession(w, r, userID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create session: %v", err)
|
|
}
|
|
|
|
// Get the cookie
|
|
cookies := w.Result().Cookies()
|
|
r2 := httptest.NewRequest("GET", "/", nil)
|
|
for _, cookie := range cookies {
|
|
r2.AddCookie(cookie)
|
|
}
|
|
|
|
// Destroy the session
|
|
w2 := httptest.NewRecorder()
|
|
err = store.DestroySession(w2, r2)
|
|
if err != nil {
|
|
t.Fatalf("Failed to destroy session: %v", err)
|
|
}
|
|
|
|
// Create a new request without any cookies (simulating browser behavior after logout)
|
|
r3 := httptest.NewRequest("GET", "/", nil)
|
|
|
|
// Validate session should return false
|
|
if store.ValidateSession(r3) {
|
|
t.Error("Expected ValidateSession to return false after logout")
|
|
}
|
|
})
|
|
|
|
t.Run("session cookie has security settings", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest("GET", "/", nil)
|
|
|
|
userID := "test-user-security"
|
|
err := store.CreateSession(w, r, userID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create session: %v", err)
|
|
}
|
|
|
|
cookies := w.Result().Cookies()
|
|
if len(cookies) == 0 {
|
|
t.Fatal("Expected session cookie, got none")
|
|
}
|
|
|
|
cookie := cookies[0]
|
|
|
|
// Verify HttpOnly flag is set
|
|
if !cookie.HttpOnly {
|
|
t.Error("Expected HttpOnly flag to be true")
|
|
}
|
|
|
|
// Verify SameSite is set
|
|
if cookie.SameSite != http.SameSiteLaxMode {
|
|
t.Errorf("Expected SameSite to be Lax, got %v", cookie.SameSite)
|
|
}
|
|
|
|
// Verify Path is set
|
|
if cookie.Path != "/" {
|
|
t.Errorf("Expected Path to be /, got %s", cookie.Path)
|
|
}
|
|
|
|
// Verify MaxAge is set
|
|
if cookie.MaxAge != 3600 {
|
|
t.Errorf("Expected MaxAge to be 3600, got %d", cookie.MaxAge)
|
|
}
|
|
})
|
|
}
|