package handlers import ( "log" "net/http" "strconv" "adam-french.co.uk/backend/models" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" ) type CreatePostInput struct { Title string `json:"title" binding:"required"` Content string `json:"content" binding:"required"` } func (store *Store) GetPosts(ctx *gin.Context) { var posts []models.Post if err := store.DB.Preload("Author").Order("Created_At DESC").Find(&posts).Error; err != nil { log.Println(err) ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } ctx.JSON(http.StatusOK, posts) } func (store *Store) GetPost(ctx *gin.Context) { postIDStr := ctx.Param("id") postID, err := strconv.ParseUint(postIDStr, 10, 64) if err != nil { ctx.JSON(http.StatusBadRequest, "invalid id") return } post := models.Post{ID: uint(postID)} if err := store.DB.First(&post).Error; err != nil { log.Println(err) ctx.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } ctx.JSON(http.StatusOK, post) } func (store *Store) CreatePost(ctx *gin.Context) { var input CreatePostInput if err := ctx.ShouldBindBodyWithJSON(&input); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"}) return } claimsVal, ok := ctx.Get("userClaims") if !ok { ctx.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } claims, ok := claimsVal.(*jwt.MapClaims) if !ok { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } userIDF, ok := (*claims)["id"].(float64) if !ok { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } userID := uint(userIDF) // Create post post := models.Post{Title: input.Title, Content: input.Content, AuthorID: userID} tx := store.DB.Create(&post) if tx.Error != nil { log.Println(tx.Error) ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } ctx.JSON(http.StatusCreated, post) } func (store *Store) UpdatePost(ctx *gin.Context) { postID := ctx.Param("id") var post models.Post if err := store.DB.First(&post, postID).Error; err != nil { log.Println(err) ctx.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } claimsVal, ok := ctx.Get("userClaims") if !ok { ctx.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } claims, ok := claimsVal.(*jwt.MapClaims) if !ok { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } userIDF, ok := (*claims)["id"].(float64) if !ok { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } userID := uint(userIDF) if !(userID == post.AuthorID) { ctx.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } var input CreatePostInput if err := ctx.ShouldBindBodyWithJSON(&input); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"}) return } post.Title = input.Title post.Content = input.Content tx := store.DB.Save(&post) if tx.Error != nil { log.Println(tx.Error) ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } ctx.JSON(http.StatusOK, post) } func (store *Store) DeletePost(ctx *gin.Context) { postID := ctx.Param("id") var post models.Post if err := store.DB.First(&post, postID).Error; err != nil { log.Println(err) ctx.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } claimsVal, ok := ctx.Get("userClaims") if !ok { ctx.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } claims, ok := claimsVal.(*jwt.MapClaims) if !ok { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } userIDF, ok := (*claims)["id"].(float64) if !ok { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } userID := uint(userIDF) if !(userID == post.AuthorID) { ctx.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } store.DB.Delete(&post) ctx.JSON(http.StatusOK, post) }