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) }