Skip to content
quarry Artifact [f3eb0bb897]
Login

Artifact [f3eb0bb897]

Artifact f3eb0bb8979e77e9ab84f8172d0eac69684540c9874d386fb0f3cfd1ce07dbd4:


package web

import (
	"net/http/httptest"
	"net/url"
	"sync"
	"testing"
	"time"

	"craftdesign.group/quarry/internal/api"
	"craftdesign.group/quarry/internal/ops"
)

// memMirrorUV is a mirror table in memory, with the import's half.
type memMirrorUV struct {
	mu sync.Mutex
	m  map[string]api.Mirror
	pw map[string]string
}

func (s *memMirrorUV) Mirrors() ([]api.Mirror, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	var out []api.Mirror
	for _, m := range s.m {
		out = append(out, m)
	}
	return out, nil
}
func (s *memMirrorUV) MirrorFor(repo string) (api.Mirror, bool, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	m, ok := s.m[repo]
	return m, ok, nil
}
func (s *memMirrorUV) SetMirror(repo, u string, every int) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	m := s.m[repo]
	if m.URL != u {
		m.UVUser, m.UVCredential = "", false
	}
	m.Repo, m.URL, m.Every, m.Enabled = repo, u, every, true
	s.m[repo] = m
	return nil
}
func (s *memMirrorUV) DetachMirror(string) error                                       { return nil }
func (s *memMirrorUV) SetMirrorWrites(string, bool) error                              { return nil }
func (s *memMirrorUV) RecordMirrorRun(string, time.Duration, bool, error) (int, error) { return 0, nil }
func (s *memMirrorUV) MirrorPulls(string, int) ([]api.MirrorPull, error)               { return nil, nil }
func (s *memMirrorUV) MirrorDiverged(string, string, time.Time) error                  { return nil }
func (s *memMirrorUV) SetMirrorUV(repo string, on bool) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	m := s.m[repo]
	m.UV = on
	s.m[repo] = m
	return nil
}
func (s *memMirrorUV) SetMirrorUVCredential(repo, user, pw string) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	m := s.m[repo]
	m.UVUser, m.UVCredential = user, user != ""
	s.m[repo], s.pw[repo] = m, pw
	return nil
}
func (s *memMirrorUV) MirrorUVCredential(repo string) (string, string, bool, error) {
	m, _, _ := s.MirrorFor(repo)
	return m.UVUser, s.pw[repo], m.UVCredential, nil
}
func (s *memMirrorUV) RecordMirrorUV(string, string, int, string) error { return nil }

// The fleet form saves the mirror and its import as one: a field the
// import refuses leaves the address and the credential as they were.
func TestFleetMirrorFormNeverHalfApplies(t *testing.T) {
	store := &memMirrorUV{m: map[string]api.Mirror{"test": {Repo: "test", URL: "https://a.example/x", Every: 3600, Enabled: true,
		UVUser: "puller", UVCredential: true}}, pw: map[string]string{"test": "secret"}}
	accts := newBetaAccts()
	_ = accts.AddAccount("root", "root-pw", true)
	r := ops.NewRegistry()
	// No UV catalog: this forge keeps no unversioned files, so the
	// switch is blocked for every repository.
	if err := api.RegisterAll(r, api.Deps{Version: "v", Accounts: accts, Mirrors: store, MirrorUV: store,
		Repos: api.NewRepos(map[string]*api.Repo{"test": {}})}); err != nil {
		t.Fatal(err)
	}
	srv := httptest.NewServer(HandlerWith(r, nil, nil,
		[]Option{WithSessions(&betaSessions{accts: accts, admin: "root"}), WithCaps(betaCaps{admin: "root"})},
		Verify(func(string, string, string, ops.Auth) api.Decision { return api.Denied })))
	defer srv.Close()
	post := func(f url.Values) int {
		res := as(t, srv, "root", "POST", "/fleet/mirror", f)
		body(res)
		return res.StatusCode
	}
	form := url.Values{"repo": {"test"}, "url": {"https://b.example/x"}, "every": {"3600"}, "uvform": {"1"},
		"uvuser": {"puller"}, "uvpassword": {""}}
	code := post(form)
	m, _, _ := store.MirrorFor("test")
	check := func(ok bool, pass, fail string, args ...any) {
		t.Helper()
		if ok {
			t.Log("ok: " + pass)
		} else {
			t.Errorf("FAIL: "+fail, args...)
		}
	}
	check(code >= 400 && m.URL == "https://a.example/x" && m.UVCredential && store.pw["test"] == "secret",
		"a new address with the old login and no password is refused before either is saved",
		"status %d, mirror %+v", code, m)

	form.Set("url", "https://a.example/x")
	form.Set("every", "7200")
	form.Set("uv", "1")
	code = post(form)
	m, _, _ = store.MirrorFor("test")
	check(code >= 400 && m.Every == 3600 && !m.UV,
		"the switch on where the store cannot import is refused before the interval is saved",
		"status %d, mirror %+v", code, m)

	form.Del("uv")
	code = post(form)
	m, _, _ = store.MirrorFor("test")
	check(code == 303 && m.Every == 7200 && m.UVCredential && store.pw["test"] == "secret",
		"the same form with the switch off saves, keeping the held password",
		"status %d, mirror %+v", code, m)
}