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.
Add instance-wide roles and refine access UI
5b814e9958090cfd1fa826efb2d375bf613547c1 · Keenan Nemetz · 14d ago · parent 9579c1f9
Add instance-wide roles and refine access UI Instance roles now live on accounts, apply to public repositories, and the Admin role is the unified instance-admin permission with access to every repository. Repository ACLs can raise an instance role but not lower it. Adds role assignment to the users UI and CLI, open-registration role config, a reusable role picker, and separates adding a repository account from saving access rules.
server/web/admin_users.go +14−4
| @@ -10,6 +10,7 @@ import ( | |||
| 10 | 10 | "strings" | |
| 11 | 11 | "time" | |
| 12 | 12 | ||
| 13 | "github.com/rodent-software/vole/forge/access" | ||
| 13 | 14 | "github.com/rodent-software/vole/forge/identity" | |
| 14 | 15 | "github.com/rodent-software/vole/forge/session" | |
| 15 | 16 | ) | |
| @@ -119,7 +120,12 @@ func (w *Web) CreateAdminUser(rw http.ResponseWriter, r *http.Request) { | |||
| 119 | 120 | return | |
| 120 | 121 | } | |
| 121 | 122 | name := strings.TrimSpace(r.PostFormValue("name")) | |
| 122 | acct, inv, err := w.Ident.CreateWithInvite(name, w.accountName(r), 0) | ||
| 123 | role, err := access.ParseRole(r.PostFormValue("role")) | ||
| 124 | if err != nil { | ||
| 125 | w.render(rw, "admin_users", w.adminUsersView(r, err.Error()), http.StatusBadRequest) | ||
| 126 | return | ||
| 127 | } | ||
| 128 | acct, inv, err := w.Ident.CreateWithInviteRole(name, role, w.accountName(r), 0) | ||
| 123 | 129 | if err != nil { | |
| 124 | 130 | w.render(rw, "admin_users", w.adminUsersView(r, err.Error()), http.StatusBadRequest) | |
| 125 | 131 | return | |
| @@ -140,13 +146,17 @@ func (w *Web) AdminUserPage(rw http.ResponseWriter, r *http.Request) { | |||
| 140 | 146 | w.render(rw, "admin_user", w.adminUserView(r, acct, ""), 0) | |
| 141 | 147 | } | |
| 142 | 148 | ||
| 143 | func (w *Web) SetAdminUser(rw http.ResponseWriter, r *http.Request) { | ||
| 149 | func (w *Web) SetAdminUserRole(rw http.ResponseWriter, r *http.Request) { | ||
| 144 | 150 | acct, pr, ok := w.adminUserPost(rw, r) | |
| 145 | 151 | if !ok { | |
| 146 | 152 | return | |
| 147 | 153 | } | |
| 148 | admin := r.PostFormValue("admin") == "true" | ||
| 149 | if _, err := w.Ident.SetAdmin(acct.Name, admin, pr.account.Name); err != nil { | ||
| 154 | role, err := access.ParseRole(r.PostFormValue("role")) | ||
| 155 | if err != nil { | ||
| 156 | w.render(rw, "admin_user", w.adminUserView(r, acct, err.Error()), http.StatusBadRequest) | ||
| 157 | return | ||
| 158 | } | ||
| 159 | if _, err := w.Ident.SetInstanceRole(acct.Name, role, pr.account.Name); err != nil { | ||
| 150 | 160 | w.render(rw, "admin_user", w.adminUserView(r, acct, err.Error()), http.StatusBadRequest) | |
| 151 | 161 | return | |
| 152 | 162 | } | |