package middleware import ( "context" "farga/db/types" "farga/lib" "farga/templating" "net/http" "github.com/google/uuid" "github.com/gorilla/mux" ) var RepoKey = "repo" // manages retrieving repo DB data + private func Repo(store Store) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) userHandle := vars["user"] repoName := vars["repo"] dbRepo, err := store.RepoHandle(userHandle, repoName) if err != nil || dbRepo.ID == uuid.Nil { templating.Render(w, r, "base", "repo/not_found") return } // verify if the user has access to the repo. reqUser, ok := r.Context().Value(lib.UserKey).(*types.User) if dbRepo.IsPrivate && (!ok || dbRepo.User.ID != reqUser.ID) { templating.Render(w, r, "base", "repo/not_found") return } ctx := context.WithValue(r.Context(), RepoKey, dbRepo) r = r.WithContext(ctx) next.ServeHTTP(w, r) }) } } // only allows the owner of a repo through. // requires `md.Repo` and `md.GeneralAuth` middleware. func RequireRepoOwnership(store Store) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { repo, repoOk := r.Context().Value(RepoKey).(types.Repo) user, userOk := r.Context().Value(lib.UserKey).(*types.User) if !repoOk || !userOk || user.ID == uuid.Nil { templating.Render(w, r, "base", "repo/not_found") return } if *repo.UserID != user.ID { http.Redirect(w, r, "?err=Forbidden", http.StatusSeeOther) return } next.ServeHTTP(w, r) }) } }