package handlers import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/imc-vibe/backend/internal/db" ) type DomainHandler struct { db *db.DB } func NewDomainHandler(database *db.DB) *DomainHandler { return &DomainHandler{db: database} } type CreateDomainRequest struct { Name string `json:"name" binding:"required"` } type DomainPermissions struct { DomainID uint `json:"domainId"` DomainName string `json:"domainName"` UserID uint `json:"userId"` CanManage bool `json:"canManage"` } func (h *DomainHandler) List(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil { Error(c, http.StatusUnauthorized, "authentication required") return } isAdmin := authCtx.IsAdmin() domains, err := h.db.GetUserAccessibleDomains(authCtx.UserID, isAdmin) if err != nil { Error(c, http.StatusInternalServerError, "database error") return } domainStats := make([]db.DomainStats, len(domains)) for i, d := range domains { var userCount, aliasCount int64 h.db.Model(&db.User{}).Where("domain_id = ?", d.ID).Count(&userCount) h.db.Model(&db.Alias{}).Where("domain_id = ?", d.ID).Count(&aliasCount) domainStats[i] = db.DomainStats{ ID: d.ID, Name: d.Name, UserCount: userCount, AliasCount: aliasCount, } } Success(c, domainStats) } func (h *DomainHandler) Get(c *gin.Context) { domainName := c.Param("name") if domainName == "" { Error(c, http.StatusBadRequest, "domain name required") return } domain, err := h.db.GetDomainByName(domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } authCtx := GetAuthContext(c) if authCtx == nil { Error(c, http.StatusUnauthorized, "authentication required") return } canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return } Success(c, domain) } func (h *DomainHandler) Create(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil || !authCtx.IsAdmin() { Error(c, http.StatusForbidden, "admin access required") return } var req CreateDomainRequest if err := c.ShouldBindJSON(&req); err != nil { Error(c, http.StatusBadRequest, "invalid request body") return } existing, err := h.db.GetDomainByName(req.Name) if err == nil && existing != nil { Error(c, http.StatusConflict, "domain already exists") return } domain, err := h.db.CreateDomain(req.Name) if err != nil { Error(c, http.StatusInternalServerError, "failed to create domain") return } Created(c, domain) } func (h *DomainHandler) Delete(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil || !authCtx.IsAdmin() { Error(c, http.StatusForbidden, "admin access required") return } domainName := c.Param("name") if domainName == "" { Error(c, http.StatusBadRequest, "domain name required") return } domain, err := h.db.GetDomainByName(domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } if err := h.db.DeleteDomain(domain.ID); err != nil { Error(c, http.StatusInternalServerError, "failed to delete domain") return } NoContent(c) } func (h *DomainHandler) GetPermissions(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil { Error(c, http.StatusUnauthorized, "authentication required") return } if !authCtx.IsAdmin() { Error(c, http.StatusForbidden, "admin access required") return } domainName := c.Param("name") if domainName == "" { Error(c, http.StatusBadRequest, "domain name required") return } domain, err := h.db.GetDomainByName(domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } users, err := h.db.GetUsersForDomain(domain.ID) if err != nil { Error(c, http.StatusInternalServerError, "database error") return } permissions := make([]DomainPermissions, len(users)) for i, u := range users { permissions[i] = DomainPermissions{ DomainID: domain.ID, DomainName: domain.Name, UserID: u.ID, CanManage: true, } } Success(c, permissions) } func (h *DomainHandler) AddPermission(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil || !authCtx.IsAdmin() { Error(c, http.StatusForbidden, "admin access required") return } domainName := c.Param("name") if domainName == "" { Error(c, http.StatusBadRequest, "domain name required") return } domain, err := h.db.GetDomainByName(domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } var req struct { UserID uint `json:"userId" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { Error(c, http.StatusBadRequest, "invalid request") return } if err := h.db.AddUserToDomain(req.UserID, domain.ID); err != nil { Error(c, http.StatusInternalServerError, "failed to add user to domain") return } Success(c, map[string]string{"message": "user added to domain"}) } func (h *DomainHandler) RemovePermission(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil || !authCtx.IsAdmin() { Error(c, http.StatusForbidden, "admin access required") return } domainName := c.Param("name") if domainName == "" { Error(c, http.StatusBadRequest, "domain name required") return } domain, err := h.db.GetDomainByName(domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } userIDStr := c.Param("userId") userID, err := strconv.ParseUint(userIDStr, 10, 64) if err != nil { Error(c, http.StatusBadRequest, "invalid user id") return } if err := h.db.RemoveUserFromDomain(uint(userID), domain.ID); err != nil { Error(c, http.StatusInternalServerError, "failed to remove user from domain") return } NoContent(c) }