forgejo-tickets/internal/handlers/admin/repos.go

148 lines
4.3 KiB
Go

package admin
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/mattnite/forgejo-tickets/internal/forgejo"
"github.com/mattnite/forgejo-tickets/internal/models"
"github.com/rs/zerolog/log"
)
type RepoHandler struct {
deps Dependencies
}
func (h *RepoHandler) List(c *gin.Context) {
var repos []models.Repo
if err := h.deps.DB.Order("name ASC").Find(&repos).Error; err != nil {
log.Error().Err(err).Msg("list repos error")
h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusInternalServerError, "Failed to load repos")
return
}
h.deps.Renderer.Render(c.Writer, c.Request, "admin/repos/list", map[string]interface{}{
"Repos": repos,
"BaseURL": h.deps.Config.BaseURL,
})
}
func (h *RepoHandler) NewForm(c *gin.Context) {
h.deps.Renderer.Render(c.Writer, c.Request, "admin/repos/new", nil)
}
func (h *RepoHandler) Create(c *gin.Context) {
name := strings.TrimSpace(c.PostForm("name"))
slug := strings.TrimSpace(c.PostForm("slug"))
forgejoOwner := strings.TrimSpace(c.PostForm("forgejo_owner"))
forgejoRepo := strings.TrimSpace(c.PostForm("forgejo_repo"))
active := c.PostForm("active") == "on"
if name == "" || slug == "" || forgejoOwner == "" || forgejoRepo == "" {
h.deps.Renderer.Render(c.Writer, c.Request, "admin/repos/new", map[string]interface{}{
"Error": "All fields are required",
"Name": name,
"Slug": slug,
"ForgejoOwner": forgejoOwner,
"ForgejoRepo": forgejoRepo,
})
return
}
webhookSecret, err := forgejo.GenerateWebhookSecret()
if err != nil {
log.Error().Err(err).Msg("generate webhook secret error")
h.deps.Renderer.Render(c.Writer, c.Request, "admin/repos/new", map[string]interface{}{
"Error": "Failed to generate webhook secret",
"Name": name,
"Slug": slug,
"ForgejoOwner": forgejoOwner,
"ForgejoRepo": forgejoRepo,
})
return
}
repo := models.Repo{
Name: name,
Slug: slug,
ForgejoOwner: forgejoOwner,
ForgejoRepo: forgejoRepo,
WebhookSecret: webhookSecret,
Active: active,
}
if ssoKey := strings.TrimSpace(c.PostForm("sso_public_key")); ssoKey != "" {
repo.SSOPublicKey = &ssoKey
}
if err := h.deps.DB.Create(&repo).Error; err != nil {
log.Error().Err(err).Msg("create repo error")
h.deps.Renderer.Render(c.Writer, c.Request, "admin/repos/new", map[string]interface{}{
"Error": "Failed to create repo: " + err.Error(),
"Name": name,
"Slug": slug,
"ForgejoOwner": forgejoOwner,
"ForgejoRepo": forgejoRepo,
})
return
}
c.Redirect(http.StatusSeeOther, "/repos/"+repo.ID.String()+"/edit")
}
func (h *RepoHandler) EditForm(c *gin.Context) {
repoID, err := uuid.Parse(c.Param("id"))
if err != nil {
h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusBadRequest, "Invalid repo ID")
return
}
var repo models.Repo
if err := h.deps.DB.First(&repo, "id = ?", repoID).Error; err != nil {
h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusNotFound, "Repo not found")
return
}
h.deps.Renderer.Render(c.Writer, c.Request, "admin/repos/edit", map[string]interface{}{
"Repo": repo,
"BaseURL": h.deps.Config.BaseURL,
"ForgejoURL": h.deps.Config.ForgejoURL,
})
}
func (h *RepoHandler) Update(c *gin.Context) {
repoID, err := uuid.Parse(c.Param("id"))
if err != nil {
h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusBadRequest, "Invalid repo ID")
return
}
name := strings.TrimSpace(c.PostForm("name"))
slug := strings.TrimSpace(c.PostForm("slug"))
forgejoOwner := strings.TrimSpace(c.PostForm("forgejo_owner"))
forgejoRepo := strings.TrimSpace(c.PostForm("forgejo_repo"))
active := c.PostForm("active") == "on"
var ssoPublicKey *string
if ssoKey := strings.TrimSpace(c.PostForm("sso_public_key")); ssoKey != "" {
ssoPublicKey = &ssoKey
}
if err := h.deps.DB.Model(&models.Repo{}).Where("id = ?", repoID).Updates(map[string]interface{}{
"name": name,
"slug": slug,
"forgejo_owner": forgejoOwner,
"forgejo_repo": forgejoRepo,
"active": active,
"sso_public_key": ssoPublicKey,
}).Error; err != nil {
log.Error().Err(err).Msg("update repo error")
h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusInternalServerError, "Failed to update repo")
return
}
c.Redirect(http.StatusSeeOther, "/repos/"+repoID.String()+"/edit")
}