package user import ( "clickandjoin.app/storageserver/modules/image" "clickandjoin.app/storageserver/modules/scylladb" "clickandjoin.app/storageserver/modules/structs" "clickandjoin.app/storageserver/modules/utils" gocnjhelper "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper" "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper/cnjglobals" "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper/dbstructs" "github.com/gofiber/fiber/v2" "github.com/google/uuid" ) 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/utils/definitions.go#L21 // 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) != cnjglobals.LenUserId { gocnjhelper.LogDebug("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) > utils.MaxFileNameLen { gocnjhelper.LogDebug("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 := cnjglobals.GetAuhorizationToken(c) if len(xAuthorization) != cnjglobals.LenXAuthorizationHeader { return c.SendStatus(fiber.StatusUnauthorized) } foundSession := dbstructs.UserSession{Id: xAuthorization} q := scylladb.Session.Query(gocnjhelper.DbMSessions.Get("user_id")).BindStruct(foundSession) if err := q.GetRelease(&foundSession); err != nil { gocnjhelper.LogErrorf("Failed to get user session, err: %s", err) return c.SendStatus(fiber.StatusUnauthorized) } file, err := c.FormFile(utils.FormFileKey) if err != nil { gocnjhelper.LogErrorf("Failed to get form file, err: %s", err) return c.SendStatus(fiber.StatusBadRequest) } if file.Size > utils.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, utils.ImageSizes[utils.DefaultImageSize], utils.ImageSizes[utils.DefaultImageSize], 40) if err != nil { return c.SendStatus(fiber.StatusInternalServerError) } avatarUrl := utils.GetUserAvatarUrl(foundSession.UserId, fileName) user := dbstructs.User{Id: foundSession.UserId, AvatarUrl: avatarUrl} q = scylladb.Session.Query(gocnjhelper.DbMUsers.Update("avatar_url")).BindStruct(user) if err := q.ExecRelease(); err != nil { gocnjhelper.LogErrorf("Failed to update user avatar url, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } return c.Status(fiber.StatusOK).JSON(structs.UpdatedUserAvatarResponse{AvatarUrl: avatarUrl}) }