carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "net/http"
6 "net/url"
7 "testing"
8
9 "github.com/carlosframework/platform/internal/objstore"
10)
11
12func TestRevivalPollingWithoutCallbackKeys(t *testing.T) {
13 fx, _, member, _ := storeArmed(t, "revival-poll-only")
14 grantStore(t, fx, member)
15 requestScanning(t, fx, member, false)
16 scanner := objstore.NewMemScanner()
17 fx.srv.cfg.StoreScanner = scanner
18 fx.srv.cfg.CallbackSigner = nil
19 fx.srv.cfg.SecretsPub = ""
20 enableDeploymentScanning(t, fx)
21 if status, out := postJSON(t, scanURL(fx, "titogo")+"/grant", map[string]any{}, member); status != http.StatusOK {
22 t.Fatalf("grant without callback or sealing keys = %d %v", status, out)
23 }
24 rec := storedRecord(t, fx, "titogo")
25 if rec.Scanning.WebhookGen != 0 || rec.Scanning.WebhookKeyID != "" {
26 t.Fatalf("polling-only grant created callback state: %+v", rec.Scanning)
27 }
28 if _, exists := appVars(t, fx, "titogo")[objstore.DefaultEnvPrefix+"_SCAN_CALLBACK_SECRET"]; exists {
29 t.Fatal("polling-only grant delivered a callback secret")
30 }
31
32 token := appToken(t, fx, "poll-only")
33 key := " uploads/report.pdf "
34 bucket := rec.Provisioned.Bucket
35 seedObject(scanner, bucket, key, "infected-upload")
36 scanner.ScanAs(key, objstore.VerdictInfected)
37 other := "uploads/report.pdf"
38 version := seedObject(scanner, bucket, other, "clean-other-upload")
39 scanner.Put(bucket, other, version, objstore.VerdictClean)
40 if status, out := postJSON(t, enqueueURL(fx, "titogo"), map[string]any{"key": key}, token); status != http.StatusAccepted {
41 t.Fatalf("enqueue = %d %v", status, out)
42 }
43 if status, out := getStatus(t, fx, token, "key="+url.QueryEscape(key)); status != http.StatusOK || out["state"] != "pending" {
44 t.Fatalf("before drain = %d %v, want pending for the exact key", status, out)
45 }
46 if err := fx.srv.scanDrainTick(context.Background()); err != nil {
47 t.Fatal(err)
48 }
49 if status, out := getStatus(t, fx, token, "key="+url.QueryEscape(key)); status != http.StatusOK || out["state"] != "infected" {
50 t.Fatalf("after drain = %d %v, want infected for the exact key", status, out)
51 }
52 if scanner.Scans(key) != 1 || scanner.Scans(other) != 0 {
53 t.Fatalf("wrong objects scanned: requested=%d other=%d", scanner.Scans(key), scanner.Scans(other))
54 }
55 if n := queueLen(t, fx, fx.sqid, "titogo"); n != 0 {
56 t.Fatalf("queue after drain = %d", n)
57 }
58 if status, out := postJSON(t, enqueueURL(fx, "titogo"), map[string]any{"key": key, "callback_path": "/hooks/scan"}, token); status != http.StatusServiceUnavailable || out["reason"] != "callbacks_not_configured" {
59 t.Fatalf("callback without signer = %d %v", status, out)
60 }
61}
62