1package config
 2
 3import (
 4	"log"
 5	"strings"
 6
 7	gm "github.com/charmbracelet/wish/git"
 8	"github.com/gliderlabs/ssh"
 9)
10
11func (cfg *Config) Push(repo string, pk ssh.PublicKey) {
12	err := cfg.Reload()
13	if err != nil {
14		log.Printf("error reloading after push: %s", err)
15	}
16	if cfg.Cfg.Callbacks != nil {
17		cfg.Cfg.Callbacks.Push(repo)
18	}
19}
20
21func (cfg *Config) Fetch(repo string, pk ssh.PublicKey) {
22	if cfg.Cfg.Callbacks != nil {
23		cfg.Cfg.Callbacks.Fetch(repo)
24	}
25}
26
27func (cfg *Config) AuthRepo(repo string, pk ssh.PublicKey) gm.AccessLevel {
28	return cfg.accessForKey(repo, pk)
29}
30
31func (cfg *Config) PasswordHandler(ctx ssh.Context, password string) bool {
32	return (cfg.AnonAccess != "no-access") && cfg.AllowKeyless
33}
34
35func (cfg *Config) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) bool {
36	return cfg.accessForKey("", pk) != gm.NoAccess
37}
38
39func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
40	private := cfg.isPrivate(repo)
41	if repo == "config" {
42		private = true
43	}
44	for _, u := range cfg.Users {
45		for _, k := range u.PublicKeys {
46			apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(strings.TrimSpace(k)))
47			if err != nil {
48				log.Printf("error: malformed authorized key: '%s'", k)
49				return gm.NoAccess
50			}
51			if ssh.KeysEqual(pk, apk) {
52				if u.Admin {
53					return gm.AdminAccess
54				}
55				for _, r := range u.CollabRepos {
56					if repo == r {
57						return gm.ReadWriteAccess
58					}
59				}
60				if !private {
61					return gm.ReadOnlyAccess
62				}
63			}
64		}
65	}
66	if private && (cfg.AnonAccess != "read-write") {
67		return gm.NoAccess
68	}
69	switch cfg.AnonAccess {
70	case "no-access":
71		return gm.NoAccess
72	case "read-only":
73		return gm.ReadOnlyAccess
74	case "read-write":
75		return gm.ReadWriteAccess
76	default:
77		return gm.NoAccess
78	}
79}