imc-vibe/backend/internal/api/handlers/aliases.go
2026-03-21 22:41:23 +01:00

160 lines
3.6 KiB
Go

package handlers
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"github.com/imc-vibe/backend/internal/db"
)
type AliasHandler struct {
db *db.DB
}
func NewAliasHandler(database *db.DB) *AliasHandler {
return &AliasHandler{db: database}
}
type CreateAliasRequest struct {
Source string `json:"source"`
Destination string `json:"destination"`
}
func (h *AliasHandler) List(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
Error(w, http.StatusMethodNotAllowed, "method not allowed")
return
}
domainName := extractDomainNameFromPath(r.URL.Path)
if domainName == "" {
Error(w, http.StatusBadRequest, "domain name required")
return
}
authCtx := GetAuthContext(r)
if authCtx == nil {
Error(w, http.StatusUnauthorized, "authentication required")
return
}
canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin())
if !canAccess {
Error(w, http.StatusForbidden, "access denied")
return
}
domain, err := h.db.GetDomainByName(domainName)
if err != nil {
Error(w, http.StatusNotFound, "domain not found")
return
}
aliases, err := h.db.GetAliasesByDomain(domain.ID)
if err != nil {
Error(w, http.StatusInternalServerError, "database error")
return
}
Success(w, aliases)
}
func (h *AliasHandler) Create(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
Error(w, http.StatusMethodNotAllowed, "method not allowed")
return
}
domainName := extractDomainNameFromPath(r.URL.Path)
if domainName == "" {
Error(w, http.StatusBadRequest, "domain name required")
return
}
authCtx := GetAuthContext(r)
if authCtx == nil {
Error(w, http.StatusUnauthorized, "authentication required")
return
}
canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin())
if !canAccess {
Error(w, http.StatusForbidden, "access denied")
return
}
domain, err := h.db.GetDomainByName(domainName)
if err != nil {
Error(w, http.StatusNotFound, "domain not found")
return
}
var req CreateAliasRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
Error(w, http.StatusBadRequest, "invalid request body")
return
}
if req.Source == "" || req.Destination == "" {
Error(w, http.StatusBadRequest, "source and destination required")
return
}
alias, err := h.db.CreateAliasInDomain(req.Source, req.Destination, domain.ID)
if err != nil {
Error(w, http.StatusInternalServerError, "failed to create alias")
return
}
Created(w, alias)
}
func (h *AliasHandler) Delete(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodDelete {
Error(w, http.StatusMethodNotAllowed, "method not allowed")
return
}
pathParts := strings.Split(r.URL.Path, "/")
var domainName, idStr string
for i, part := range pathParts {
if part == "domains" && i+1 < len(pathParts) {
domainName = pathParts[i+1]
}
if part == "aliases" && i+1 < len(pathParts) {
idStr = pathParts[i+1]
}
}
if domainName == "" || idStr == "" {
Error(w, http.StatusBadRequest, "invalid path")
return
}
authCtx := GetAuthContext(r)
if authCtx == nil {
Error(w, http.StatusUnauthorized, "authentication required")
return
}
canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin())
if !canAccess {
Error(w, http.StatusForbidden, "access denied")
return
}
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
Error(w, http.StatusBadRequest, "invalid alias id")
return
}
if err := h.db.DeleteAlias(uint(id)); err != nil {
Error(w, http.StatusInternalServerError, "failed to delete alias")
return
}
NoContent(w)
}