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/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Identify accounts by their registered name

62576fa8157d431dcf2d360f3ebe481de77bda03 · Keenan Nemetz · 14d ago · parent 642e5994

Identify accounts by their registered name

Drop the internal account id and display name. Users, keys, passkeys,
invites, sessions, ACL entries, approvals, locks and CI records now all
use the registered name as the single identity.

The roster migrates in place: old id-keyed tables are rebuilt around the
name, and access-rule/lock references are rewritten through the same
mapping. Display-name editing and whoami --id are removed.

server/web/web.go +17−18

@@ -73,7 +73,7 @@ func New(repos *repo.Store, ix *index.Store, ident *identity.Store, rs *runs.Sto
73 73 sem: make(chan struct{}, archiveConc)}
74 74 // The templates are parsed after the Web exists so the roster-backed helper
75 75 // below can be a method: metadata files carry account names and approvals are
76 // keyed by ids, and a page should show the display label for either.
76 // keyed by names, and a page should show the account name for either.
77 77 w.Tmpl, err = template.New("vole").Funcs(template.FuncMap{
78 78 "since": humanSince,
79 79 "short": format.SHA,
@@ -107,18 +107,17 @@ func New(repos *repo.Store, ix *index.Store, ident *identity.Store, rs *runs.Sto
107 107 return w, nil
108 108 }
109 109
110 // who renders the account an id or name refers to as its display label. It is a
111 // presentation helper only: authors on disk stay account names and approvals
112 // stay ids, and nothing is authorized by what this returns.
113 func (w *Web) who(idOrName string) string {
114 if w.Ident == nil || idOrName == "" {
115 return idOrName
110 // who renders an account name for a page. It is a presentation helper only:
111 // nothing is authorized by what this returns.
112 func (w *Web) who(name string) string {
113 if w.Ident == nil || name == "" {
114 return name
116 115 }
117 a, err := w.Ident.Find(idOrName)
116 a, err := w.Ident.Find(name)
118 117 if err != nil {
119 return idOrName
118 return name
120 119 }
121 return a.Label()
120 return a.Name
122 121 }
123 122
124 123 // repoNav is the repository header's data: which repository, which tab is
@@ -148,11 +147,11 @@ type repoNavData struct {
148 147 // Page is embedded by every view. Exported so html/template can promote its
149 148 // fields; an unexported embedded type is not reachable from a template.
150 149 type Page struct {
151 Title string
152 Error string
153 LoggedIn bool
154 User string
155 AccountID string
150 Title string
151 Error string
152 LoggedIn bool
153 User string
154 AccountName string
156 155 // CSRF is derived from the session token and must be on every state-changing
157 156 // form or fetch.
158 157 CSRF string
@@ -178,11 +177,11 @@ func (w *Web) canRead(r *http.Request, m *repo.Meta) bool {
178 177 if err != nil {
179 178 return false
180 179 }
181 accountID := ""
180 name := ""
182 181 if p := w.principal(r); p != nil {
183 accountID = p.account.ID
182 name = p.account.Name
184 183 }
185 return a.Can(accountID, access.Read)
184 return a.Can(name, access.Read)
186 185 }
187 186
188 187 // htmxRequest reports whether a request came from HTMX. The same handler still