package server import ( "errors" "net/http" "strconv" "github.com/go-chi/chi/v5" "git.wntrmute.dev/mc/mcr/internal/auth" "git.wntrmute.dev/mc/mcr/internal/db" ) // AdminListReposHandler handles GET /v1/repositories. func AdminListReposHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { limit := 50 offset := 0 if n := r.URL.Query().Get("n"); n != "" { if v, err := strconv.Atoi(n); err == nil && v > 0 { limit = v } } if o := r.URL.Query().Get("offset"); o != "" { if v, err := strconv.Atoi(o); err == nil && v >= 0 { offset = v } } repos, err := database.ListRepositoriesWithMetadata(limit, offset) if err != nil { writeAdminError(w, http.StatusInternalServerError, "internal error") return } if repos == nil { repos = []db.RepoMetadata{} } writeJSON(w, http.StatusOK, repos) } } // AdminGetRepoHandler handles GET /v1/repositories/*. func AdminGetRepoHandler(database *db.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { name := chi.URLParam(r, "*") if name == "" { writeAdminError(w, http.StatusBadRequest, "repository name required") return } detail, err := database.GetRepositoryDetail(name) if err != nil { if errors.Is(err, db.ErrRepoNotFound) { writeAdminError(w, http.StatusNotFound, "repository not found") return } writeAdminError(w, http.StatusInternalServerError, "internal error") return } writeJSON(w, http.StatusOK, detail) } } // AdminDeleteRepoHandler handles DELETE /v1/repositories/*. // Requires admin role (enforced by RequireAdmin middleware). func AdminDeleteRepoHandler(database *db.DB, auditFn AuditFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { name := chi.URLParam(r, "*") if name == "" { writeAdminError(w, http.StatusBadRequest, "repository name required") return } if err := database.DeleteRepository(name); err != nil { if errors.Is(err, db.ErrRepoNotFound) { writeAdminError(w, http.StatusNotFound, "repository not found") return } writeAdminError(w, http.StatusInternalServerError, "internal error") return } if auditFn != nil { claims := auth.ClaimsFromContext(r.Context()) actorID := "" if claims != nil { actorID = claims.Subject } auditFn("repo_deleted", actorID, name, "", r.RemoteAddr, nil) } w.WriteHeader(http.StatusNoContent) } }