gohorsejobs/backend/internal/admin/cpanel/handler.go
Tiago Yamamoto b2284921ea feat: add Cloudflare and cPanel admin routes
Cloudflare Cache Management:
- GET /api/v1/admin/cloudflare/zones
- POST /api/v1/admin/cloudflare/cache/purge-all
- POST /api/v1/admin/cloudflare/cache/purge-urls
- POST /api/v1/admin/cloudflare/cache/purge-tags
- POST /api/v1/admin/cloudflare/cache/purge-hosts

cPanel Email Management:
- GET /api/v1/admin/cpanel/emails
- POST /api/v1/admin/cpanel/emails
- DELETE /api/v1/admin/cpanel/emails/{email}
- PUT /api/v1/admin/cpanel/emails/{email}/password
- PUT /api/v1/admin/cpanel/emails/{email}/quota

All routes protected by JWT auth middleware.
Added CLOUDFLARE_* and CPANEL_* env vars to .env.example
2025-12-14 10:11:36 -03:00

205 lines
6.3 KiB
Go

package cpanel
import (
"encoding/json"
"net/http"
)
// Handler handles cPanel admin endpoints
type Handler struct {
client *Client
}
// NewHandler creates a new cPanel handler
func NewHandler() *Handler {
return &Handler{
client: NewClient(),
}
}
// CreateEmailRequest is the request body for creating an email
type CreateEmailRequest struct {
Email string `json:"email"`
Password string `json:"password"`
Quota int `json:"quota"` // MB, 0 = unlimited
}
// ChangePasswordRequest is the request body for changing password
type ChangePasswordRequest struct {
Password string `json:"password"`
}
// UpdateQuotaRequest is the request body for updating quota
type UpdateQuotaRequest struct {
Quota int `json:"quota"` // MB
}
// ListEmails godoc
// @Summary List Email Accounts
// @Description Returns all email accounts for the cPanel account
// @Tags Admin - cPanel
// @Accept json
// @Produce json
// @Param domain query string false "Filter by domain"
// @Success 200 {array} EmailAccount
// @Failure 500 {string} string "Internal Server Error"
// @Security BearerAuth
// @Router /api/v1/admin/cpanel/emails [get]
func (h *Handler) ListEmails(w http.ResponseWriter, r *http.Request) {
domain := r.URL.Query().Get("domain")
emails, err := h.client.ListEmails(domain)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(emails)
}
// CreateEmail godoc
// @Summary Create Email Account
// @Description Creates a new email account
// @Tags Admin - cPanel
// @Accept json
// @Produce json
// @Param body body CreateEmailRequest true "Email details"
// @Success 201 {object} map[string]string
// @Failure 400 {string} string "Bad Request"
// @Failure 500 {string} string "Internal Server Error"
// @Security BearerAuth
// @Router /api/v1/admin/cpanel/emails [post]
func (h *Handler) CreateEmail(w http.ResponseWriter, r *http.Request) {
var req CreateEmailRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if req.Email == "" || req.Password == "" {
http.Error(w, "Email and password are required", http.StatusBadRequest)
return
}
if err := h.client.CreateEmail(req.Email, req.Password, req.Quota); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{
"message": "Email created successfully",
"email": req.Email,
})
}
// DeleteEmail godoc
// @Summary Delete Email Account
// @Description Deletes an email account
// @Tags Admin - cPanel
// @Accept json
// @Produce json
// @Param email path string true "Email address"
// @Success 200 {object} map[string]string
// @Failure 400 {string} string "Bad Request"
// @Failure 500 {string} string "Internal Server Error"
// @Security BearerAuth
// @Router /api/v1/admin/cpanel/emails/{email} [delete]
func (h *Handler) DeleteEmail(w http.ResponseWriter, r *http.Request) {
email := r.PathValue("email")
if email == "" {
http.Error(w, "Email is required", http.StatusBadRequest)
return
}
if err := h.client.DeleteEmail(email); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"message": "Email deleted successfully",
})
}
// ChangePassword godoc
// @Summary Change Email Password
// @Description Changes the password for an email account
// @Tags Admin - cPanel
// @Accept json
// @Produce json
// @Param email path string true "Email address"
// @Param body body ChangePasswordRequest true "New password"
// @Success 200 {object} map[string]string
// @Failure 400 {string} string "Bad Request"
// @Failure 500 {string} string "Internal Server Error"
// @Security BearerAuth
// @Router /api/v1/admin/cpanel/emails/{email}/password [put]
func (h *Handler) ChangePassword(w http.ResponseWriter, r *http.Request) {
email := r.PathValue("email")
if email == "" {
http.Error(w, "Email is required", http.StatusBadRequest)
return
}
var req ChangePasswordRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if req.Password == "" {
http.Error(w, "Password is required", http.StatusBadRequest)
return
}
if err := h.client.ChangePassword(email, req.Password); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"message": "Password changed successfully",
})
}
// UpdateQuota godoc
// @Summary Update Email Quota
// @Description Updates the disk quota for an email account
// @Tags Admin - cPanel
// @Accept json
// @Produce json
// @Param email path string true "Email address"
// @Param body body UpdateQuotaRequest true "New quota in MB"
// @Success 200 {object} map[string]string
// @Failure 400 {string} string "Bad Request"
// @Failure 500 {string} string "Internal Server Error"
// @Security BearerAuth
// @Router /api/v1/admin/cpanel/emails/{email}/quota [put]
func (h *Handler) UpdateQuota(w http.ResponseWriter, r *http.Request) {
email := r.PathValue("email")
if email == "" {
http.Error(w, "Email is required", http.StatusBadRequest)
return
}
var req UpdateQuotaRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if err := h.client.UpdateQuota(email, req.Quota); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"message": "Quota updated successfully",
})
}