fixed PR issue
This commit is contained in:
@@ -156,16 +156,8 @@ func (h *ArtifactHandler) Download(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *ArtifactHandler) resolveRunIDs(w http.ResponseWriter, r *http.Request) (repoID, runID int64, ok bool) {
|
||||
owner := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var u models.User
|
||||
if found, _ := h.db.Where("username = ?", owner).Get(&u); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, 0, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
rID, ok := resolveRepoID(h.db, w, r)
|
||||
if !ok {
|
||||
return 0, 0, false
|
||||
}
|
||||
runID, err := strconv.ParseInt(chi.URLParam(r, "runID"), 10, 64)
|
||||
@@ -173,7 +165,7 @@ func (h *ArtifactHandler) resolveRunIDs(w http.ResponseWriter, r *http.Request)
|
||||
jsonError(w, "invalid run ID", http.StatusBadRequest)
|
||||
return 0, 0, false
|
||||
}
|
||||
return repo.ID, runID, true
|
||||
return rID, runID, true
|
||||
}
|
||||
|
||||
func isUnder(root, path string) bool {
|
||||
|
||||
@@ -323,19 +323,7 @@ func (h *EnvironmentHandler) UpdateDeploymentStatus(w http.ResponseWriter, r *ht
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func (h *EnvironmentHandler) resolveRepo(w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
owner := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var u models.User
|
||||
if found, _ := h.db.Where("username = ?", owner).Get(&u); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
return resolveRepoID(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *EnvironmentHandler) resolveEnv(w http.ResponseWriter, r *http.Request) (*models.Environment, bool) {
|
||||
|
||||
@@ -132,20 +132,7 @@ func (h *IssueHandler) Reopen(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *IssueHandler) repoID(w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
|
||||
var owner models.User
|
||||
if found, _ := h.db.Where("username = ?", ownerName).Get(&owner); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
return resolveRepoID(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *IssueHandler) lookupIssue(w http.ResponseWriter, r *http.Request) (*models.Issue, bool) {
|
||||
|
||||
@@ -48,19 +48,13 @@ type deployKeyResponse struct {
|
||||
}
|
||||
|
||||
func (h *DeployKeyHandler) lookupRepo(w http.ResponseWriter, r *http.Request) (*models.Repository, *models.User, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
repo, ok := resolveRepo(h.db, w, r)
|
||||
if !ok {
|
||||
return nil, nil, false
|
||||
}
|
||||
var owner models.User
|
||||
if found, _ := h.db.Where("username = ?", ownerName).Get(&owner); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, nil, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, nil, false
|
||||
}
|
||||
return &repo, &owner, true
|
||||
h.db.ID(repo.OwnerID).Get(&owner)
|
||||
return repo, &owner, true
|
||||
}
|
||||
|
||||
func (h *DeployKeyHandler) canManage(repo *models.Repository, callerID int64) bool {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/api/middleware"
|
||||
@@ -16,31 +15,7 @@ type LFSHandler struct{ db *xorm.Engine }
|
||||
func NewLFSHandler(db *xorm.Engine) *LFSHandler { return &LFSHandler{db: db} }
|
||||
|
||||
func (h *LFSHandler) resolveRepo(w http.ResponseWriter, r *http.Request) (*models.Repository, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
|
||||
var owner models.User
|
||||
found, err := h.db.Where("username = ?", ownerName).Get(&owner)
|
||||
if err != nil {
|
||||
jsonError(w, "database error: "+err.Error(), http.StatusInternalServerError)
|
||||
return nil, false
|
||||
}
|
||||
if !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
var repo models.Repository
|
||||
found, err = h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo)
|
||||
if err != nil {
|
||||
jsonError(w, "database error: "+err.Error(), http.StatusInternalServerError)
|
||||
return nil, false
|
||||
}
|
||||
if !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
return &repo, true
|
||||
return resolveRepo(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *LFSHandler) canManage(repo *models.Repository, callerID int64) bool {
|
||||
|
||||
@@ -28,22 +28,15 @@ type memberResponse struct {
|
||||
AddedAt string `json:"addedAt"`
|
||||
}
|
||||
|
||||
// lookupRepoForMembers resolves the repo from URL params and returns the owner User.
|
||||
// lookupRepoAndOwner resolves {owner}/{repo} and returns the repo + its creator user.
|
||||
func (h *MemberHandler) lookupRepoAndOwner(w http.ResponseWriter, r *http.Request) (*models.Repository, *models.User, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
|
||||
repo, ok := resolveRepo(h.db, w, r)
|
||||
if !ok {
|
||||
return nil, nil, false
|
||||
}
|
||||
var owner models.User
|
||||
if found, _ := h.db.Where("username = ?", ownerName).Get(&owner); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, nil, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, nil, false
|
||||
}
|
||||
return &repo, &owner, true
|
||||
h.db.ID(repo.OwnerID).Get(&owner)
|
||||
return repo, &owner, true
|
||||
}
|
||||
|
||||
// callerCanManage returns true if callerID is the repo owner or has admin permission.
|
||||
|
||||
@@ -247,19 +247,7 @@ func (h *PipelineHandler) RetryJob(w http.ResponseWriter, r *http.Request) {
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func (h *PipelineHandler) repoID(w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
owner := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var u models.User
|
||||
if found, _ := h.db.Where("username = ?", owner).Get(&u); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
return resolveRepoID(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *PipelineHandler) lookupRun(w http.ResponseWriter, r *http.Request) (*models.PipelineRun, bool) {
|
||||
|
||||
@@ -18,29 +18,7 @@ func NewPRSettingsHandler(db *xorm.Engine) *PRSettingsHandler {
|
||||
}
|
||||
|
||||
func (h *PRSettingsHandler) resolveRepo(w http.ResponseWriter, r *http.Request) (*models.Repository, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var owner models.User
|
||||
found, err := h.db.Where("username = ?", ownerName).Get(&owner)
|
||||
if err != nil {
|
||||
jsonError(w, "database error: "+err.Error(), http.StatusInternalServerError)
|
||||
return nil, false
|
||||
}
|
||||
if !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
var repo models.Repository
|
||||
found, err = h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo)
|
||||
if err != nil {
|
||||
jsonError(w, "database error: "+err.Error(), http.StatusInternalServerError)
|
||||
return nil, false
|
||||
}
|
||||
if !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
return &repo, true
|
||||
return resolveRepo(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *PRSettingsHandler) canManage(repo *models.Repository, callerID int64) bool {
|
||||
|
||||
@@ -241,23 +241,7 @@ func (h *PRHandler) Update(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *PRHandler) repoIDFromURL(w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
|
||||
var owner models.User
|
||||
found, err := h.db.Where("username = ?", ownerName).Get(&owner)
|
||||
if err != nil || !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
|
||||
var repo models.Repository
|
||||
found, err = h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo)
|
||||
if err != nil || !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
return resolveRepoID(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *PRHandler) lookupPR(w http.ResponseWriter, r *http.Request) (*models.PullRequest, bool) {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package handlers
|
||||
|
||||
// repo_lookup.go — shared helper used by all handlers that resolve
|
||||
// {owner}/{repo} URL params to a repository row.
|
||||
//
|
||||
// The owner segment can be either a user username (user-owned repo) or a
|
||||
// workspace handle (workspace-owned repo). This tries user-namespace first,
|
||||
// then workspace-namespace, so the lookup is always unambiguous.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/models"
|
||||
)
|
||||
|
||||
// resolveRepoID resolves /{owner}/{repo} to a repository ID.
|
||||
// It tries user namespace first, then workspace namespace.
|
||||
// Returns (repoID, true) on success or writes a 404 and returns (0, false).
|
||||
func resolveRepoID(db *xorm.Engine, w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
repo, ok := resolveRepo(db, w, r)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
}
|
||||
|
||||
// resolveRepo is the full repo lookup returning the Repository struct.
|
||||
func resolveRepo(db *xorm.Engine, w http.ResponseWriter, r *http.Request) (*models.Repository, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
|
||||
// 1. Try user namespace.
|
||||
var u models.User
|
||||
if found, _ := db.Where("username = ?", ownerName).Get(&u); found {
|
||||
var repo models.Repository
|
||||
if found2, _ := db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); found2 {
|
||||
return &repo, true
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Try workspace namespace.
|
||||
var ws models.Workspace
|
||||
if found, _ := db.Where("handle = ?", ownerName).Get(&ws); found {
|
||||
var repo models.Repository
|
||||
if found2, _ := db.Where("workspace_id = ? AND name = ?", ws.ID, repoName).Get(&repo); found2 {
|
||||
return &repo, true
|
||||
}
|
||||
}
|
||||
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
@@ -242,29 +242,7 @@ func ResolveSecretsForRun(db *xorm.Engine, repoID, workspaceID, envID int64, ses
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func (h *SecretHandler) resolveRepoID(w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
owner := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var u models.User
|
||||
if found, _ := h.db.Where("username = ?", owner).Get(&u); !found {
|
||||
// Try workspace
|
||||
var ws models.Workspace
|
||||
if found2, _ := h.db.Where("handle = ?", owner).Get(&ws); !found2 {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found3, _ := h.db.Where("workspace_id = ? AND name = ?", ws.ID, repoName).Get(&repo); !found3 {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return 0, false
|
||||
}
|
||||
return repo.ID, true
|
||||
return resolveRepoID(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *SecretHandler) resolveEnvID(w http.ResponseWriter, r *http.Request) (int64, bool) {
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"xorm.io/xorm"
|
||||
|
||||
gitdomain "github.com/forgeo/forgebucket/internal/domain/git"
|
||||
@@ -69,23 +68,13 @@ type TimelineEvent struct {
|
||||
//
|
||||
// GET /api/v1/repos/:owner/:repo/timeline?limit=60
|
||||
func (h *TimelineHandler) GetTimeline(w http.ResponseWriter, r *http.Request) {
|
||||
owner := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
|
||||
limit := 60
|
||||
if l, err := strconv.Atoi(r.URL.Query().Get("limit")); err == nil && l > 0 && l <= 200 {
|
||||
limit = l
|
||||
}
|
||||
|
||||
// ── Resolve repo ──────────────────────────────────────────────────────────
|
||||
var u models.User
|
||||
if found, _ := h.db.Where("username = ?", owner).Get(&u); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
repo, ok := resolveRepo(h.db, w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -30,19 +30,7 @@ type accessTokenResponse struct {
|
||||
}
|
||||
|
||||
func (h *AccessTokenHandler) lookupRepo(w http.ResponseWriter, r *http.Request) (*models.Repository, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var owner models.User
|
||||
if found, _ := h.db.Where("username = ?", ownerName).Get(&owner); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
return &repo, true
|
||||
return resolveRepo(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *AccessTokenHandler) canManage(repo *models.Repository, callerID int64) bool {
|
||||
|
||||
@@ -55,19 +55,7 @@ func toWebhookResp(wh models.Webhook) webhookResponse {
|
||||
}
|
||||
|
||||
func (h *WebhookHandler) resolveRepo(w http.ResponseWriter, r *http.Request) (*models.Repository, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
var owner models.User
|
||||
if found, _ := h.db.Where("username = ?", ownerName).Get(&owner); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, false
|
||||
}
|
||||
return &repo, true
|
||||
return resolveRepo(h.db, w, r)
|
||||
}
|
||||
|
||||
func (h *WebhookHandler) canManage(repo *models.Repository, callerID int64) bool {
|
||||
|
||||
@@ -22,19 +22,13 @@ type WorkflowHandler struct{ db *xorm.Engine }
|
||||
func NewWorkflowHandler(db *xorm.Engine) *WorkflowHandler { return &WorkflowHandler{db: db} }
|
||||
|
||||
func (h *WorkflowHandler) resolveRepo(w http.ResponseWriter, r *http.Request) (*models.Repository, *models.User, bool) {
|
||||
ownerName := chi.URLParam(r, "owner")
|
||||
repoName := chi.URLParam(r, "repo")
|
||||
repo, ok := resolveRepo(h.db, w, r)
|
||||
if !ok {
|
||||
return nil, nil, false
|
||||
}
|
||||
var owner models.User
|
||||
if found, _ := h.db.Where("username = ?", ownerName).Get(&owner); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, nil, false
|
||||
}
|
||||
var repo models.Repository
|
||||
if found, _ := h.db.Where("owner_id = ? AND name = ?", owner.ID, repoName).Get(&repo); !found {
|
||||
jsonError(w, "repository not found", http.StatusNotFound)
|
||||
return nil, nil, false
|
||||
}
|
||||
return &repo, &owner, true
|
||||
h.db.ID(repo.OwnerID).Get(&owner)
|
||||
return repo, &owner, true
|
||||
}
|
||||
|
||||
func (h *WorkflowHandler) canManage(repo *models.Repository, callerID int64) bool {
|
||||
|
||||
Reference in New Issue
Block a user