From 26c7ceaed4807b94dae02cd81dc4257537dd936a Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 18 Mar 2025 18:08:09 +0100 Subject: [PATCH] chore(avatar): decouple upload from web handler --- pkg/modules/avatar/upload/upload.go | 40 ++++++++++++++++++++++ pkg/routes/api/v1/avatar.go | 51 +++-------------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/pkg/modules/avatar/upload/upload.go b/pkg/modules/avatar/upload/upload.go index 34349d4fb..327db6cef 100644 --- a/pkg/modules/avatar/upload/upload.go +++ b/pkg/modules/avatar/upload/upload.go @@ -29,6 +29,7 @@ import ( "code.vikunja.io/api/pkg/user" "github.com/disintegration/imaging" + "xorm.io/xorm" ) // Provider represents the upload avatar provider @@ -111,3 +112,42 @@ func InvalidateCache(u *user.User) { log.Errorf("Could not invalidate upload avatar cache for user %d, error was %s", u.ID, err) } } + +func StoreAvatarFile(s *xorm.Session, u *user.User, src io.Reader) (err error) { + + // Remove the old file if one exists + if u.AvatarFileID != 0 { + f := &files.File{ID: u.AvatarFileID} + if err := f.Delete(s); err != nil { + if !files.IsErrFileDoesNotExist(err) { + return err + } + } + u.AvatarFileID = 0 + } + + // Resize the new file to a max height of 1024 + img, _, err := image.Decode(src) + if err != nil { + return + } + resizedImg := imaging.Resize(img, 0, 1024, imaging.Lanczos) + buf := &bytes.Buffer{} + err = png.Encode(buf, resizedImg) + if err != nil { + return + } + + InvalidateCache(u) + + // Save the file + f, err := files.CreateWithMime(buf, "avatar.png", uint64(buf.Len()), u, "image/png") + if err != nil { + return err + } + + u.AvatarFileID = f.ID + + _, err = user.UpdateUser(s, u, false) + return +} diff --git a/pkg/routes/api/v1/avatar.go b/pkg/routes/api/v1/avatar.go index 137e583a2..b59e7ef65 100644 --- a/pkg/routes/api/v1/avatar.go +++ b/pkg/routes/api/v1/avatar.go @@ -19,27 +19,23 @@ package v1 import ( "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/db" - "code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/modules/avatar" "code.vikunja.io/api/pkg/modules/avatar/empty" "code.vikunja.io/api/pkg/modules/avatar/gravatar" "code.vikunja.io/api/pkg/modules/avatar/initials" + "code.vikunja.io/api/pkg/modules/avatar/ldap" "code.vikunja.io/api/pkg/modules/avatar/marble" "code.vikunja.io/api/pkg/modules/avatar/upload" "code.vikunja.io/api/pkg/user" "code.vikunja.io/api/pkg/web/handler" - "bytes" - "image" - "image/png" "io" "net/http" "strconv" "strings" - "github.com/disintegration/imaging" "github.com/gabriel-vasile/mimetype" "github.com/labstack/echo/v4" ) @@ -81,6 +77,8 @@ func GetAvatar(c echo.Context) error { avatarProvider = &upload.Provider{} case "marble": avatarProvider = &marble.Provider{} + case "ldap": + avatarProvider = &ldap.Provider{} default: avatarProvider = &empty.Provider{} } @@ -164,48 +162,9 @@ func UploadAvatar(c echo.Context) (err error) { } _, _ = src.Seek(0, io.SeekStart) - // Remove the old file if one exists - if u.AvatarFileID != 0 { - f := &files.File{ID: u.AvatarFileID} - if err := f.Delete(s); err != nil { - if !files.IsErrFileDoesNotExist(err) { - _ = s.Rollback() - return handler.HandleHTTPError(err) - } - } - u.AvatarFileID = 0 - } - - // Resize the new file to a max height of 1024 - img, _, err := image.Decode(src) - if err != nil { - _ = s.Rollback() - return handler.HandleHTTPError(err) - } - resizedImg := imaging.Resize(img, 0, 1024, imaging.Lanczos) - buf := &bytes.Buffer{} - if err := png.Encode(buf, resizedImg); err != nil { - _ = s.Rollback() - return handler.HandleHTTPError(err) - } - - upload.InvalidateCache(u) - - // Save the file - f, err := files.CreateWithMime(buf, file.Filename, uint64(file.Size), u, "image/png") - if err != nil { - _ = s.Rollback() - if files.IsErrFileIsTooLarge(err) { - return echo.ErrBadRequest - } - - return handler.HandleHTTPError(err) - } - - u.AvatarFileID = f.ID u.AvatarProvider = "upload" - - if _, err := user.UpdateUser(s, u, false); err != nil { + err = upload.StoreAvatarFile(s, u, src) + if err != nil { _ = s.Rollback() return handler.HandleHTTPError(err) }