3 files changed,
41 insertions(+),
56 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-01-21 02:16:43 +0200
Authored at:
2026-01-21 01:45:09 +0200
Change ID:
kmotoklossmmuynpvomzvwzrtlqqmzqv
Parent:
1ea9b7f
M
internal/handlers/git.go
路路路 2 2 3 3 import ( 4 4 "compress/gzip" 5 + "fmt" 5 6 "io" 6 7 "log/slog" 7 8 "net/http" 路路路 31 32 } 32 33 33 34 func (h *handlers) infoRefs(w http.ResponseWriter, r *http.Request) { 34 - name := filepath.Clean(r.PathValue("name")) 35 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 35 + name := r.PathValue("name") 36 + _, err := h.openPublicRepo(name, "") 36 37 if err != nil { 37 38 h.write404(w, err) 38 39 return 39 40 } 40 41 41 - isPrivate, err := repo.IsPrivate() 42 - if isPrivate || err != nil { 43 - h.write404(w, err) 44 - return 45 - } 46 - 47 42 w.Header().Set("content-type", "application/x-git-upload-pack-advertisement") 48 43 w.WriteHeader(http.StatusOK) 49 44 路路路 57 52 } 58 53 59 54 func (h *handlers) uploadPack(w http.ResponseWriter, r *http.Request) { 60 - name := filepath.Clean(r.PathValue("name")) 61 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 55 + name := r.PathValue("name") 56 + _, err := h.openPublicRepo(name, "") 62 57 if err != nil { 63 58 h.write404(w, err) 64 59 return 65 60 } 66 61 67 - isPrivate, err := repo.IsPrivate() 68 - if isPrivate || err != nil { 69 - h.write404(w, err) 70 - return 71 - } 72 - 73 62 w.Header().Set("content-type", "application/x-git-upload-pack-result") 74 63 w.Header().Set("Connection", "Keep-Alive") 75 64 w.Header().Set("Transfer-Encoding", "chunked") 路路路 95 84 slog.Error("git: upload-pack", "err", err) 96 85 return 97 86 } 87 +} 88 + 89 +func (h *handlers) openPublicRepo(name, ref string) (*git.Repo, error) { 90 + n := filepath.Clean(name) 91 + repo, err := git.Open(filepath.Join(h.c.Repo.Dir, n), ref) 92 + if err != nil { 93 + return nil, err 94 + } 95 + 96 + isPrivate, err := repo.IsPrivate() 97 + if err != nil { 98 + return nil, err 99 + } 100 + 101 + if isPrivate { 102 + return nil, fmt.Errorf("repo is private") 103 + } 104 + 105 + return repo, nil 98 106 } 99 107 100 108 type flushWriter struct {
M
internal/handlers/repo.go
路路路 17 17 "github.com/yuin/goldmark" 18 18 "github.com/yuin/goldmark/extension" 19 19 "github.com/yuin/goldmark/renderer/html" 20 - "olexsmir.xyz/mugit/internal/git" 21 20 "olexsmir.xyz/mugit/internal/humanize" 22 21 ) 23 22 路路路 36 35 repoInfos := []repoInfo{} 37 36 for _, dir := range dirs { 38 37 name := dir.Name() 39 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 38 + repo, err := h.openPublicRepo(name, "") 40 39 if err != nil { 41 40 slog.Error("", "name", name, "err", err) 42 41 continue 路路路 54 53 continue 55 54 } 56 55 57 - if isPrivate, err := repo.IsPrivate(); err != nil || isPrivate { 58 - slog.Error("", "err", err) 59 - continue 60 - } 61 - 62 56 repoInfos = append(repoInfos, repoInfo{ 63 57 Name: name, 64 58 Desc: desc, 路路路 85 79 )) 86 80 87 81 func (h *handlers) repoIndex(w http.ResponseWriter, r *http.Request) { 88 - name := filepath.Clean(r.PathValue("name")) 89 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 82 + name := r.PathValue("name") 83 + repo, err := h.openPublicRepo(name, "") 90 84 if err != nil { 91 85 h.write404(w, err) 92 86 return 93 87 } 94 88 95 - isPrivate, err := repo.IsPrivate() 96 - if isPrivate || err != nil { 97 - h.write404(w, err) 98 - return 99 - } 100 - 101 89 var readmeContents template.HTML 102 90 for _, readme := range h.c.Repo.Readmes { 103 91 ext := filepath.Ext(readme) 路路路 154 142 } 155 143 156 144 func (h *handlers) repoTree(w http.ResponseWriter, r *http.Request) { 157 - name := filepath.Clean(r.PathValue("name")) 145 + name := r.PathValue("name") 158 146 ref := r.PathValue("ref") 159 147 treePath := r.PathValue("rest") 160 148 161 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), ref) 149 + repo, err := h.openPublicRepo(name, ref) 162 150 if err != nil { 163 151 h.write404(w, err) 164 152 return 路路路 195 183 } 196 184 197 185 func (h *handlers) fileContents(w http.ResponseWriter, r *http.Request) { 198 - name := filepath.Clean(r.PathValue("name")) 186 + name := r.PathValue("name") 199 187 ref := r.PathValue("ref") 200 188 treePath := r.PathValue("rest") 201 189 路路路 204 192 raw = rawParam 205 193 } 206 194 207 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 195 + repo, err := h.openPublicRepo(name, ref) 208 196 if err != nil { 209 - h.write404(w, err) 210 - return 211 - } 212 - 213 - isPrivate, err := repo.IsPrivate() 214 - if isPrivate || err != nil { 215 197 h.write404(w, err) 216 198 return 217 199 } 路路路 261 243 } 262 244 263 245 func (h *handlers) log(w http.ResponseWriter, r *http.Request) { 264 - name := filepath.Clean(r.PathValue("name")) 246 + name := r.PathValue("name") 265 247 ref := r.PathValue("ref") 266 248 267 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), ref) 249 + repo, err := h.openPublicRepo(name, ref) 268 250 if err != nil { 269 251 h.write404(w, err) 270 252 return 路路路 299 281 } 300 282 301 283 func (h *handlers) commit(w http.ResponseWriter, r *http.Request) { 302 - name := filepath.Clean(r.PathValue("name")) 284 + name := r.PathValue("name") 303 285 ref := r.PathValue("ref") 304 - 305 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), ref) 286 + repo, err := h.openPublicRepo(name, ref) 306 287 if err != nil { 307 288 h.write404(w, err) 308 289 return 路路路 337 318 } 338 319 339 320 func (h *handlers) refs(w http.ResponseWriter, r *http.Request) { 340 - name := filepath.Clean(r.PathValue("name")) 341 - repo, err := git.Open(filepath.Join(h.c.Repo.Dir, name), "") 321 + name := r.PathValue("name") 322 + repo, err := h.openPublicRepo(name, "") 342 323 if err != nil { 343 324 h.write404(w, err) 344 325 return
M
internal/ssh/server.go
路路路 4 4 "fmt" 5 5 "log/slog" 6 6 "path/filepath" 7 + "slices" 7 8 "strconv" 8 9 9 10 "github.com/gliderlabs/ssh" 路路路 53 54 54 55 slog.Info("ssh request", "fingerprint", fingerprint) 55 56 56 - authorized := false 57 - for _, authKey := range s.authKeys { 58 - if ssh.KeysEqual(key, authKey) { 59 - authorized = true 60 - break 61 - } 62 - } 63 - 57 + authorized := slices.ContainsFunc(s.authKeys, func(i gossh.PublicKey) bool { 58 + return ssh.KeysEqual(key, i) 59 + }) 64 60 ctx.SetValue(authorizedKey, authorized) 65 61 return true 66 62 }