package server import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "path/filepath" "testing" "task/internal/sqlite" ) func TestProjectTokenBearerAuth(t *testing.T) { db, err := sqlite.Open(filepath.Join(t.TempDir(), "t.db"), []byte("secret")) if err != nil { t.Fatal(err) } defer db.Close() admin, err := db.CreateUser("admin", "pass", true) if err != nil { t.Fatal(err) } srv := New(db) handler := srv.Handler() loginBody, _ := json.Marshal(map[string]string{"username": "admin", "password": "pass"}) req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/login", bytes.NewReader(loginBody)) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) cookie := rec.Result().Cookies()[0] createBody, _ := json.Marshal(map[string]string{"name": "Demo"}) req = httptest.NewRequest(http.MethodPost, "/api/v1/projects", bytes.NewReader(createBody)) req.Header.Set("Content-Type", "application/json") req.AddCookie(cookie) rec = httptest.NewRecorder() handler.ServeHTTP(rec, req) var proj map[string]any _ = json.Unmarshal(rec.Body.Bytes(), &proj) pid := proj["id"].(string) tokBody, _ := json.Marshal(map[string]string{"name": "tui", "scope": "write"}) req = httptest.NewRequest(http.MethodPost, "/api/v1/projects/"+pid+"/tokens", bytes.NewReader(tokBody)) req.Header.Set("Content-Type", "application/json") req.AddCookie(cookie) rec = httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusCreated { t.Fatalf("create token %d %s", rec.Code, rec.Body.String()) } var tok map[string]any _ = json.Unmarshal(rec.Body.Bytes(), &tok) raw := tok["token"].(string) if raw == "" { t.Fatal("expected raw token") } ticketBody, _ := json.Marshal(map[string]string{"title": "Via token"}) req = httptest.NewRequest(http.MethodPost, "/api/v1/projects/"+pid+"/tickets", bytes.NewReader(ticketBody)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+raw) rec = httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusCreated { t.Fatalf("bearer create ticket %d %s", rec.Code, rec.Body.String()) } req = httptest.NewRequest(http.MethodGet, "/api/v1/projects/"+pid+"/tickets", nil) req.Header.Set("Authorization", "Bearer "+raw) rec = httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("bearer list %d", rec.Code) } // delete other user _, _ = db.CreateUser("bob", "x", false) users, _ := db.ListUsers() var bobID string for _, u := range users { if u.Username == "bob" { bobID = u.ID } } req = httptest.NewRequest(http.MethodDelete, "/api/v1/users/"+bobID, nil) req.AddCookie(cookie) rec = httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("delete user %d %s", rec.Code, rec.Body.String()) } patch, _ := json.Marshal(map[string]bool{"isAdmin": false}) req = httptest.NewRequest(http.MethodPatch, "/api/v1/users/"+admin.ID, bytes.NewReader(patch)) req.Header.Set("Content-Type", "application/json") req.AddCookie(cookie) rec = httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code == http.StatusOK { t.Fatal("should not demote self") } }