first commit
This commit is contained in:
193
api/handlers/avatar_handler.go
Normal file
193
api/handlers/avatar_handler.go
Normal file
@@ -0,0 +1,193 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gauth-central/internal/database"
|
||||
"gauth-central/internal/models"
|
||||
"gauth-central/pkg/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AvatarHandler struct{}
|
||||
|
||||
func NewAvatarHandler() *AvatarHandler {
|
||||
return &AvatarHandler{}
|
||||
}
|
||||
|
||||
// UploadAvatar godoc
|
||||
// @Summary Upload user avatar
|
||||
// @Tags User
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param avatar formData file true "Avatar image file"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /user/avatar [post]
|
||||
func (h *AvatarHandler) UploadAvatar(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
// Parse multipart form
|
||||
file, err := c.FormFile("avatar")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "No file uploaded"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate file size (max 5MB)
|
||||
if file.Size > 5*1024*1024 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "File size exceeds 5MB limit"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user to check for old avatar
|
||||
var user models.User
|
||||
if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete old avatar file if exists and is not from OAuth
|
||||
if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
|
||||
oldPath := "." + user.Avatar
|
||||
os.Remove(oldPath) // Ignore error if file doesn't exist
|
||||
}
|
||||
|
||||
// Use utils.SaveOptimizedImage
|
||||
avatarURL, err := utils.SaveOptimizedImage(file, "./uploads/avatars", userID, nil)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save avatar: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Update avatar URL
|
||||
if err := database.DB.Model(&user).Update("avatar", avatarURL).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update avatar"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Avatar uploaded successfully",
|
||||
"avatar_url": avatarURL,
|
||||
"user": gin.H{
|
||||
"id": user.ID,
|
||||
"username": user.UserName,
|
||||
"email": user.Email,
|
||||
"avatar": avatarURL,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteAvatar godoc
|
||||
// @Summary Delete user avatar
|
||||
// @Tags User
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /user/avatar [delete]
|
||||
func (h *AvatarHandler) DeleteAvatar(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
var user models.User
|
||||
if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete avatar file if it's a local upload
|
||||
if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
|
||||
filepath := "." + user.Avatar
|
||||
os.Remove(filepath) // Ignore error if file doesn't exist
|
||||
}
|
||||
|
||||
// Set avatar to empty string
|
||||
if err := database.DB.Model(&user).Update("avatar", "").Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete avatar"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Avatar deleted successfully",
|
||||
"user": gin.H{
|
||||
"id": user.ID,
|
||||
"username": user.UserName,
|
||||
"email": user.Email,
|
||||
"avatar": "",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// AdminUploadAvatar godoc
|
||||
// @Summary Upload avatar for any user (Admin only)
|
||||
// @Tags Admin - User Management
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param id path string true "User ID"
|
||||
// @Param avatar formData file true "Avatar image file"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /admin/users/{id}/avatar [post]
|
||||
func (h *AvatarHandler) AdminUploadAvatar(c *gin.Context) {
|
||||
userID := c.Param("id")
|
||||
|
||||
// Parse multipart form
|
||||
file, err := c.FormFile("avatar")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "No file uploaded"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate file size (max 5MB)
|
||||
if file.Size > 5*1024*1024 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "File size exceeds 5MB limit"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user to check for old avatar
|
||||
var user models.User
|
||||
if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete old avatar file if exists and is not from OAuth
|
||||
if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
|
||||
oldPath := "." + user.Avatar
|
||||
os.Remove(oldPath) // Ignore error if file doesn't exist
|
||||
}
|
||||
|
||||
// Use utils.SaveOptimizedImage
|
||||
avatarURL, err := utils.SaveOptimizedImage(file, "./uploads/avatars", userID, nil)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save avatar: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Update avatar URL
|
||||
if err := database.DB.Model(&user).Update("avatar", avatarURL).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update avatar"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Avatar uploaded successfully",
|
||||
"avatar_url": avatarURL,
|
||||
"user": gin.H{
|
||||
"id": user.ID,
|
||||
"username": user.UserName,
|
||||
"email": user.Email,
|
||||
"avatar": avatarURL,
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user