Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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.

Name branches after the account, and labels after the display

474a812d199a109ba894124cd6f26be12c73285d · Keenan Nemetz · 16d ago · parent ade6107e

Name branches after the account, and labels after the display

A contributor's folder was `refs/heads/contrib/<account-id>/`, which told a
reader nothing without decoding a ULID. It is now the account name,

    refs/heads/contrib/<name>/<branch>

and the name is therefore fixed at creation: renaming an account would strand
every ref under its old folder, so `vole admin user rename` is gone and the
users row itself — kept after retirement — is what stops a name being reissued.

What people see is now a separate, mutable display name, validated by the same
rules wherever it is set (CLI, remote admin, registration, `/account`) and shown
on pages, approvals, listings and refusals. Nothing is authorized by it and
nothing on disk is keyed by it: metadata authors stay account names because the
push boundary resolves them for ownership, and approvals stay account ids.

`user_names`, `Snapshot.Reserved` and `Account.Former` are dropped: with a fixed
name there are no former names to remember, and the UNIQUE column already does
the reserving. Opening an older roster adds the `display` column and drops the
alias table in place; contributor refs written under the old id namespace are
left where they are, readable, and landable by a maintainer.

server/web/account.go +27

@@ -5,6 +5,33 @@ import (
5 5 "strings"
6 6 )
7 7
8 // SetAccountDisplay changes the signed-in account's display label. This is the
9 // one profile field a person owns: the account name is fixed at creation because
10 // refs and metadata files were written with it, but the label nobody is
11 // authorized by can be anything they like.
12 func (w *Web) SetAccountDisplay(rw http.ResponseWriter, r *http.Request) {
13 pr, ok := w.requireHTMLUser(rw, r)
14 if !ok {
15 return
16 }
17 r.Body = http.MaxBytesReader(rw, r.Body, 16<<10)
18 if !w.checkCSRF(r) {
19 http.Error(rw, "bad request", http.StatusForbidden)
20 return
21 }
22 if err := r.ParseForm(); err != nil {
23 http.Error(rw, "cannot read the form", http.StatusBadRequest)
24 return
25 }
26 display := strings.TrimSpace(r.PostFormValue("display"))
27 if _, err := w.Ident.SetDisplay(pr.account.ID, display, pr.account.Name); err != nil {
28 http.Error(rw, err.Error(), http.StatusBadRequest)
29 return
30 }
31 w.audit("web.display", pr.account.ID, display)
32 http.Redirect(rw, r, "/account", http.StatusSeeOther)
33 }
34
8 35 // AddAccountKey lets a signed-in person attach an SSH public key without an
9 36 // administrator. Open registration is only useful for Git contributions if the
10 37 // account can turn its browser session into a key that pushes.