diff options
| author | Lena <lena@omega> | 2026-08-01 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-08-01 00:00:00 +0000 |
| commit | bb6bc2387d58c737dbf92e73f8544bf39319dbd8 (patch) | |
| tree | 6d5eaf5dac213074cd832da50f64260fce728fed /templates/repo-settings.html | |
| download | git-forge-master.tar.gz | |
A small self-hosted git forge: HTTP push and pull, cgit browsing,
local and OIDC accounts, TOTP, scoped push tokens, per-repo
permissions, issues, a wiki, and outbound mail.
It does not reimplement git. git-http-backend and cgit run as CGI
behind its own listener, which authorises every request before
exec'ing either. One binary, one data directory, one listener: no
database, no JavaScript, and state is JSON in a git repo with a
working tree.
Diffstat (limited to 'templates/repo-settings.html')
| -rw-r--r-- | templates/repo-settings.html | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/templates/repo-settings.html b/templates/repo-settings.html new file mode 100644 index 0000000..d90f744 --- /dev/null +++ b/templates/repo-settings.html @@ -0,0 +1,122 @@ +{{define "title"}}{{.Data.Path}} settings - {{.Site}}{{end}} +{{define "main"}} +{{$repo := .Data.Repo}} +<h2>Settings</h2> + +{{if not .Data.Enrolled}} +<div class="error"> +This account has no authenticator, so it cannot change who may read or write +this repository, and cannot change grants. +<a href="/settings/totp">Enrol one</a> and come back. +</div> +{{end}} + +<form method="post" action="/{{.Data.Path}}/settings"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p> +<label for="desc">Description, shown in the header and in the index</label> +<input id="desc" name="desc" value="{{$repo.Desc}}"> +</p> +{{template "knobs" $repo}} +<p> +<label for="labels">Labels an issue may carry, one per line</label> +<textarea id="labels" name="labels" rows="5">{{.Data.Labels}}</textarea> +</p> +<p> +<label for="settings-code">Your authenticator code</label> +<input id="settings-code" name="code" inputmode="numeric" autocomplete="one-time-code"> +<span class="dim"> +Needed only to move one of the three above: who may read or write outlives this +session, the way a grant does. A description or a label does not. +</span> +</p> +<p><button type="submit">Save</button></p> +</form> + +<h3>Grants</h3> +<p class="dim"> +read clones and browses a private repository. write adds pushing to it. admin +adds this page. A global admin holds admin everywhere without appearing here. +A push token can be minted for any repository an account can reach, and carries +the access that account already has there and nothing more. +</p> +<p class="dim"> +Access handed out here outlives the session that hands it out, so changing a +grant asks for your own authenticator code as well. +</p> +<table summary="grants" class="list nowrap"> +<tr class="nohover"><th class="left">Account</th><th class="left">Level</th><th class="left"></th></tr> +{{range $account, $level := $repo.Grants}} +<tr> +<td>{{template "who" $account}}</td> +<td>{{$level}}</td> +<td> +{{if $.Data.Enrolled}} +<form method="post" action="/{{$.Data.Path}}/settings/grant"> +<input type="hidden" name="csrf" value="{{$.CSRF}}"> +<input type="hidden" name="account" value="{{$account}}"> +<input name="code" size="6" inputmode="numeric" autocomplete="one-time-code" aria-label="Your authenticator code" placeholder="code" required> +<button type="submit">revoke</button> +</form> +{{end}} +</td> +</tr> +{{else}} +<tr><td colspan="3" class="dim">Nobody, so only global admins can reach it.</td></tr> +{{end}} +</table> + +{{if .Data.Enrolled}} +<form method="post" action="/{{.Data.Path}}/settings/grant"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p> +<label for="account">Account</label> +<input id="account" name="account" autocapitalize="none" required> +</p> +<fieldset> +<legend>Level</legend> +<label class="choice" for="g-read"> +<input id="g-read" type="radio" name="level" value="read" checked> +<strong>read</strong> <span class="dim">clone and browse it</span> +</label> +<label class="choice" for="g-write"> +<input id="g-write" type="radio" name="level" value="write"> +<strong>write</strong> <span class="dim">and push to it</span> +</label> +<label class="choice" for="g-admin"> +<input id="g-admin" type="radio" name="level" value="admin"> +<strong>admin</strong> <span class="dim">and change this page</span> +</label> +</fieldset> +<p> +<label for="grant-code">Your authenticator code</label> +<input id="grant-code" name="code" inputmode="numeric" autocomplete="one-time-code" required> +</p> +<p><button type="submit">Grant</button></p> +</form> +{{end}} + +{{if .Data.Delete}} +<div class="danger"> +<h3>Delete this repository</h3> +<p> +This removes the repository, its issues, and its wiki together. There is no +undo and the history goes with it. Type <code>{{.Data.Path}}</code> to confirm, +and your own authenticator code, so that a session somebody else is sitting in +front of cannot do it. +</p> +<form method="post" action="/{{.Data.Path}}/settings/delete"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p> +<label for="confirm">Repository path</label> +<input id="confirm" name="confirm" autocapitalize="none" required> +</p> +<p> +<label for="code">Your authenticator code</label> +<input id="code" name="code" inputmode="numeric" autocomplete="one-time-code" required> +</p> +<p><button type="submit">Delete it</button></p> +</form> +</div> +{{end}} +{{end}} |