repos / git-pr

a self-hosted git collaboration server
git clone https://github.com/picosh/git-pr.git

jolheiser  ·  2025-04-17

ssh.go

 1package git
 2
 3import (
 4	"fmt"
 5	"path/filepath"
 6
 7	"github.com/charmbracelet/ssh"
 8	"github.com/charmbracelet/wish"
 9)
10
11func authHandler(pr *PrCmd) func(ctx ssh.Context, key ssh.PublicKey) bool {
12	return func(ctx ssh.Context, key ssh.PublicKey) bool {
13		pubkey := pr.Backend.Pubkey(key)
14		userName := ctx.User()
15		err := pr.IsBanned(pubkey, userName)
16		if err != nil {
17			pr.Backend.Logger.Info(
18				"user denied access",
19				"err", err,
20				"username", userName,
21				"pubkey", pubkey,
22			)
23			return false
24		}
25		return true
26	}
27}
28
29func GitSshServer(cfg *GitCfg) *ssh.Server {
30	dbpath := filepath.Join(cfg.DataDir, "pr.db?_fk=on")
31	dbh, err := SqliteOpen("file:"+dbpath, cfg.Logger)
32	if err != nil {
33		panic(fmt.Sprintf("cannot find database file, check folder and perms: %s: %s", dbpath, err))
34	}
35
36	be := &Backend{
37		DB:     dbh,
38		Logger: cfg.Logger,
39		Cfg:    cfg,
40	}
41	prCmd := &PrCmd{
42		Backend: be,
43	}
44
45	s, err := wish.NewServer(
46		wish.WithAddress(
47			fmt.Sprintf("%s:%s", cfg.Host, cfg.SshPort),
48		),
49		wish.WithHostKeyPath(
50			filepath.Join(cfg.DataDir, "term_info_ed25519"),
51		),
52		wish.WithPublicKeyAuth(authHandler(prCmd)),
53		wish.WithMiddleware(
54			GitPatchRequestMiddleware(be, prCmd),
55		),
56	)
57	if err != nil {
58		cfg.Logger.Error("could not create server", "err", err)
59		return nil
60	}
61	return s
62}