dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

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 }