main / internal/interface/web/git_handler.go
1.2 KB · Go Raw
1package web
2
3import (
4 "errors"
5 "net/http"
6 "strings"
7
8 "github.com/go-chi/chi"
9
10 "gitgud/internal/domain"
11)
12
13func (h *Handlers) gitHTTP(w http.ResponseWriter, r *http.Request) {
14 owner := chi.URLParam(r, "owner")
15 repoName := strings.TrimSuffix(chi.URLParam(r, "repo"), ".git")
16
17 isPush := strings.HasSuffix(r.URL.Path, "git-receive-pack") ||
18 r.URL.Query().Get("service") == "git-receive-pack"
19
20 user := h.basicAuthUser(r)
21
22 allow, needAuth, remoteUser, err := h.gitAccess.Authorize(r.Context(), owner, repoName, isPush, user)
23 if needAuth {
24 requireBasicAuth(w)
25 return
26 }
27 if err != nil {
28 if errors.Is(err, domain.ErrPermission) {
29 http.Error(w, "forbidden", http.StatusForbidden)
30 return
31 }
32 http.NotFound(w, r)
33 return
34 }
35 if !allow {
36 http.NotFound(w, r)
37 return
38 }
39
40 h.gitBackend.Handler(remoteUser).ServeHTTP(w, r)
41}
42
43func (h *Handlers) basicAuthUser(r *http.Request) *domain.User {
44 username, password, ok := r.BasicAuth()
45 if !ok {
46 return nil
47 }
48 u, err := h.users.Authenticate(r.Context(), username, password)
49 if err != nil {
50 return nil
51 }
52 return u
53}
54
55func requireBasicAuth(w http.ResponseWriter) {
56 w.Header().Set("WWW-Authenticate", `Basic realm="gitgud"`)
57 http.Error(w, "authentication required", http.StatusUnauthorized)
58}