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/templates/admin_users.html +11−16
| @@ -19,9 +19,6 @@ | |||
| 19 | 19 | <label>Account name | |
| 20 | 20 | <input type="text" name="name" required maxlength="63" autocomplete="off" placeholder="lowercase-name"> | |
| 21 | 21 | </label> | |
| 22 | <label>Display name | ||
| 23 | <input type="text" name="display" maxlength="80" autocomplete="off" placeholder="Optional label"> | ||
| 24 | </label> | ||
| 25 | 22 | <div class="form-actions"><button type="submit">{{icon "user"}}Create invite</button></div> | |
| 26 | 23 | </form> | |
| 27 | 24 | </div> | |
| @@ -33,14 +30,13 @@ | |||
| 33 | 30 | {{range .Users}} | |
| 34 | 31 | <tr> | |
| 35 | 32 | <td> | |
| 36 | <a href="/admin/users/{{.Account.ID}}">{{.Account.Label}}</a> | ||
| 37 | {{if ne .Account.Name .Account.Label}}<span class="muted">@{{.Account.Name}}</span>{{end}} | ||
| 33 | <a href="/admin/users/{{.Account.Name}}">{{.Account.Name}}</a> | ||
| 38 | 34 | </td> | |
| 39 | 35 | <td><span class="state {{.Account.Status}}">{{.Account.Status}}</span></td> | |
| 40 | 36 | <td>{{if .Account.Admin}}<span class="label">instance admin</span>{{else}}<span class="muted">account</span>{{end}}</td> | |
| 41 | 37 | <td>{{len .Account.Keys}}</td> | |
| 42 | 38 | <td>{{.Sessions}}</td> | |
| 43 | <td><a href="/admin/users/{{.Account.ID}}">Manage</a></td> | ||
| 39 | <td><a href="/admin/users/{{.Account.Name}}">Manage</a></td> | ||
| 44 | 40 | </tr> | |
| 45 | 41 | {{end}} | |
| 46 | 42 | </tbody> | |
| @@ -53,10 +49,9 @@ | |||
| 53 | 49 | {{template "header" .}} | |
| 54 | 50 | <div class="page-head"> | |
| 55 | 51 | <div class="page-head-main"> | |
| 56 | <h1>{{.Account.Label}}</h1> | ||
| 52 | <h1>{{.Account.Name}}</h1> | ||
| 57 | 53 | <p class="page-sub"> | |
| 58 | <code>@{{.Account.Name}}</code> | ||
| 59 | · <span class="state {{.Account.Status}}">{{.Account.Status}}</span> | ||
| 54 | <span class="state {{.Account.Status}}">{{.Account.Status}}</span> | ||
| 60 | 55 | {{if .Account.Admin}}· instance admin{{end}} | |
| 61 | 56 | · created {{since .Account.Created.Unix}} | |
| 62 | 57 | </p> | |
| @@ -71,7 +66,7 @@ | |||
| 71 | 66 | <div class="card form-card"> | |
| 72 | 67 | <h2>Access and enrollment</h2> | |
| 73 | 68 | <div class="form-actions"> | |
| 74 | <form class="inline" method="post" action="/admin/users/{{.Account.ID}}/admin"> | ||
| 69 | <form class="inline" method="post" action="/admin/users/{{.Account.Name}}/admin"> | ||
| 75 | 70 | <input type="hidden" name="csrf" value="{{.CSRF}}"> | |
| 76 | 71 | {{if .Account.Admin}} | |
| 77 | 72 | <input type="hidden" name="admin" value="false"> | |
| @@ -81,12 +76,12 @@ | |||
| 81 | 76 | <button type="submit" class="secondary">{{icon "user"}}Grant instance admin</button> | |
| 82 | 77 | {{end}} | |
| 83 | 78 | </form> | |
| 84 | <form class="inline" method="post" action="/admin/users/{{.Account.ID}}/invite"> | ||
| 79 | <form class="inline" method="post" action="/admin/users/{{.Account.Name}}/invite"> | ||
| 85 | 80 | <input type="hidden" name="csrf" value="{{.CSRF}}"> | |
| 86 | 81 | <button type="submit" class="secondary">{{icon "external-link"}}New enrollment link</button> | |
| 87 | 82 | </form> | |
| 88 | 83 | {{if .Sessions}} | |
| 89 | <form class="inline" method="post" action="/admin/users/{{.Account.ID}}/sessions/revoke"> | ||
| 84 | <form class="inline" method="post" action="/admin/users/{{.Account.Name}}/sessions/revoke"> | ||
| 90 | 85 | <input type="hidden" name="csrf" value="{{.CSRF}}"> | |
| 91 | 86 | <button type="submit" class="warn">{{icon "log-out"}}Revoke all sessions</button> | |
| 92 | 87 | </form> | |
| @@ -106,7 +101,7 @@ | |||
| 106 | 101 | <td>{{.Type}}</td> | |
| 107 | 102 | <td class="muted">{{.Comment}}</td> | |
| 108 | 103 | <td> | |
| 109 | <form class="inline" method="post" action="/admin/users/{{$.Account.ID}}/keys/remove"> | ||
| 104 | <form class="inline" method="post" action="/admin/users/{{$.Account.Name}}/keys/remove"> | ||
| 110 | 105 | <input type="hidden" name="csrf" value="{{$.CSRF}}"> | |
| 111 | 106 | <input type="hidden" name="fingerprint" value="{{.Fingerprint}}"> | |
| 112 | 107 | <button type="submit" class="danger">Remove</button> | |
| @@ -144,7 +139,7 @@ | |||
| 144 | 139 | ||
| 145 | 140 | <h2>Danger zone</h2> | |
| 146 | 141 | <div class="card danger-zone"> | |
| 147 | <form method="post" action="/admin/users/{{.Account.ID}}/retire" class="form-block"> | ||
| 142 | <form method="post" action="/admin/users/{{.Account.Name}}/retire" class="form-block"> | ||
| 148 | 143 | <input type="hidden" name="csrf" value="{{.CSRF}}"> | |
| 149 | 144 | <h3>Retire account</h3> | |
| 150 | 145 | <p class="muted">Disables the account, ends its sessions, and closes any enrollment links. The name is never reissued.</p> | |
| @@ -162,7 +157,7 @@ | |||
| 162 | 157 | <div class="page-head"> | |
| 163 | 158 | <div class="page-head-main"> | |
| 164 | 159 | <h1>Enrollment link</h1> | |
| 165 | <p class="page-sub">For <strong>{{.Account.Label}}</strong> <code>@{{.Account.Name}}</code> · expires {{.Expires.UTC.Format "2006-01-02 15:04 UTC"}}</p> | ||
| 160 | <p class="page-sub">For <strong>{{.Account.Name}}</strong> · expires {{.Expires.UTC.Format "2006-01-02 15:04 UTC"}}</p> | ||
| 166 | 161 | </div> | |
| 167 | 162 | </div> | |
| 168 | 163 | ||
| @@ -177,7 +172,7 @@ | |||
| 177 | 172 | </div> | |
| 178 | 173 | ||
| 179 | 174 | <div class="form-actions"> | |
| 180 | <a class="button secondary" href="/admin/users/{{.Account.ID}}">{{icon "user"}}Back to account</a> | ||
| 175 | <a class="button secondary" href="/admin/users/{{.Account.Name}}">{{icon "user"}}Back to account</a> | ||
| 181 | 176 | <a class="button" href="/admin/users">{{icon "users"}}All users</a> | |
| 182 | 177 | </div> | |
| 183 | 178 | {{template "footer" .}} | |