the beginning of the idiots
This commit is contained in:
638
qwen/go/handlers/handlers.go
Normal file
638
qwen/go/handlers/handlers.go
Normal file
@@ -0,0 +1,638 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"mohportal/middleware"
|
||||
"mohportal/models"
|
||||
"mohportal/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var (
|
||||
tenantService *services.TenantService
|
||||
userService *services.UserService
|
||||
positionService *services.PositionService
|
||||
resumeService *services.ResumeService
|
||||
applicationService *services.ApplicationService
|
||||
)
|
||||
|
||||
// Initialize services
|
||||
func init() {
|
||||
tenantService = &services.TenantService{}
|
||||
userService = &services.UserService{}
|
||||
positionService = &services.PositionService{}
|
||||
resumeService = &services.ResumeService{}
|
||||
applicationService = &services.ApplicationService{}
|
||||
}
|
||||
|
||||
// HealthCheck returns the health status of the application
|
||||
func HealthCheck(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "healthy",
|
||||
"message": "MerchantsOfHope.org recruiting platform is running",
|
||||
"service": "MOH Portal API",
|
||||
})
|
||||
}
|
||||
|
||||
// Tenant Handlers
|
||||
func CreateTenant(c *gin.Context) {
|
||||
var req struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Slug string `json:"slug" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
LogoURL string `json:"logo_url"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
tenant, err := tenantService.CreateTenant(req.Name, req.Slug, req.Description, req.LogoURL)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, tenant)
|
||||
}
|
||||
|
||||
func GetTenants(c *gin.Context) {
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0"))
|
||||
|
||||
tenants, err := tenantService.GetTenants(limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, tenants)
|
||||
}
|
||||
|
||||
func GetTenant(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid tenant ID"})
|
||||
return
|
||||
}
|
||||
|
||||
tenant, err := tenantService.GetTenant(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, tenant)
|
||||
}
|
||||
|
||||
func UpdateTenant(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid tenant ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
Description string `json:"description"`
|
||||
LogoURL string `json:"logo_url"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
tenant, err := tenantService.UpdateTenant(id, req.Name, req.Slug, req.Description, req.LogoURL)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, tenant)
|
||||
}
|
||||
|
||||
func DeleteTenant(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid tenant ID"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := tenantService.DeleteTenant(id); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Tenant deleted successfully"})
|
||||
}
|
||||
|
||||
// Auth Handlers
|
||||
func Login(c *gin.Context) {
|
||||
var req struct {
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
user, err := userService.AuthenticateUser(req.Email, req.Password)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Generate JWT token (this is a simplified example)
|
||||
// In a real application, you'd use the jwt package to create a proper token
|
||||
|
||||
// For now, return user info with a placeholder token
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Login successful",
|
||||
"user": user,
|
||||
"token": "placeholder_token", // In real implementation, return actual JWT
|
||||
})
|
||||
}
|
||||
|
||||
func Register(c *gin.Context) {
|
||||
var req struct {
|
||||
TenantID string `json:"tenant_id" binding:"required"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
FirstName string `json:"first_name" binding:"required"`
|
||||
LastName string `json:"last_name" binding:"required"`
|
||||
Phone string `json:"phone"`
|
||||
Role string `json:"role" binding:"required"`
|
||||
Password string `json:"password" binding:"required,min=8"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
tenantID, err := uuid.Parse(req.TenantID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid tenant ID"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate role
|
||||
if !models.ValidRole(req.Role) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid role"})
|
||||
return
|
||||
}
|
||||
|
||||
user, err := userService.CreateUser(tenantID, req.Email, req.Username, req.FirstName, req.LastName, req.Phone, req.Role, req.Password)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"message": "User registered successfully",
|
||||
"user": user,
|
||||
})
|
||||
}
|
||||
|
||||
func Logout(c *gin.Context) {
|
||||
middleware.LogoutHandler(c) // This will handle the response
|
||||
}
|
||||
|
||||
func Profile(c *gin.Context) {
|
||||
// Get user from context (set by auth middleware)
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user": user,
|
||||
})
|
||||
}
|
||||
|
||||
// OIDC/Social Media Login
|
||||
func OIDCLogin(c *gin.Context) {
|
||||
middleware.OIDCLoginHandler(c) // This will redirect the user
|
||||
}
|
||||
|
||||
func OIDCCallback(c *gin.Context) {
|
||||
middleware.OIDCCallbackHandler(c) // This will handle the callback
|
||||
}
|
||||
|
||||
func SocialLogin(c *gin.Context) {
|
||||
middleware.SocialLoginHandler(c) // This will redirect the user
|
||||
}
|
||||
|
||||
func SocialCallback(c *gin.Context) {
|
||||
middleware.SocialCallbackHandler(c) // This will handle the callback
|
||||
}
|
||||
|
||||
// Position Handlers
|
||||
func GetPositions(c *gin.Context) {
|
||||
// Parse query parameters
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0"))
|
||||
status := c.Query("status")
|
||||
employmentType := c.Query("employment_type")
|
||||
experienceLevel := c.Query("experience_level")
|
||||
location := c.Query("location")
|
||||
|
||||
// Parse tenant ID if provided
|
||||
var tenantID *uuid.UUID
|
||||
if tenantStr := c.Query("tenant_id"); tenantStr != "" {
|
||||
id, err := uuid.Parse(tenantStr)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid tenant ID"})
|
||||
return
|
||||
}
|
||||
tenantID = &id
|
||||
}
|
||||
|
||||
positions, err := positionService.GetPositions(tenantID, limit, offset, status, employmentType, experienceLevel, location)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, positions)
|
||||
}
|
||||
|
||||
func GetPosition(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid position ID"})
|
||||
return
|
||||
}
|
||||
|
||||
position, err := positionService.GetPosition(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, position)
|
||||
}
|
||||
|
||||
func CreatePosition(c *gin.Context) {
|
||||
// Get user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
userData, ok := user.(models.User)
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error getting user data"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Title string `json:"title" binding:"required"`
|
||||
Description string `json:"description" binding:"required"`
|
||||
Requirements string `json:"requirements"`
|
||||
Location string `json:"location"`
|
||||
EmploymentType string `json:"employment_type" binding:"required"`
|
||||
SalaryMin *float64 `json:"salary_min"`
|
||||
SalaryMax *float64 `json:"salary_max"`
|
||||
ExperienceLevel string `json:"experience_level" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate employment type
|
||||
if !models.ValidEmploymentType(req.EmploymentType) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid employment type"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate experience level
|
||||
if !models.ValidExperienceLevel(req.ExperienceLevel) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid experience level"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate salary range
|
||||
if req.SalaryMin != nil && req.SalaryMax != nil && *req.SalaryMin > *req.SalaryMax {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Minimum salary cannot be greater than maximum salary"})
|
||||
return
|
||||
}
|
||||
|
||||
position, err := positionService.CreatePosition(userData.TenantID, userData.ID, req.Title, req.Description, req.Requirements, req.Location, req.EmploymentType, req.ExperienceLevel, req.SalaryMin, req.SalaryMax)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, position)
|
||||
}
|
||||
|
||||
func UpdatePosition(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid position ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Title string `json:"title" binding:"required"`
|
||||
Description string `json:"description" binding:"required"`
|
||||
Requirements string `json:"requirements"`
|
||||
Location string `json:"location"`
|
||||
EmploymentType string `json:"employment_type" binding:"required"`
|
||||
SalaryMin *float64 `json:"salary_min"`
|
||||
SalaryMax *float64 `json:"salary_max"`
|
||||
ExperienceLevel string `json:"experience_level" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate employment type
|
||||
if !models.ValidEmploymentType(req.EmploymentType) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid employment type"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate experience level
|
||||
if !models.ValidExperienceLevel(req.ExperienceLevel) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid experience level"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate salary range
|
||||
if req.SalaryMin != nil && req.SalaryMax != nil && *req.SalaryMin > *req.SalaryMax {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Minimum salary cannot be greater than maximum salary"})
|
||||
return
|
||||
}
|
||||
|
||||
position, err := positionService.UpdatePosition(id, req.Title, req.Description, req.Requirements, req.Location, req.EmploymentType, req.ExperienceLevel, req.SalaryMin, req.SalaryMax)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, position)
|
||||
}
|
||||
|
||||
func DeletePosition(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid position ID"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := positionService.DeletePosition(id); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Position deleted successfully"})
|
||||
}
|
||||
|
||||
// Application Handlers
|
||||
func GetApplications(c *gin.Context) {
|
||||
// Parse query parameters
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0"))
|
||||
status := c.Query("status")
|
||||
|
||||
// Parse user ID if provided
|
||||
var userID *uuid.UUID
|
||||
if userStr := c.Query("user_id"); userStr != "" {
|
||||
id, err := uuid.Parse(userStr)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
||||
return
|
||||
}
|
||||
userID = &id
|
||||
}
|
||||
|
||||
// Parse position ID if provided
|
||||
var positionID *uuid.UUID
|
||||
if positionStr := c.Query("position_id"); positionStr != "" {
|
||||
id, err := uuid.Parse(positionStr)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid position ID"})
|
||||
return
|
||||
}
|
||||
positionID = &id
|
||||
}
|
||||
|
||||
applications, err := applicationService.GetApplications(userID, positionID, status, limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, applications)
|
||||
}
|
||||
|
||||
func GetApplication(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid application ID"})
|
||||
return
|
||||
}
|
||||
|
||||
application, err := applicationService.GetApplication(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, application)
|
||||
}
|
||||
|
||||
func CreateApplication(c *gin.Context) {
|
||||
// Get user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
userData, ok := user.(models.User)
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error getting user data"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
PositionID string `json:"position_id" binding:"required"`
|
||||
ResumeID string `json:"resume_id"`
|
||||
CoverLetter string `json:"cover_letter"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
positionID, err := uuid.Parse(req.PositionID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid position ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var resumeID *uuid.UUID
|
||||
if req.ResumeID != "" {
|
||||
id, err := uuid.Parse(req.ResumeID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid resume ID"})
|
||||
return
|
||||
}
|
||||
resumeID = &id
|
||||
}
|
||||
|
||||
application, err := applicationService.CreateApplication(positionID, userData.ID, resumeID, req.CoverLetter)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, application)
|
||||
}
|
||||
|
||||
func UpdateApplication(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid application ID"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get reviewer user from context
|
||||
reviewer, exists := c.Get("user")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
reviewerData, ok := reviewer.(models.User)
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error getting user data"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Status string `json:"status" binding:"required"`
|
||||
Notes string `json:"notes"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate status
|
||||
if !models.ValidStatus(req.Status) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid status"})
|
||||
return
|
||||
}
|
||||
|
||||
application, err := applicationService.UpdateApplication(id, req.Status, reviewerData.ID, req.Notes)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, application)
|
||||
}
|
||||
|
||||
func DeleteApplication(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid application ID"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := applicationService.DeleteApplication(id); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Application deleted successfully"})
|
||||
}
|
||||
|
||||
// Resume Handlers
|
||||
func UploadResume(c *gin.Context) {
|
||||
// Get user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
userData, ok := user.(models.User)
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error getting user data"})
|
||||
return
|
||||
}
|
||||
|
||||
title := c.PostForm("title")
|
||||
if title == "" {
|
||||
title = "Resume"
|
||||
}
|
||||
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "File upload failed"})
|
||||
return
|
||||
}
|
||||
|
||||
resume, err := resumeService.UploadResume(userData.ID, file, title)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, resume)
|
||||
}
|
||||
|
||||
func GetResume(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid resume ID"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
userData, ok := user.(models.User)
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error getting user data"})
|
||||
return
|
||||
}
|
||||
|
||||
resume, err := resumeService.GetResume(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure the user owns the resume
|
||||
if resume.UserID != userData.ID {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "Access denied"})
|
||||
return
|
||||
}
|
||||
|
||||
// Serve the file
|
||||
c.File(resume.FilePath)
|
||||
}
|
||||
Reference in New Issue
Block a user