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.
Budget only the untrusted write role
e5542ac6b64fa3ebaf62af4831e55996dba45e7e · Keenan Nemetz · 12d ago · parent 9e8cc155
Budget only the untrusted write role Maintainers and admins are trusted roles: they can already change the rules, push shared branches and run the instance, so a write budget would slow their work without bounding anybody who could not do worse. The budget now applies only below maintain, which is the contribute role and the read-only accounts that cannot write at all. The setting is named for what it does: contributor_writes_per_hour. The role is the effective one on the repository, so an instance-wide maintainer on a public repository is exempt for the same reason a repository maintainer is.
server/web/write_context.go +16−4
| @@ -61,15 +61,27 @@ func (w *Web) beginWrite(rw http.ResponseWriter, r *http.Request, maxBody int64) | |||
| 61 | 61 | w.serverError(rw, r, "cannot read the access rules: "+err.Error()) | |
| 62 | 62 | return nil, false | |
| 63 | 63 | } | |
| 64 | // The account is what a write is attributed to, and a repository's pages parse | ||
| 65 | // every issue and comment anybody wrote: a script posting in a loop is the case | ||
| 66 | // this bounds, not a person. | ||
| 67 | if !w.limitForm(rw, r, w.limits.write, "write:"+pr.account.Name) { | ||
| 64 | // Only the untrusted role is budgeted. A repository's pages parse every issue | ||
| 65 | // and comment anybody wrote, so a contributor posting in a loop is the case this | ||
| 66 | // bounds; a maintainer or admin can already change these rules, push shared | ||
| 67 | // branches and run the instance, and slowing their work would bound nobody who | ||
| 68 | // could not do worse. | ||
| 69 | if writeBudgeted(acl.RoleFor(pr.account.Name)) && | ||
| 70 | !w.limitForm(rw, r, w.limits.write, "write:"+pr.account.Name) { | ||
| 68 | 71 | return nil, false | |
| 69 | 72 | } | |
| 70 | 73 | return &writeContext{Repo: m, ACL: acl, Name: pr.account.Name}, true | |
| 71 | 74 | } | |
| 72 | 75 | ||
| 76 | // writeBudgeted reports whether this account's browser writes are counted against | ||
| 77 | // the contributor budget. Maintainers and admins are trusted roles: the instance's | ||
| 78 | // threat model treats them as able to write metadata and approve changes already, | ||
| 79 | // so a write budget would only get in their way. The contribute role is the | ||
| 80 | // untrusted one, and read-only accounts below it cannot write at all. | ||
| 81 | func writeBudgeted(role access.Role) bool { | ||
| 82 | return !role.AtLeast(access.Maintain) | ||
| 83 | } | ||
| 84 | |||
| 73 | 85 | // beginPost resolves a write that is scoped to the account rather than to a | |
| 74 | 86 | // repository: the key and passkey forms on the account page. | |
| 75 | 87 | func (w *Web) beginPost(rw http.ResponseWriter, r *http.Request, maxBody int64) (*principal, bool) { | |