uploadInterceptor.go (2546B)
1 package interceptors 2 3 import ( 4 "dkforest/pkg/config" 5 "dkforest/pkg/database" 6 "dkforest/pkg/utils" 7 "dkforest/pkg/web/handlers/interceptors/command" 8 hutils "dkforest/pkg/web/handlers/utils" 9 "errors" 10 "fmt" 11 "github.com/asaskevich/govalidator" 12 "github.com/dustin/go-humanize" 13 "github.com/sirupsen/logrus" 14 "io" 15 "mime/multipart" 16 ) 17 18 type UploadInterceptor struct{} 19 20 func (i UploadInterceptor) InterceptMsg(cmd *command.Command) { 21 if file, handler, uploadErr := cmd.C.Request().FormFile("file"); uploadErr == nil { 22 // Save file on disk & database & append file link to html 23 var err error 24 cmd.Upload, err = handleUploadedFile(cmd.DB, file, handler, cmd.AuthUser) 25 if err != nil { 26 cmd.Err = err 27 return 28 } 29 } 30 } 31 32 func handleUploadedFile(db *database.DkfDB, file multipart.File, handler *multipart.FileHeader, authUser *database.User) (*database.Upload, error) { 33 defer file.Close() 34 if !authUser.CanUpload() { 35 return nil, hutils.AccountTooYoungErr 36 } 37 userSizeUploaded := db.GetUserTotalUploadSize(authUser.ID) 38 if handler.Size+userSizeUploaded > config.MaxUserTotalUploadSize { 39 return nil, fmt.Errorf("user upload limit reached (%s)", humanize.Bytes(config.MaxUserTotalUploadSize)) 40 } 41 origFileName := handler.Filename 42 if handler.Size > config.MaxUserFileUploadSize { 43 return nil, fmt.Errorf("the maximum file size is %s", humanize.Bytes(config.MaxUserFileUploadSize)) 44 } 45 if !govalidator.StringLength(origFileName, "3", "50") { 46 return nil, errors.New("invalid file name, 3-50 characters") 47 } 48 if !govalidator.IsPrintableASCII(origFileName) { 49 return nil, errors.New("file name must be ascii printable only") 50 } 51 origFileName = tzRgx.ReplaceAllString(origFileName, "xxxx-xx-xx at xx.xx.xx XX") 52 origFileName = tz1Rgx.ReplaceAllString(origFileName, "xxxx-xx-xx xx-xx-xx") 53 origFileName = tz3Rgx.ReplaceAllString(origFileName, "xxxx-xx-xx xxxxxx") 54 origFileName = tz4Rgx.ReplaceAllString(origFileName, "xxxx-xx-xx_xx_xx_xx") 55 fileBytes, err := io.ReadAll(file) 56 if err != nil { 57 return nil, err 58 } 59 60 // Validate image type and determine extension 61 mimeType := handler.Header.Get("Content-Type") 62 if mimeType == "image/jpeg" { 63 fileBytes, err = utils.ReencodeJpg(fileBytes) 64 } else if mimeType == "image/png" { 65 fileBytes, err = utils.ReencodePng(fileBytes) 66 } 67 if err != nil { 68 return nil, err 69 } 70 71 // Uploaded files are encrypted on disk 72 upload, err := db.CreateEncryptedUploadWithSize(origFileName, fileBytes, authUser.ID, handler.Size) 73 if err != nil { 74 logrus.Error(err) 75 return nil, err 76 } 77 return upload, nil 78 }