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/admin_users.go +15−16

@@ -46,7 +46,7 @@ func (w *Web) adminUsersView(r *http.Request, msg string) adminUsersView {
46 46 for _, acct := range accounts {
47 47 row := adminUserRow{Account: acct}
48 48 if w.Sessions != nil {
49 if list, err := w.Sessions.List(acct.ID); err == nil {
49 if list, err := w.Sessions.List(acct.Name); err == nil {
50 50 row.Sessions = len(list)
51 51 }
52 52 }
@@ -56,9 +56,9 @@ func (w *Web) adminUsersView(r *http.Request, msg string) adminUsersView {
56 56 }
57 57
58 58 func (w *Web) adminUserView(r *http.Request, acct *identity.Account, msg string) adminUserView {
59 v := adminUserView{Page: w.page(r, acct.Label()), Account: acct, Error: msg}
59 v := adminUserView{Page: w.page(r, acct.Name), Account: acct, Error: msg}
60 60 if w.Sessions != nil {
61 v.Sessions, _ = w.Sessions.List(acct.ID)
61 v.Sessions, _ = w.Sessions.List(acct.Name)
62 62 }
63 63 return v
64 64 }
@@ -69,7 +69,7 @@ func (w *Web) adminInviteView(r *http.Request, acct *identity.Account, inv *iden
69 69 link = base + link
70 70 }
71 71 return adminInviteView{
72 Page: w.page(r, "Invite "+acct.Label()), Account: acct,
72 Page: w.page(r, "Invite "+acct.Name), Account: acct,
73 73 Link: link, Expires: inv.Expires, BrowserLogin: w.enabled(),
74 74 }
75 75 }
@@ -81,7 +81,7 @@ func (w *Web) adminUserPost(rw http.ResponseWriter, r *http.Request) (*identity.
81 81 if !ok {
82 82 return nil, nil, false
83 83 }
84 acct, err := w.Ident.Find(r.PathValue("id"))
84 acct, err := w.Ident.Find(r.PathValue("name"))
85 85 if err != nil {
86 86 w.notFound(rw, r)
87 87 return nil, nil, false
@@ -119,8 +119,7 @@ func (w *Web) CreateAdminUser(rw http.ResponseWriter, r *http.Request) {
119 119 return
120 120 }
121 121 name := strings.TrimSpace(r.PostFormValue("name"))
122 display := strings.TrimSpace(r.PostFormValue("display"))
123 acct, inv, err := w.Ident.CreateWithInvite(name, display, w.accountID(r), 0)
122 acct, inv, err := w.Ident.CreateWithInvite(name, w.accountName(r), 0)
124 123 if err != nil {
125 124 w.render(rw, "admin_users", w.adminUsersView(r, err.Error()), http.StatusBadRequest)
126 125 return
@@ -133,7 +132,7 @@ func (w *Web) AdminUserPage(rw http.ResponseWriter, r *http.Request) {
133 132 if _, ok := w.requireInstanceAdmin(rw, r); !ok {
134 133 return
135 134 }
136 acct, err := w.Ident.Find(r.PathValue("id"))
135 acct, err := w.Ident.Find(r.PathValue("name"))
137 136 if err != nil {
138 137 w.notFound(rw, r)
139 138 return
@@ -147,11 +146,11 @@ func (w *Web) SetAdminUser(rw http.ResponseWriter, r *http.Request) {
147 146 return
148 147 }
149 148 admin := r.PostFormValue("admin") == "true"
150 if _, err := w.Ident.SetAdmin(acct.ID, admin, pr.account.ID); err != nil {
149 if _, err := w.Ident.SetAdmin(acct.Name, admin, pr.account.Name); err != nil {
151 150 w.render(rw, "admin_user", w.adminUserView(r, acct, err.Error()), http.StatusBadRequest)
152 151 return
153 152 }
154 http.Redirect(rw, r, "/admin/users/"+acct.ID, http.StatusSeeOther)
153 http.Redirect(rw, r, "/admin/users/"+acct.Name, http.StatusSeeOther)
155 154 }
156 155
157 156 func (w *Web) RetireAdminUser(rw http.ResponseWriter, r *http.Request) {
@@ -163,7 +162,7 @@ func (w *Web) RetireAdminUser(rw http.ResponseWriter, r *http.Request) {
163 162 w.render(rw, "admin_user", w.adminUserView(r, acct, "Type the account name exactly to confirm retirement."), http.StatusBadRequest)
164 163 return
165 164 }
166 if _, err := w.Ident.Retire(acct.ID, pr.account.ID); err != nil {
165 if _, err := w.Ident.Retire(acct.Name, pr.account.Name); err != nil {
167 166 w.render(rw, "admin_user", w.adminUserView(r, acct, err.Error()), http.StatusBadRequest)
168 167 return
169 168 }
@@ -175,7 +174,7 @@ func (w *Web) InviteAdminUser(rw http.ResponseWriter, r *http.Request) {
175 174 if !ok {
176 175 return
177 176 }
178 inv, err := w.Ident.Invite(acct.ID, pr.account.ID, 0)
177 inv, err := w.Ident.Invite(acct.Name, pr.account.Name, 0)
179 178 if err != nil {
180 179 w.render(rw, "admin_user", w.adminUserView(r, acct, err.Error()), http.StatusBadRequest)
181 180 return
@@ -193,11 +192,11 @@ func (w *Web) RevokeAdminUserSessions(rw http.ResponseWriter, r *http.Request) {
193 192 w.serverError(rw, r, "sessions are unavailable")
194 193 return
195 194 }
196 if _, err := w.Sessions.RevokeAccount(acct.ID); err != nil {
195 if _, err := w.Sessions.RevokeAccount(acct.Name); err != nil {
197 196 w.serverError(rw, r, "cannot revoke sessions: "+err.Error())
198 197 return
199 198 }
200 http.Redirect(rw, r, "/admin/users/"+acct.ID, http.StatusSeeOther)
199 http.Redirect(rw, r, "/admin/users/"+acct.Name, http.StatusSeeOther)
201 200 }
202 201
203 202 func (w *Web) RemoveAdminUserKey(rw http.ResponseWriter, r *http.Request) {
@@ -210,9 +209,9 @@ func (w *Web) RemoveAdminUserKey(rw http.ResponseWriter, r *http.Request) {
210 209 w.render(rw, "admin_user", w.adminUserView(r, acct, "Choose a key to remove."), http.StatusBadRequest)
211 210 return
212 211 }
213 if err := w.Ident.RemoveKey(acct.ID, fingerprint, pr.account.ID); err != nil {
212 if err := w.Ident.RemoveKey(acct.Name, fingerprint, pr.account.Name); err != nil {
214 213 w.render(rw, "admin_user", w.adminUserView(r, acct, err.Error()), http.StatusBadRequest)
215 214 return
216 215 }
217 http.Redirect(rw, r, "/admin/users/"+acct.ID, http.StatusSeeOther)
216 http.Redirect(rw, r, "/admin/users/"+acct.Name, http.StatusSeeOther)
218 217 }