StorageServer/routers/v1/user/useravatar.go

154 lines
4.2 KiB
Go

package user
import (
"clickandjoin.app/storageserver/modules/image"
"clickandjoin.app/storageserver/modules/scylladb"
"clickandjoin.app/storageserver/modules/structs"
"clickandjoin.app/storageserver/modules/utils"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
func GetAvatar(c *fiber.Ctx) error {
// swagger:operation GET /avatars/:userId/:fileName avatars avatarsGetAvatar
// ---
// summary: Get avatar from a user
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: size
// in: query
// description: Size can be specified as query to influence the size of the image. Available sizes https://git.clickandjoin.umbach.dev/ClickandJoin/StorageServer/src/branch/alpha/modules/image/image.go#L28
// responses:
// '200':
// description: Avatar from user
// '400':
// description: Avatar does not exist
// '422':
// description: Invalid userId or fileName
userId := c.Params("userId")
if len(userId) != structs.LenUserId {
logrus.Debugln("UserId is longer than allowed")
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
fileName := c.Params("fileName")
// check if the filename length has not been manipulated by the user
if len(fileName) > image.MaxFileNameLen {
logrus.Debugln("Filename is longer than allowed")
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
// image resolution
size := c.Query("size")
img, err := image.GetImage(userId, fileName, size)
if err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
c.Context().SetContentType("image/webp")
return c.Send(img)
}
func UpdateAvatar(c *fiber.Ctx) error {
// swagger:operation POST /user/avatar user userUpdateAvatar
// ---
// summary: Update avatar of a user
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: X-Authorization
// in: header
// required: true
// - name: file
// in: formData
// description: New avatar
// required: true
// responses:
// '200':
// description: Updated user avatar
// schema:
// "$ref": "#/definitions/UpdatedUserAvatarResponse"
// '400':
// description: Invalid FormData
// '401':
// description: Invalid X-Authorization token
// '415':
// description: Image format is not supported
// '422':
// description: Avatar size too large
// '500':
// description: Internal server error
xAuthorization := utils.GetAuhorizationToken(c)
if len(xAuthorization) != structs.LenXAuthorizationToken {
return c.SendStatus(fiber.StatusUnauthorized)
}
foundSession := structs.UserSession{Id: xAuthorization}
q := scylladb.Session.Query(scylladb.Sessions.Get("user_id")).BindStruct(foundSession)
if err := q.GetRelease(&foundSession); err != nil {
logrus.Errorln("Failed to get user session, err:", err)
return c.SendStatus(fiber.StatusUnauthorized)
}
file, err := c.FormFile(image.FormFileKey)
if err != nil {
logrus.Errorln("Failed to get form file, err:", err)
return c.SendStatus(fiber.StatusBadRequest)
}
if file.Size > image.MaxAvatarSize {
return c.SendStatus(fiber.StatusRequestEntityTooLarge)
}
if valid := image.FileTypeVerification(file.Header.Get("Content-Type")); !valid {
return c.SendStatus(fiber.StatusUnsupportedMediaType)
}
if err = image.DeleteOldAvatarImage(foundSession.UserId); err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
fileName := uuid.New().String()
err = image.SaveImage(
file,
foundSession.UserId,
utils.GetUserStoragePath(foundSession.UserId)+fileName,
image.ImageSizes[image.DefaultImageSize],
image.ImageSizes[image.DefaultImageSize],
40)
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
avatarUrl := utils.GetUserAvatarUrl(foundSession.UserId, fileName)
user := structs.User{Id: foundSession.UserId, AvatarUrl: avatarUrl}
q = scylladb.Session.Query(scylladb.Users.Update("avatar_url")).BindStruct(user)
if err := q.ExecRelease(); err != nil {
logrus.Errorln("Failed to update user avatar url, err:", err)
return c.SendStatus(fiber.StatusInternalServerError)
}
return c.Status(fiber.StatusOK).JSON(structs.UpdatedUserAvatarResponse{AvatarUrl: avatarUrl})
}