2026-03-03 12:50:24 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/http/httptest"
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestLoginValid(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
admin := testAdminUser(t, app)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
|
|
|
|
req := testRequest("POST", "/api/login", map[string]string{
|
2026-03-10 14:08:00 -05:00
|
|
|
"email": admin.Email,
|
2026-03-03 12:50:24 -06:00
|
|
|
"password": "admin123",
|
|
|
|
|
})
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusOK {
|
|
|
|
|
t.Fatalf("status = %d, want 200\nbody: %s", w.Code, w.Body.String())
|
|
|
|
|
}
|
|
|
|
|
result := parseJSON(t, w)
|
|
|
|
|
if result["token"] == nil || result["token"] == "" {
|
|
|
|
|
t.Error("missing token in response")
|
|
|
|
|
}
|
|
|
|
|
user, ok := result["user"].(map[string]any)
|
2026-03-10 14:08:00 -05:00
|
|
|
if !ok || user["email"] != "oberon@athens.example" {
|
2026-03-03 12:50:24 -06:00
|
|
|
t.Errorf("user = %v", result["user"])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestLoginWrongPassword(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
testAdminUser(t, app)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
|
|
|
|
req := testRequest("POST", "/api/login", map[string]string{
|
2026-03-10 14:08:00 -05:00
|
|
|
"email": "oberon@athens.example",
|
2026-03-03 12:50:24 -06:00
|
|
|
"password": "wrong",
|
|
|
|
|
})
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusUnauthorized {
|
|
|
|
|
t.Errorf("status = %d, want 401", w.Code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestLoginNonexistentUser(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
|
|
|
|
req := testRequest("POST", "/api/login", map[string]string{
|
2026-03-10 14:08:00 -05:00
|
|
|
"email": "nobody@test.com",
|
2026-03-03 12:50:24 -06:00
|
|
|
"password": "test",
|
|
|
|
|
})
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusUnauthorized {
|
|
|
|
|
t.Errorf("status = %d, want 401", w.Code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAuthMiddlewareNoToken(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
|
|
|
|
req := testRequest("GET", "/api/me", nil)
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusUnauthorized {
|
|
|
|
|
t.Errorf("status = %d, want 401", w.Code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAuthMiddlewareInvalidToken(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
|
|
|
|
req := testAuthRequest("GET", "/api/me", nil, "bad-token")
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusUnauthorized {
|
|
|
|
|
t.Errorf("status = %d, want 401", w.Code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAuthMiddlewareRoleEnforcement(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
2026-03-10 14:08:00 -05:00
|
|
|
gate := testUserWithRoles(t, app, "Starveling", []string{"gatekeeper"}, []int{})
|
2026-03-03 12:50:24 -06:00
|
|
|
token := testToken(t, app, gate)
|
|
|
|
|
|
|
|
|
|
req := testAuthRequest("GET", "/api/users", nil, token)
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusForbidden {
|
|
|
|
|
t.Errorf("status = %d, want 403", w.Code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestMeEndpoint(t *testing.T) {
|
|
|
|
|
app := testApp(t)
|
|
|
|
|
admin := testAdminUser(t, app)
|
|
|
|
|
token := testToken(t, app, admin)
|
|
|
|
|
mux := testMux(app)
|
|
|
|
|
|
|
|
|
|
req := testAuthRequest("GET", "/api/me", nil, token)
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
mux.ServeHTTP(w, req)
|
|
|
|
|
|
|
|
|
|
if w.Code != http.StatusOK {
|
|
|
|
|
t.Fatalf("status = %d", w.Code)
|
|
|
|
|
}
|
|
|
|
|
result := parseJSON(t, w)
|
2026-03-10 14:08:00 -05:00
|
|
|
if result["email"] != "oberon@athens.example" {
|
|
|
|
|
t.Errorf("email = %v", result["email"])
|
2026-03-03 12:50:24 -06:00
|
|
|
}
|
|
|
|
|
}
|