Skip to content
quarry Artifact [fefa58d1a7]
Login

Artifact [fefa58d1a7]

Artifact fefa58d1a7b3f3b58979af68aa4278eda7e69a243603b743a10dc8964ff7b00a:


package cibridge

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

// A RUNNER GETS ITS JOB'S RUN TOKEN ONLY FOR A TASK IT HOLDS (RFC 0021
// §runs). The body names nothing: what is minted is the forge's call
// from its own records, and a refusal is a note for the job's log.
func TestARunTokenGoesOnlyToTheRunnerHoldingTheTask(t *testing.T) {
	engine := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/v1/tasks/run1.publish/resolve" || r.Header.Get("Authorization") != "Bearer CLAIMER" {
			http.Error(w, "task not claimed by this token", http.StatusForbidden)
			return
		}
		w.WriteHeader(http.StatusOK)
	}))
	defer engine.Close()
	var asked []string
	token := func(repo, taskID string) (map[string]string, string, error) {
		asked = append(asked, repo+" "+taskID)
		return map[string]string{"QUARRY_USER": "run-abc", "QUARRY_TOKEN": "qrt_abc_s3cret"}, "", nil
	}
	h, err := Handler(engine.URL, "ADMIN", func(string) string { return "g" }, func(r string) bool { return r == "alpha" }, nil, token)
	if err != nil {
		t.Fatal(err)
	}
	ask := func(bearer string) *httptest.ResponseRecorder {
		req := httptest.NewRequest("POST", "/r/alpha/ci/bridge/v1/tasks/run1.publish/token", strings.NewReader(`{}`))
		if bearer != "" {
			req.Header.Set("Authorization", "Bearer "+bearer)
		}
		rec := httptest.NewRecorder()
		h.ServeHTTP(rec, req)
		return rec
	}
	rec := ask("CLAIMER")
	var out struct {
		Env  map[string]string `json:"env"`
		Note string            `json:"note"`
	}
	json.Unmarshal(rec.Body.Bytes(), &out)
	if rec.Code != 200 || out.Env["QUARRY_TOKEN"] != "qrt_abc_s3cret" || out.Env["QUARRY_USER"] != "run-abc" || rec.Header().Get("Cache-Control") != "no-store" {
		t.Errorf("FAIL: the claiming runner got %d %q; want the token, uncached", rec.Code, rec.Body)
	}
	for _, b := range []string{"OTHER", "ADMIN", ""} {
		if rec := ask(b); rec.Code < 400 || strings.Contains(rec.Body.String(), "s3cret") {
			t.Errorf("FAIL: bearer %q got %d %q; want a refusal and no token", b, rec.Code, rec.Body)
		}
	}
	if len(asked) != 1 {
		t.Errorf("FAIL: the forge was asked %v; want only for the claiming runner", asked)
	}
	t.Log("ok: the token goes to the claiming runner alone, uncached")
}