auth.go

 1package config
 2
 3import (
 4	"log"
 5
 6	gm "github.com/charmbracelet/wish/git"
 7	"github.com/gliderlabs/ssh"
 8)
 9
10func (cfg *Config) AuthRepo(repo string, pk ssh.PublicKey) gm.AccessLevel {
11	return cfg.accessForKey(repo, pk)
12}
13
14func (cfg *Config) PasswordHandler(ctx ssh.Context, password string) bool {
15	return (cfg.AnonAccess != "no-access") && cfg.AllowNoKeys
16}
17
18func (cfg *Config) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) bool {
19	if cfg.accessForKey("", pk) == gm.NoAccess {
20		return false
21	}
22	return true
23}
24
25func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
26	for _, u := range cfg.Users {
27		apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(u.PublicKey))
28		if err != nil {
29			log.Printf("error: malformed authorized key: '%s'", u.PublicKey)
30			return gm.NoAccess
31		}
32		if ssh.KeysEqual(pk, apk) {
33			if u.Admin {
34				return gm.AdminAccess
35			}
36			for _, r := range u.CollabRepos {
37				if repo == r {
38					return gm.ReadWriteAccess
39				}
40			}
41			if repo != "config" {
42				return gm.ReadOnlyAccess
43			}
44		}
45	}
46	if repo == "config" && (cfg.AnonAccess != "read-write") {
47		return gm.NoAccess
48	}
49	switch cfg.AnonAccess {
50	case "no-access":
51		return gm.NoAccess
52	case "read-only":
53		return gm.ReadOnlyAccess
54	case "read-write":
55		return gm.ReadWriteAccess
56	default:
57		return gm.NoAccess
58	}
59}