git.go

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