vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Create accounts with a key and find the instance config
c36d507302c0f7fb24af6eba390c4121d67318c3 · Keenan Nemetz · 16d ago · parent 3abbe749
Create accounts with a key and find the instance config An account is now written with its first key in one transaction, so a name cannot be claimed without a credential. add-key remains for additional keys, and remote user create forwards the key on stdin. Local commands now resolve the config from --config, VOLE_CONFIG, ./vole.toml, or ~/.vole/vole.toml before falling back to defaults. init prints --config in its next steps when the instance will not be discovered automatically.
server/integration_test.go +4−9
| @@ -110,13 +110,10 @@ func newFixtureWith(t *testing.T, tweak func(*config.Config)) *fixture { | |||
| 110 | 110 | if err != nil { | |
| 111 | 111 | t.Fatal(err) | |
| 112 | 112 | } | |
| 113 | owner, err := ident.Create("keenan", "test") | ||
| 113 | owner, err := ident.Create("keenan", pub, "test") | ||
| 114 | 114 | if err != nil { | |
| 115 | 115 | t.Fatal(err) | |
| 116 | 116 | } | |
| 117 | if _, err := ident.AddKey("keenan", pub, "test"); err != nil { | ||
| 118 | t.Fatal(err) | ||
| 119 | } | ||
| 120 | 117 | ||
| 121 | 118 | log := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{Level: slog.LevelError})) | |
| 122 | 119 | srv, err := server.New(cfg, binPath, log) | |
| @@ -174,13 +171,10 @@ func keypair(t *testing.T, path string) (pubLine, privPath string) { | |||
| 174 | 171 | func (f *fixture) addWriter(t *testing.T) string { | |
| 175 | 172 | t.Helper() | |
| 176 | 173 | pub, priv := keypair(t, filepath.Join(f.cfg.DataDir, "id_writer")) | |
| 177 | writer, err := f.srv.Identity.Create("wilbur", "test") | ||
| 174 | writer, err := f.srv.Identity.Create("wilbur", pub, "test") | ||
| 178 | 175 | if err != nil { | |
| 179 | 176 | t.Fatal(err) | |
| 180 | 177 | } | |
| 181 | if _, err := f.srv.Identity.AddKey(writer.ID, pub, "test"); err != nil { | ||
| 182 | t.Fatal(err) | ||
| 183 | } | ||
| 184 | 178 | m := mustRepo(t, f) | |
| 185 | 179 | a, err := m.ACL() | |
| 186 | 180 | if err != nil { | |
| @@ -2569,7 +2563,8 @@ func TestRetiredNameCannotBeReissued(t *testing.T) { | |||
| 2569 | 2563 | if _, err := f.srv.Identity.Retire("wilbur", "test"); err != nil { | |
| 2570 | 2564 | t.Fatal(err) | |
| 2571 | 2565 | } | |
| 2572 | if _, err := f.srv.Identity.Create("wilbur", "test"); err == nil { | ||
| 2566 | reissue, _ := keypair(t, filepath.Join(f.cfg.DataDir, "id_reissued")) | ||
| 2567 | if _, err := f.srv.Identity.Create("wilbur", reissue, "test"); err == nil { | ||
| 2573 | 2568 | t.Fatal("the retired name was reissued") | |
| 2574 | 2569 | } | |
| 2575 | 2570 | // And the retired key no longer authenticates. | |