mirror of
https://github.com/notherealmarco/WASAPhoto.git
synced 2025-03-13 13:35:23 +01:00
172 lines
4.6 KiB
Go
172 lines
4.6 KiB
Go
package api
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
"github.com/notherealmarco/WASAPhoto/service/api/authorization"
|
|
"github.com/notherealmarco/WASAPhoto/service/api/helpers"
|
|
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
|
)
|
|
|
|
func (rt *_router) PostPhoto(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
|
|
|
|
// defer r.Body.Close()
|
|
|
|
uid := ps.ByName("user_id")
|
|
|
|
// send error if the user has no permission to perform this action
|
|
if !authorization.SendAuthorizationError(ctx.Auth.UserAuthorized, uid, rt.db, w, rt.baseLogger, http.StatusNotFound) {
|
|
return
|
|
}
|
|
|
|
transaction, photo_id, err := rt.db.PostPhoto(uid)
|
|
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Database error: PostPhoto", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
path := rt.dataPath + "/photos/" + uid + "/" + strconv.FormatInt(photo_id, 10) + ".jpg"
|
|
|
|
if err = os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { // perms = 511
|
|
helpers.SendInternalError(err, "Error creating directory", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
/*file, err := os.Create(path)
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Error creating file", w, rt.baseLogger)
|
|
helpers.RollbackOrLogError(transaction, rt.baseLogger)
|
|
return
|
|
}*/
|
|
|
|
bytes, err := io.ReadAll(r.Body)
|
|
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Error checking the file", w, rt.baseLogger)
|
|
helpers.RollbackOrLogError(transaction, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
mimeType := http.DetectContentType(bytes)
|
|
|
|
if !strings.HasPrefix(mimeType, "image/") {
|
|
helpers.SendStatus(http.StatusBadRequest, w, mimeType+" file is not a valid image", rt.baseLogger)
|
|
helpers.RollbackOrLogError(transaction, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
if err = os.WriteFile(path, bytes, 0644); err != nil {
|
|
helpers.SendInternalError(err, "Error writing the file", w, rt.baseLogger)
|
|
helpers.RollbackOrLogError(transaction, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
/*if err = file.Close(); err != nil {
|
|
helpers.SendInternalError(err, "Error closing file", w, rt.baseLogger)
|
|
helpers.RollbackOrLogError(transaction, rt.baseLogger)
|
|
}*/
|
|
|
|
err = transaction.Commit()
|
|
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Error committing transaction", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
helpers.SendStatus(http.StatusCreated, w, "Photo uploaded", rt.baseLogger)
|
|
}
|
|
|
|
func (rt *_router) GetPhoto(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
|
|
|
|
if !authorization.SendErrorIfNotLoggedIn(ctx.Auth.Authorized, rt.db, w, rt.baseLogger) {
|
|
// We want the user to be authenticated
|
|
return
|
|
}
|
|
|
|
uid := ps.ByName("user_id")
|
|
|
|
photo_id_str := ps.ByName("photo_id")
|
|
photo_id, err := strconv.ParseInt(photo_id_str, 10, 64)
|
|
|
|
if err != nil {
|
|
helpers.SendBadRequest(w, "Invalid photo id", rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
// This is also checking if the requesting user is banned by the author of the photo
|
|
exists, err := rt.db.PhotoExists(uid, photo_id, ctx.Auth.GetUserID())
|
|
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Database error: PhotoExists", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
if !exists {
|
|
helpers.SendNotFound(w, "Resource not found", rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
path := rt.dataPath + "/photos/" + uid + "/" + photo_id_str + ".jpg"
|
|
|
|
file, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
helpers.SendNotFound(w, "Photo not found", rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
_, err = io.Copy(w, file)
|
|
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Error writing response", w, rt.baseLogger)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (rt *_router) DeletePhoto(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
|
|
|
|
uid := ps.ByName("user_id")
|
|
photo_id := ps.ByName("photo_id")
|
|
|
|
// photo id to int64
|
|
photo_id_int, err := strconv.ParseInt(photo_id, 10, 64)
|
|
|
|
if err != nil {
|
|
helpers.SendBadRequestError(err, "Bad photo id", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
// send error if the user has no permission to perform this action (only the author can delete a photo)
|
|
if !authorization.SendAuthorizationError(ctx.Auth.UserAuthorized, uid, rt.db, w, rt.baseLogger, http.StatusNotFound) {
|
|
return
|
|
}
|
|
|
|
deleted, err := rt.db.DeletePhoto(uid, photo_id_int)
|
|
if err != nil {
|
|
helpers.SendInternalError(err, "Error deleting photo from database", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
if !deleted {
|
|
helpers.SendNotFound(w, "Photo not found", rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
path := rt.dataPath + "/photos/" + uid + "/" + photo_id + ".jpg"
|
|
|
|
if err := os.Remove(path); err != nil {
|
|
helpers.SendInternalError(err, "Error deleting file", w, rt.baseLogger)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|