aurganize-backend/backend/internal/handlers/tenant_handler.go

158 lines
4.8 KiB
Go

package handlers
import (
"net/http"
"github.com/creativenoz/aurganize-v62/backend/internal/services"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
)
type TenantHandler struct {
tenantService *services.TenantService
}
func NewTenantHanlder(tenantService *services.TenantService) *TenantHandler {
log.Info().
Str("handler", "tenant").
Str("component", "handler_init").
Msg("tenant handler initialized")
return &TenantHandler{
tenantService: tenantService,
}
}
func (th *TenantHandler) GetTenant(c echo.Context) error {
rawTenantId := c.Param("id")
log.Info().
Str("handler", "tenant").
Str("action", "get_tenant_attempt").
Str("tenant_id", rawTenantId).
Str("ip", c.RealIP()).
Msg("attempting to get tenant by id")
tenantId, err := uuid.Parse(rawTenantId)
if err != nil {
log.Warn().
Str("handler", "tenant").
Str("action", "invalid_tenant_id_format").
Str("invalid_id", rawTenantId).
Str("ip", c.RealIP()).
Err(err).
Msg("failed to parse tenant id - invalid uuid format")
return echo.NewHTTPError(http.StatusBadRequest, "invalid tenant id")
}
ctx := c.Request().Context()
log.Debug().
Str("handler", "tenant").
Str("action", "fetching_tenant_from_service").
Str("tenant_id", tenantId.String()).
Msg("querying tenant service for tenant data")
tenant, err := th.tenantService.GetByID(ctx, tenantId)
if err != nil {
log.Warn().
Str("handler", "tenant").
Str("action", "tenant_not_found").
Str("tenant_id", tenantId.String()).
Str("ip", c.RealIP()).
Err(err).
Msg("tenant not found in database")
return echo.NewHTTPError(http.StatusNotFound, "tenant not found")
}
log.Debug().
Str("handler", "tenant").
Str("action", "checking_tenant_authorization").
Str("tenant_id", tenant.ID.String()).
Str("tenant_name", tenant.Name).
Msg("tenant found, verifying user authorization")
userTenantId, ok := c.Get("tenant_id").(uuid.UUID)
if !ok {
log.Error().
Str("handler", "tenant").
Str("action", "missing_user_tenant_context").
Interface("context_value", c.Get("tenant_id")).
Str("ip", c.RealIP()).
Msg("user tenant id missing or invalid in request context - middleware issue")
return echo.NewHTTPError(http.StatusBadRequest, "invalid user tenant id")
}
log.Debug().
Str("handler", "tenant").
Str("action", "tenant_authorization_check").
Str("requested_tenant_id", tenant.ID.String()).
Str("user_tenant_id", userTenantId.String()).
Bool("match", tenant.ID == userTenantId).
Msg("comparing requested tenant with user's tenant")
if tenant.ID != userTenantId {
log.Warn().
Str("handler", "tenant").
Str("action", "tenant_access_denied").
Str("requested_tenant_id", tenant.ID.String()).
Str("user_tenant_id", userTenantId.String()).
Str("requested_tenant_name", tenant.Name).
Str("ip", c.RealIP()).
Str("user_agent", c.Request().UserAgent()).
Msg("access denied - user attempted to access different tenant")
return echo.NewHTTPError(http.StatusForbidden, "acces denied")
}
log.Info().
Str("handler", "tenant").
Str("action", "get_tenant_success").
Str("tenant_id", tenant.ID.String()).
Str("tenant_name", tenant.Name).
Str("user_tenant_id", userTenantId.String()).
Str("ip", c.RealIP()).
Msg("tenant retrieved successfully")
return c.JSON(http.StatusOK, tenant.ToResponse())
}
func (th *TenantHandler) GetMyTenant(c echo.Context) error {
log.Info().
Str("handler", "tenant").
Str("action", "get_my_tenant_attempt").
Str("ip", c.RealIP()).
Msg("user requesting their own tenant information")
tenantID, ok := c.Get("tenant_id").(uuid.UUID)
if !ok {
log.Error().
Str("handler", "tenant").
Str("action", "get_my_tenant_missing_context").
Interface("context_value", c.Get("tenant_id")).
Str("ip", c.RealIP()).
Msg("tenant id missing from authenticated request context - authentication issue")
return echo.NewHTTPError(http.StatusBadRequest, "invalid tenant id")
}
log.Debug().
Str("handler", "tenant").
Str("action", "fetching_my_tenant_from_service").
Str("tenant_id", tenantID.String()).
Msg("querying tenant service for user's tenant")
ctx := c.Request().Context()
tenant, err := th.tenantService.GetByID(ctx, tenantID)
if err != nil {
log.Error().
Str("handler", "tenant").
Str("action", "my_tenant_not_found").
Str("tenant_id", tenantID.String()).
Str("ip", c.RealIP()).
Err(err).
Msg("CRITICAL: user's tenant not found in database - data consistency issue")
return echo.NewHTTPError(http.StatusInternalServerError, "failed to retrieve tenant")
}
log.Info().
Str("handler", "tenant").
Str("action", "get_my_tenant_success").
Str("tenant_id", tenant.ID.String()).
Str("tenant_name", tenant.Name).
Str("ip", c.RealIP()).
Msg("user's tenant retrieved successfully")
return c.JSON(http.StatusOK, tenant.ToResponse())
}