5ff41c0e6f71e5aaac3a3edbe7373baebb226ad9

Author
Toby Padilla <toby@charm.sh>
Committer
Toby Padilla <toby@charm.sh>
Date

Message

Allow repos to be private / admin only

Diff

This diff is truncated to protect this page.

  1diff --git a/config/config.go b/config/config.go
  2index 8eafe28106c904b2036b2696eb470c97b19c7ea6..168ba4c56d4187238a0d05cc45b1b9229f548fc2 100644
  3--- a/config/config.go
  4+++ b/config/config.go
  5@@ -31,9 +31,10 @@ type User struct {
  6 }
  7 
  8 type Repo struct {
  9-	Name string `yaml:"name"`
 10-	Repo string `yaml:"repo"`
 11-	Note string `yaml:"note"`
 12+	Name    string `yaml:"name"`
 13+	Repo    string `yaml:"repo"`
 14+	Note    string `yaml:"note"`
 15+	Private bool   `yaml:"private"`
 16 }
 17 
 18 func NewConfig(host string, port int, pk string, rs *git.RepoSource) (*Config, error) {
 19@@ -155,3 +156,12 @@ func (cfg *Config) createDefaultConfigRepo(yaml string) error {
 20 	}
 21 	return cfg.reload()
 22 }
 23+
 24+func (cfg *Config) isPrivate(repo string) bool {
 25+	for _, r := range cfg.Repos {
 26+		if r.Repo == repo {
 27+			return r.Private
 28+		}
 29+	}
 30+	return false
 31+}
 32diff --git a/config/defaults.go b/config/defaults.go
 33index 2617844193f8a15e4d6a2e2dfac465db7f032188..0eaceb131042bda44378cdacd11bdc670361f4a6 100644
 34--- a/config/defaults.go
 35+++ b/config/defaults.go
 36@@ -1,6 +1,6 @@
 37 package config
 38 
 39diff --git a/config/git.go b/config/git.go
 40index 0e559508fd2dd74e3ac9857e78d17790044141c0..bd7372a8b0eee0c657f1e6a022f44c9e581f5c61 100644
 41--- a/config/git.go
 42+++ b/config/git.go
 43@@ -35,6 +35,10 @@ func (cfg *Config) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) bool {
 44 }
 45 
 46 func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
 47+	private := cfg.isPrivate(repo)
 48+	if repo == "config" {
 49+		private = true
 50+	}
 51 	for _, u := range cfg.Users {
 52 		apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(u.PublicKey))
 53 		if err != nil {
 54@@ -50,12 +54,12 @@ func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
 55 					return gm.ReadWriteAccess
 56 				}
 57 			}
 58-			if repo != "config" {
 59+			if !private {
 60 				return gm.ReadOnlyAccess
 61 			}
 62 		}
 63 	}
 64-	if repo == "config" && (cfg.AnonAccess != "read-write") {
 65+	if private && (cfg.AnonAccess != "read-write") {
 66 		return gm.NoAccess
 67 	}
 68 	switch cfg.AnonAccess {
 69diff --git a/tui/bubble.go b/tui/bubble.go
 70index 6ae9047c1d64cf6a25b4914fdf9e08226cee68aa..11c238b047bc237b512a73722ab8b814b29c8934 100644
 71--- a/tui/bubble.go
 72+++ b/tui/bubble.go
 73@@ -11,6 +11,7 @@ import (
 74 	"github.com/charmbracelet/soft/tui/bubbles/repo"
 75 	"github.com/charmbracelet/soft/tui/bubbles/selection"
 76 	"github.com/charmbracelet/soft/tui/style"
 77+	"github.com/gliderlabs/ssh"
 78 )
 79 
 80 type sessionState int
 81@@ -27,6 +28,7 @@ type SessionConfig struct {
 82 	Width       int
 83 	Height      int
 84 	InitialRepo string
 85+	Session     ssh.Session
 86 }
 87 
 88 type MenuEntry struct {
 89@@ -49,6 +51,7 @@ type Bubble struct {
 90 	boxes       []tea.Model
 91 	activeBox   int
 92 	repoSelect  *selection.Bubble
 93+	session     ssh.Session
 94 }
 95 
 96 func NewBubble(cfg *config.Config, sCfg *SessionConfig) *Bubble {
 97@@ -60,6 +63,7 @@ func NewBubble(cfg *config.Config, sCfg *SessionConfig) *Bubble {
 98 		repoMenu:    make([]MenuEntry, 0),
 99 		boxes:       make([]tea.Model, 2),
100 		initialRepo: sCfg.InitialRepo,
101+		session:     sCfg.Session,
102 	}
103 	b.state = startState
104 	return b
105diff --git a/tui/commands.go b/tui/commands.go
106index 083a2f4da354ec2ad23f75cf29d42d9545c89d80..072d83b2e2f820f7cd2680766c54f5b274df37e1 100644
107--- a/tui/commands.go
108+++ b/tui/commands.go
109@@ -8,6 +8,7 @@ import (
110 	"github.com/charmbracelet/soft/config"
111 	br "github.com/charmbracelet/soft/tui/bubbles/repo"
112 	"github.com/charmbracelet/soft/tui/bubbles/selection"
113+	gm "github.com/charmbracelet/wish/git"
114 	"github.com/muesli/termenv"
115 )
116 
117@@ -61,18 +62,20 @@ func (b *Bubble) setupCmd() tea.Msg {
118 
119 func (b *Bubble) menuEntriesFromSource() ([]MenuEntry, error) {
120 	mes := make([]MenuEntry, 0)
121-	for _, r := range b.config.Repos {
122-		me, err := b.newMenuEntry(r.Name, r.Repo)
123-		if err != nil {
124-			return nil, err
125-		}
126-		mes = append(mes, me)
127-	}
128 	rs := b.config.Source.AllRepos()
129 OUTER:
130 	for _, r := range rs {
131-		for _, me := range mes {
132-			if r.Name == me.Repo {
133+		acc := b.config.AuthRepo(r.Name, b.session.PublicKey())
134+		if acc == gm.NoAccess && r.Name != "config" {
135+			continue
136+		}
137+		for _, cr := range b.config.Repos {
138+			if r.Name == cr.Repo {
139+				me, err := b.newMenuEntry(cr.Name, cr.Repo)
140+				if err != nil {
141+					return nil, err
142+				}
143+				mes = append(mes, me)
144 				continue OUTER
145 			}
146 		}
147@@ -87,6 +90,9 @@ OUTER:
148 
149 func (b *Bubble) newMenuEntry(name string, repo string) (MenuEntry, error) {
150 	var tmplConfig *config.Config
151+	if repo == "config" {
152+		tmplConfig = b.config
153+	}
154 	me := MenuEntry{Name: name, Repo: repo}
155 	width := b.width
156 	boxLeftWidth := b.styles.Menu.GetWidth() + b.styles.Menu.GetHorizontalFrameSize()
157@@ -95,9 +101,6 @@ func (b *Bubble) newMenuEntry(name string, repo string) (MenuEntry, error) {
158 		lipgloss.Height(b.footerView()) +
159 		b.styles.RepoBody.GetVerticalFrameSize() +
160 		b.styles.App.GetVerticalMargins()
161-	if repo == "config" {
162-		tmplConfig = b.config
163-	}
164 	rb := br.NewBubble(
165 		b.config.Source,
166 		me.Repo,
167diff --git a/tui/session.go b/tui/session.go
168index c91e5a31dc0152e125b24061d6ae007d30561575..540ced5152b5a4c70ae03944988d32d7db76fc23 100644
169--- a/tui/session.go
170+++ b/tui/session.go
171@@ -11,7 +11,7 @@ import (
172 func SessionHandler(cfg *config.Config) func(ssh.Session) (tea.Model, []tea.ProgramOption) {
173 	return func(s ssh.Session) (tea.Model, []tea.ProgramOption) {
174 		cmd := s.Command()
175-		scfg := &SessionConfig{}
176+		scfg := &SessionConfig{Session: s}
177 		switch len(cmd) {
178 		case 0:
179 			scfg.InitialRepo = ""