Files
EvoBGP/internal/httpapi/routes_api_keys_test.go
DenozordecandCursor ec65249bf1
CI / changes (push) Successful in 7s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Has been skipped
CI / go (push) Successful in 41s
CI / bird2 (push) Successful in 16s
CI / release (push) Successful in 3m18s
fix(ci): satisfy golangci-lint in api keys code
Правки errcheck в тестах httpapi и gofmt полей APIKeyPatch в store.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 11:33:19 +07:00

120 lines
3.4 KiB
Go

package httpapi
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestBearerDevWithoutInsecureDev(t *testing.T) {
srv, err := New(Options{SeedDemo: true, BundleSeedHex: testBundleSeed})
if err != nil {
t.Fatal(err)
}
defer srv.Close()
ts := httptest.NewServer(srv.Handler())
defer ts.Close()
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/v1/modules?limit=1", nil)
req.Header.Set("Authorization", "Bearer dev")
resp, err := ts.Client().Do(req)
if err != nil {
t.Fatal(err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
b, _ := io.ReadAll(resp.Body)
t.Fatalf("status=%d body=%s", resp.StatusCode, b)
}
}
func TestAPIKeysCRUDAndAuth(t *testing.T) {
srv, err := New(Options{SeedDemo: true, BundleSeedHex: testBundleSeed})
if err != nil {
t.Fatal(err)
}
defer srv.Close()
tenant, _, _, _, _ := srv.Store().DemoIDs()
mustSetTestAPIKeys(t, srv, "opkey|"+tenant+"|operator")
ts := httptest.NewServer(srv.Handler())
defer ts.Close()
client := ts.Client()
base := ts.URL
reqCreate, _ := http.NewRequest(http.MethodPost, base+"/v1/api-keys", strings.NewReader(`{"name":"ci","role":"editor"}`))
reqCreate.Header.Set("Authorization", "Bearer opkey")
reqCreate.Header.Set("Content-Type", "application/json")
respCreate, err := client.Do(reqCreate)
if err != nil {
t.Fatal(err)
}
defer func() { _ = respCreate.Body.Close() }()
if respCreate.StatusCode != http.StatusCreated {
b, _ := io.ReadAll(respCreate.Body)
t.Fatalf("create status=%d body=%s", respCreate.StatusCode, b)
}
var created map[string]any
if err := json.NewDecoder(respCreate.Body).Decode(&created); err != nil {
t.Fatal(err)
}
token, _ := created["token"].(string)
if token == "" {
t.Fatal("missing token in create response")
}
id, _ := created["id"].(string)
if id == "" {
t.Fatal("missing id")
}
reqMod, _ := http.NewRequest(http.MethodGet, base+"/v1/modules?limit=1", nil)
reqMod.Header.Set("Authorization", "Bearer "+token)
respMod, err := client.Do(reqMod)
if err != nil {
t.Fatal(err)
}
defer func() { _ = respMod.Body.Close() }()
if respMod.StatusCode != http.StatusOK {
b, _ := io.ReadAll(respMod.Body)
t.Fatalf("modules status=%d body=%s", respMod.StatusCode, b)
}
reqDel, _ := http.NewRequest(http.MethodDelete, base+"/v1/api-keys/"+id, nil)
reqDel.Header.Set("Authorization", "Bearer opkey")
respDel, err := client.Do(reqDel)
if err != nil {
t.Fatal(err)
}
defer func() { _ = respDel.Body.Close() }()
if respDel.StatusCode != http.StatusNoContent {
t.Fatalf("delete status=%d", respDel.StatusCode)
}
reqAfter, _ := http.NewRequest(http.MethodGet, base+"/v1/modules?limit=1", nil)
reqAfter.Header.Set("Authorization", "Bearer "+token)
respAfter, err := client.Do(reqAfter)
if err != nil {
t.Fatal(err)
}
defer func() { _ = respAfter.Body.Close() }()
if respAfter.StatusCode != http.StatusUnauthorized {
t.Fatalf("expected 401 after revoke, got %d", respAfter.StatusCode)
}
mustSetTestAPIKeys(t, srv, "nodekey|"+tenant+"|node,opkey|"+tenant+"|operator")
reqNode2, _ := http.NewRequest(http.MethodGet, base+"/v1/api-keys", nil)
reqNode2.Header.Set("Authorization", "Bearer nodekey")
respNode, err := client.Do(reqNode2)
if err != nil {
t.Fatal(err)
}
defer func() { _ = respNode.Body.Close() }()
if respNode.StatusCode != http.StatusForbidden {
t.Fatalf("node list api-keys status=%d want 403", respNode.StatusCode)
}
}