diff --git a/handlers.go b/handlers.go index f4d68ab..10794ca 100644 --- a/handlers.go +++ b/handlers.go @@ -122,15 +122,29 @@ func getMetricLabels(r *http.Request) prometheus.Labels { return labels } +// isUserPath checks if a request path is accessible by the user when using +// private repositories. +func isUserPath(username, path string) bool { + prefix := "/" + username + if !strings.HasPrefix(path, prefix) { + return false + } + return len(path) == len(prefix) || path[len(prefix)] == '/' +} + // AuthHandler wraps h with a http.HandlerFunc that performs basic authentication against the user/passwords pairs // stored in f and returns the http.HandlerFunc. func AuthHandler(f *HtpasswdFile, h http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - if username, password, ok := r.BasicAuth(); !ok || !f.Validate(username, password) { + username, password, ok := r.BasicAuth() + if !ok || !f.Validate(username, password) { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + if Config.PrivateRepos && !isUserPath(username, r.URL.Path) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } - h.ServeHTTP(w, r) } } @@ -141,12 +155,6 @@ func CheckConfig(w http.ResponseWriter, r *http.Request) { log.Println("CheckConfig()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - cfg, err := getPath(r, "config") if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -171,12 +179,6 @@ func GetConfig(w http.ResponseWriter, r *http.Request) { log.Println("GetConfig()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - cfg, err := getPath(r, "config") if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -201,12 +203,6 @@ func SaveConfig(w http.ResponseWriter, r *http.Request) { log.Println("SaveConfig()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - cfg, err := getPath(r, "config") if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -237,12 +233,6 @@ func DeleteConfig(w http.ResponseWriter, r *http.Request) { log.Println("DeleteConfig()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - if Config.AppendOnly { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return @@ -274,12 +264,6 @@ func ListBlobs(w http.ResponseWriter, r *http.Request) { log.Println("ListBlobs()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - fileType := pat.Param(r, "type") path, err := getPath(r, fileType) if err != nil { @@ -335,12 +319,6 @@ func CheckBlob(w http.ResponseWriter, r *http.Request) { log.Println("CheckBlob()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - path, err := getFilePath(r, pat.Param(r, "type"), pat.Param(r, "name")) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -365,12 +343,6 @@ func GetBlob(w http.ResponseWriter, r *http.Request) { log.Println("GetBlob()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - path, err := getFilePath(r, pat.Param(r, "type"), pat.Param(r, "name")) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -407,12 +379,6 @@ func SaveBlob(w http.ResponseWriter, r *http.Request) { log.Println("SaveBlob()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - path, err := getFilePath(r, pat.Param(r, "type"), pat.Param(r, "name")) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -482,12 +448,6 @@ func DeleteBlob(w http.ResponseWriter, r *http.Request) { log.Println("DeleteBlob()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - if Config.AppendOnly && pat.Param(r, "type") != "locks" { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return @@ -532,12 +492,6 @@ func CreateRepo(w http.ResponseWriter, r *http.Request) { log.Println("CreateRepo()") } - // private repos - if Config.PrivateRepos && (getUser(r) != getRepo(r)) { - http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) - return - } - repo, err := join(Config.Path, getRepo(r)) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)