package admin import ( "crypto/rand" "encoding/hex" "net/http" "strings" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/mattnite/forgejo-tickets/internal/models" "github.com/rs/zerolog/log" ) type UserHandler struct { deps Dependencies } func (h *UserHandler) List(c *gin.Context) { var users []models.User if err := h.deps.DB.Order("created_at DESC").Limit(100).Find(&users).Error; err != nil { log.Error().Err(err).Msg("list users error") h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusInternalServerError, "Failed to load users") return } h.deps.Renderer.Render(c.Writer, c.Request, "admin/users/list", map[string]interface{}{ "Users": users, }) } func (h *UserHandler) Detail(c *gin.Context) { userID, err := uuid.Parse(c.Param("id")) if err != nil { h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusBadRequest, "Invalid user ID") return } var user models.User if err := h.deps.DB.First(&user, "id = ?", userID).Error; err != nil { h.deps.Renderer.RenderError(c.Writer, c.Request, http.StatusNotFound, "User not found") return } var tickets []models.Ticket h.deps.DB.Preload("Repo").Where("user_id = ?", user.ID).Order("created_at DESC").Limit(50).Find(&tickets) h.deps.Renderer.Render(c.Writer, c.Request, "admin/users/detail", map[string]interface{}{ "User": user, "Tickets": tickets, }) } func (h *UserHandler) NewForm(c *gin.Context) { h.deps.Renderer.Render(c.Writer, c.Request, "admin/users/new", nil) } func (h *UserHandler) Create(c *gin.Context) { name := strings.TrimSpace(c.PostForm("name")) email := strings.TrimSpace(c.PostForm("email")) if name == "" || email == "" { h.deps.Renderer.Render(c.Writer, c.Request, "admin/users/new", map[string]interface{}{ "Error": "Name and email are required", "Name": name, "Email": email, }) return } tempPassBytes := make([]byte, 12) rand.Read(tempPassBytes) tempPassword := hex.EncodeToString(tempPassBytes)[:16] user, err := h.deps.Auth.CreateUserWithPassword(c.Request.Context(), email, tempPassword, name, true) if err != nil { if strings.Contains(err.Error(), "duplicate key") || strings.Contains(err.Error(), "unique") { h.deps.Renderer.Render(c.Writer, c.Request, "admin/users/new", map[string]interface{}{ "Error": "A user with this email already exists", "Name": name, "Email": email, }) } else { h.deps.Renderer.Render(c.Writer, c.Request, "admin/users/new", map[string]interface{}{ "Error": "Failed to create user: " + err.Error(), "Name": name, "Email": email, }) } return } if err := h.deps.EmailClient.SendWelcomeEmail(email, name, tempPassword); err != nil { log.Error().Err(err).Msg("send welcome email error") } c.Redirect(http.StatusSeeOther, "/users/"+user.ID.String()) }