Skip to content

Commit

Permalink
Add caching for user files
Browse files Browse the repository at this point in the history
  • Loading branch information
fossyy committed Sep 23, 2024
1 parent 1feeafe commit 59d4154
Show file tree
Hide file tree
Showing 15 changed files with 314 additions and 87 deletions.
7 changes: 7 additions & 0 deletions handler/file/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ func DELETE(w http.ResponseWriter, r *http.Request) {
return
}

err = app.Server.Service.RemoveUserFilesCache(r.Context(), userSession.UserID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

err = app.Server.Storage.Delete(r.Context(), fmt.Sprintf("%s/%s", file.OwnerID.String(), file.ID.String()))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
Expand Down
8 changes: 5 additions & 3 deletions handler/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

func GET(w http.ResponseWriter, r *http.Request) {
userSession := r.Context().Value("user").(types.User)
files, err := app.Server.Database.GetFiles(userSession.UserID.String(), "", types.All)
files, err := app.Server.Service.GetUserFiles(r.Context(), userSession.UserID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand All @@ -21,7 +21,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
var filesData []types.FileData

for _, file := range files {
userFile, err := app.Server.Service.GetUserFile(r.Context(), file.ID)
userFile, err := app.Server.Service.GetFileDetail(r.Context(), file.ID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand All @@ -37,7 +37,8 @@ func GET(w http.ResponseWriter, r *http.Request) {
app.Server.Logger.Error(err.Error())
return
}
usage, err := app.Server.Service.GetUserStorageUsage(r.Context(), userSession.UserID.String())

usage, err := app.Server.Service.CalculateUserStorageUsage(r.Context(), userSession.UserID.String())
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand All @@ -63,4 +64,5 @@ func GET(w http.ResponseWriter, r *http.Request) {
app.Server.Logger.Error(err.Error())
return
}
return
}
2 changes: 1 addition & 1 deletion handler/file/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
var filesData []types.FileData

for _, file := range files {
userFile, err := app.Server.Service.GetUserFile(r.Context(), file.ID)
userFile, err := app.Server.Service.GetFileDetail(r.Context(), file.ID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand Down
11 changes: 9 additions & 2 deletions handler/file/rename/rename.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,21 @@ func PATCH(w http.ResponseWriter, r *http.Request) {
return
}

err = app.Server.Service.DeleteFileCache(r.Context(), fileID)
err = app.Server.Service.RemoveFileCache(r.Context(), fileID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

userFile, err := app.Server.Service.GetUserFile(r.Context(), newFile.ID)
err = app.Server.Service.RemoveUserFilesCache(r.Context(), userSession.UserID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

userFile, err := app.Server.Service.GetFileDetail(r.Context(), newFile.ID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand Down
9 changes: 8 additions & 1 deletion handler/file/upload/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ func POST(w http.ResponseWriter, r *http.Request) {
app.Server.Logger.Error("error copying byte to file dst: " + err.Error())
return
}
app.Server.Service.UpdateFileChunk(r.Context(), file.ID, file.OwnerID, rawIndex, file.TotalChunk)
err = app.Server.Service.UpdateFileChunk(r.Context(), file.ID, file.OwnerID, rawIndex, file.TotalChunk)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
return
}

w.WriteHeader(http.StatusAccepted)
return
}
12 changes: 10 additions & 2 deletions handler/file/visibility/visibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,27 @@ func PUT(w http.ResponseWriter, r *http.Request) {
return
}

err = app.Server.Service.DeleteFileCache(r.Context(), fileID)
err = app.Server.Service.RemoveFileCache(r.Context(), fileID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

userFile, err := app.Server.Service.GetUserFile(r.Context(), file.ID)
err = app.Server.Service.RemoveUserFilesCache(r.Context(), userSession.UserID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

userFile, err := app.Server.Service.GetFileDetail(r.Context(), file.ID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

component := fileView.JustFile(*userFile)
err = component.Render(r.Context(), w)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion handler/forgotPassword/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
return
}

err = app.Server.Service.DeleteUser(r.Context(), userData.User.Email)
err = app.Server.Service.RemoveUserCache(r.Context(), userData.User.Email)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand Down
2 changes: 1 addition & 1 deletion handler/user/ResetPassword/ResetPassword.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
return
}

err = app.Server.Service.DeleteUser(r.Context(), userSession.Email)
err = app.Server.Service.RemoveUserCache(r.Context(), userSession.Email)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand Down
2 changes: 1 addition & 1 deletion handler/user/totp/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
app.Server.Logger.Error(err.Error())
return
}
err := app.Server.Service.DeleteUser(r.Context(), userSession.Email)
err := app.Server.Service.RemoveUserCache(r.Context(), userSession.Email)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand Down
133 changes: 133 additions & 0 deletions handler/user/totp/setup.go~
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package userHandlerTotpSetup

import (
"bytes"
"encoding/base64"
"fmt"
"github.com/a-h/templ"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/view/client/user/totp"
"image/png"
"net/http"
"time"

"github.com/fossyy/filekeeper/types"
"github.com/skip2/go-qrcode"
"github.com/xlzd/gotp"
)

func generateQRCode(uri string) (string, error) {
qr, err := qrcode.New(uri, qrcode.Medium)
if err != nil {
return "", fmt.Errorf("failed to generate QR code: %w", err)
}

var buffer bytes.Buffer
if err := png.Encode(&buffer, qr.Image(256)); err != nil {
return "", fmt.Errorf("failed to encode QR code to PNG: %w", err)
}

return base64.StdEncoding.EncodeToString(buffer.Bytes()), nil
}

func GET(w http.ResponseWriter, r *http.Request) {
secret := gotp.RandomSecret(16)
userSession := r.Context().Value("user").(types.User)
totp := gotp.NewDefaultTOTP(secret)
uri := totp.ProvisioningUri(userSession.Email, "filekeeper")
base64Str, err := generateQRCode(uri)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

var component templ.Component
if r.Header.Get("hx-request") == "true" {
component = userTotpSetupView.MainContent("Filekeeper - 2FA Setup Page", base64Str, secret, userSession, types.Message{
Code: 3,
Message: "",
})
} else {
component = userTotpSetupView.Main("Filekeeper - 2FA Setup Page", base64Str, secret, userSession, types.Message{
Code: 3,
Message: "",
})
}
if err := component.Render(r.Context(), w); err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}
}

func POST(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}

code := r.Form.Get("totp")
secret := r.Form.Get("secret")
totp := gotp.NewDefaultTOTP(secret)
userSession := r.Context().Value("user").(types.User)
uri := totp.ProvisioningUri(userSession.Email, "filekeeper")

base64Str, err := generateQRCode(uri)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}
var component templ.Component
if totp.Verify(code, time.Now().Unix()) {
if err := app.Server.Database.InitializeTotp(userSession.Email, secret); err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}
err := app.Server.Service.DeleteUser(r.Context(), userSession.Email)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}
if r.Header.Get("hx-request") == "true" {
component = userTotpSetupView.MainContent("Filekeeper - 2FA Setup Page", base64Str, secret, userSession, types.Message{
Code: 1,
Message: "Your TOTP setup is complete! Your account is now more secure.",
})
} else {
component = userTotpSetupView.Main("Filekeeper - 2FA Setup Page", base64Str, secret, userSession, types.Message{
Code: 1,
Message: "Your TOTP setup is complete! Your account is now more secure.",
})
}

if err := component.Render(r.Context(), w); err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}
return
} else {
if r.Header.Get("hx-request") == "true" {
component = userTotpSetupView.MainContent("Filekeeper - 2FA Setup Page", base64Str, secret, userSession, types.Message{
Code: 0,
Message: "The code you entered is incorrect. Please double-check the code and try again.",
})
} else {
component = userTotpSetupView.Main("Filekeeper - 2FA Setup Page", base64Str, secret, userSession, types.Message{
Code: 0,
Message: "The code you entered is incorrect. Please double-check the code and try again.",
})
}
if err := component.Render(r.Context(), w); err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
return
}
return
}
}
14 changes: 11 additions & 3 deletions handler/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
return
}

usage, err := app.Server.Service.GetUserStorageUsage(r.Context(), userSession.UserID.String())
usage, err := app.Server.Service.CalculateUserStorageUsage(r.Context(), userSession.UserID.String())
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
app.Server.Logger.Error(err.Error())
Expand Down Expand Up @@ -193,11 +193,19 @@ func handlerWS(conn *websocket.Conn, userSession types.User) {

err := app.Server.Database.CreateFile(&newFile)
if err != nil {
app.Server.Logger.Error(err.Error())
sendErrorResponse(conn, action.Action, "Error Creating File")
continue
}

userFile, err := app.Server.Service.GetUserFile(context.Background(), fileID)
err = app.Server.Service.RemoveUserFilesCache(context.Background(), userSession.UserID)
if err != nil {
app.Server.Logger.Error(err.Error())
sendErrorResponse(conn, action.Action, "Error Creating File")
return
}

userFile, err := app.Server.Service.GetFileDetail(context.Background(), fileID)
if err != nil {
app.Server.Logger.Error(err.Error())
sendErrorResponse(conn, action.Action, "Unknown error")
Expand All @@ -216,7 +224,7 @@ func handlerWS(conn *websocket.Conn, userSession types.User) {
sendErrorResponse(conn, action.Action, "File Is Different")
continue
}
userFile, err := app.Server.Service.GetUserFile(context.Background(), file.ID)
userFile, err := app.Server.Service.GetFileDetail(context.Background(), file.ID)
if err != nil {
app.Server.Logger.Error(err.Error())
sendErrorResponse(conn, action.Action, "Unknown error")
Expand Down
Loading

0 comments on commit 59d4154

Please sign in to comment.