main backend.go
Eric Bower  ·  2026-02-25
 1package patchbin
 2
 3import (
 4	"crypto/sha256"
 5	"encoding/base64"
 6	"encoding/hex"
 7	"fmt"
 8	"log/slog"
 9
10	"github.com/jmoiron/sqlx"
11	"golang.org/x/crypto/ssh"
12)
13
14type Backend struct {
15	Logger  *slog.Logger
16	DB      *sqlx.DB
17	Cfg     *GitCfg
18	Limiter *RateLimiter
19}
20
21// Pubkey returns the standardized public key string for SSH.
22func (be *Backend) Pubkey(pk ssh.PublicKey) string {
23	return be.KeyForKeyText(pk)
24}
25
26func (be *Backend) KeyForFingerprint(pk ssh.PublicKey) string {
27	return ssh.FingerprintSHA256(pk)
28}
29
30func (be *Backend) PubkeyToPublicKey(pubkey string) (ssh.PublicKey, error) {
31	kk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubkey))
32	return kk, err
33}
34
35func (be *Backend) KeyForKeyText(pk ssh.PublicKey) string {
36	kb := base64.StdEncoding.EncodeToString(pk.Marshal())
37	return fmt.Sprintf("%s %s", pk.Type(), kb)
38}
39
40func (be *Backend) KeysEqual(pka, pkb string) bool {
41	return pka == pkb
42}
43
44func (be *Backend) PublicKeysEqual(a, b ssh.PublicKey) bool {
45	return string(a.Marshal()) == string(b.Marshal())
46}
47
48func (be *Backend) IsAdmin(pk ssh.PublicKey) bool {
49	for _, apk := range be.Cfg.Admins {
50		if be.PublicKeysEqual(pk, apk) {
51			return true
52		}
53	}
54	return false
55}
56
57// ComputeUserName derives a username from an SSH public key.
58// Uses the first 8 characters of the SHA256 hash of the key.
59func (be *Backend) ComputeUserName(pubkey string) string {
60	hash := sha256.Sum256([]byte(pubkey))
61	return hex.EncodeToString(hash[:4])
62}