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/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.

Allow opt-in open registration

f920a9f12c4ff12e4f47497a084f0201d8914181 · Keenan Nemetz · 16d ago · parent 6c84d387

Allow opt-in open registration

Add open_registration, off by default and effective only with an HTTPS public_url. /register creates an account and its first passkey without an administrator; the account row is written only after the WebAuthn ceremony succeeds, so an abandoned registration reserves no name.

New accounts start with no repository-specific ACL entries. Add self-service SSH key management on the Account page so a registered contributor can add the key needed to push to their contributor namespace.

Cover registration enablement, name validation, deferred account creation, and self-service key add/remove in tests, and document the policy.

server/web/templates.go +49

@@ -674,8 +674,29 @@ release a description; the tarball below works either way.</p>
674 674 <button type="submit">Use a passkey</button>
675 675 <p class="error" data-auth-error></p>
676 676 </form>
677 {{if .Registration}}
678 <p class="muted">No account yet? <a href="/register">Create one</a>.</p>
679 {{else}}
677 680 <p class="muted">No account yet? Ask an administrator for a one-time enrollment link.</p>
678 681 {{end}}
682 {{end}}
683 </div>
684 {{template "footer" .}}
685 {{end}}
686
687 {{define "register"}}
688 {{template "header" .}}
689 <div class="auth card">
690 <h1>Create an account</h1>
691 <p class="muted">Pick a name and register a passkey. You can add an SSH key after signing in.</p>
692 <form data-auth="register">
693 <label>Account name
694 <input type="text" name="username" pattern="[a-z0-9][a-z0-9_-]{1,31}" maxlength="32" autocomplete="username webauthn" required autofocus>
695 </label>
696 <button type="submit">Create account and passkey</button>
697 <p class="error" data-auth-error></p>
698 </form>
699 <p class="muted">Names are 2–32 characters: lowercase letters, digits, <code>-</code> and <code>_</code>.</p>
679 700 </div>
680 701 {{template "footer" .}}
681 702 {{end}}
@@ -709,6 +730,34 @@ release a description; the tarball below works either way.</p>
709 730 <h1>Account</h1>
710 731 <p><strong>{{.Account.Name}}</strong> <span class="muted">{{.Account.ID}}</span></p>
711 732
733 <h2>SSH keys</h2>
734 {{if .Account.Keys}}
735 <table>
736 <tr><th>Fingerprint</th><th>Type</th><th>Comment</th><th></th></tr>
737 {{range .Account.Keys}}
738 <tr>
739 <td class="sha">{{.Fingerprint}}</td>
740 <td class="muted">{{.Type}}</td>
741 <td class="muted">{{.Comment}}</td>
742 <td>
743 <form method="post" action="/account/keys/remove">
744 <input type="hidden" name="csrf" value="{{$.CSRF}}">
745 <input type="hidden" name="fingerprint" value="{{.Fingerprint}}">
746 <button class="link" type="submit">remove</button>
747 </form>
748 </td>
749 </tr>
750 {{end}}
751 </table>
752 {{else}}
753 <p class="muted">No SSH keys yet.</p>
754 {{end}}
755 <form method="post" action="/account/keys" class="card">
756 <input type="hidden" name="csrf" value="{{.CSRF}}">
757 <label>Public key <textarea name="key" rows="3" placeholder="ssh-ed25519 AAAA... you@example.com" required></textarea></label>
758 <button type="submit">Add SSH key</button>
759 </form>
760
712 761 <h2>Passkeys</h2>
713 762 {{if .Credentials}}
714 763 <table>