Files
warpbox-dev/backend/libs/handlers/dashboard.go

195 lines
6.7 KiB
Go
Raw Normal View History

package handlers
import (
"fmt"
"net/http"
"os"
"warpbox.dev/backend/libs/helpers"
"warpbox.dev/backend/libs/services"
"warpbox.dev/backend/libs/web"
)
type dashboardData struct {
User services.PublicUser
Collections []collectionView
Boxes []userBoxView
StorageUsed string
MaxUploadSize string
Selected string
LastInviteURL string
}
type collectionView struct {
ID string
Name string
}
type userBoxView struct {
ID string
Title string
CollectionID string
CollectionName string
FileCount int
Size string
CreatedAt string
ExpiresAt string
URL string
}
func (a *App) Dashboard(w http.ResponseWriter, r *http.Request) {
user, ok := a.requireUser(w, r)
if !ok {
return
}
a.logger.Info("user dashboard viewed", withRequestLogAttrs(r,
"source", "page",
"severity", "user_activity",
"code", 2502,
"user_id", user.ID,
)...)
collections, err := a.authService.ListCollections(user.ID)
if err != nil {
http.Error(w, "unable to load collections", http.StatusInternalServerError)
return
}
collectionNames := map[string]string{}
collectionViews := make([]collectionView, 0, len(collections))
for _, collection := range collections {
collectionNames[collection.ID] = collection.Name
collectionViews = append(collectionViews, collectionView{ID: collection.ID, Name: collection.Name})
}
boxes, err := a.uploadService.UserBoxes(user.ID, collectionNames)
if err != nil {
http.Error(w, "unable to load boxes", http.StatusInternalServerError)
return
}
storageUsed, err := a.uploadService.UserStorageUsed(user.ID)
if err != nil {
http.Error(w, "unable to load storage usage", http.StatusInternalServerError)
return
}
selected := r.URL.Query().Get("collection")
boxViews := make([]userBoxView, 0, len(boxes))
for _, row := range boxes {
if selected != "" && row.Box.CollectionID != selected {
continue
}
title := row.Box.Title
if title == "" {
title = fmt.Sprintf("%d file upload", len(row.Box.Files))
}
boxViews = append(boxViews, userBoxView{
ID: row.Box.ID,
Title: title,
CollectionID: row.Box.CollectionID,
CollectionName: row.CollectionName,
FileCount: len(row.Box.Files),
Size: row.TotalSizeLabel,
CreatedAt: row.Box.CreatedAt.Format("Jan 2 15:04"),
ExpiresAt: boxExpiryLabel(row.Box.ExpiresAt, "Jan 2 15:04"),
URL: "/d/" + row.Box.ID,
})
}
a.renderPage(w, r, http.StatusOK, "dashboard.html", web.PageData{
Title: "My files",
Description: "Your Warpbox personal file space.",
CurrentUser: a.authService.PublicUser(user),
Data: dashboardData{
User: a.authService.PublicUser(user),
Collections: collectionViews,
Boxes: boxViews,
StorageUsed: helpers.FormatBytes(storageUsed),
MaxUploadSize: a.uploadService.MaxUploadSizeLabel(),
Selected: selected,
},
})
}
func (a *App) CreateCollection(w http.ResponseWriter, r *http.Request) {
user, ok := a.requireUser(w, r)
if !ok || !a.validateCSRF(w, r) {
return
}
if err := r.ParseForm(); err != nil {
http.Redirect(w, r, "/app", http.StatusSeeOther)
return
}
if _, err := a.authService.CreateCollection(user.ID, r.FormValue("name")); err != nil {
a.logger.Warn("collection create failed", withRequestLogAttrs(r, "source", "user_activity", "severity", "warn", "code", 4410, "user_id", user.ID, "error", err.Error())...)
} else {
a.logger.Info("collection created", withRequestLogAttrs(r, "source", "user_activity", "severity", "user_activity", "code", 2410, "user_id", user.ID, "name", r.FormValue("name"))...)
}
http.Redirect(w, r, "/app", http.StatusSeeOther)
}
func (a *App) RenameUserBox(w http.ResponseWriter, r *http.Request) {
user, ok := a.requireUser(w, r)
if !ok || !a.validateCSRF(w, r) {
return
}
if err := r.ParseForm(); err != nil {
http.Redirect(w, r, "/app", http.StatusSeeOther)
return
}
if err := a.uploadService.RenameOwnedBox(r.PathValue("boxID"), user.ID, r.FormValue("title")); err != nil {
a.logger.Warn("owned box rename failed", withRequestLogAttrs(r, "source", "user_activity", "severity", "warn", "code", 4411, "user_id", user.ID, "box_id", r.PathValue("boxID"), "error", err.Error())...)
a.handleUserBoxError(w, r, err)
return
}
a.logger.Info("owned box renamed", withRequestLogAttrs(r, "source", "user_activity", "severity", "user_activity", "code", 2411, "user_id", user.ID, "box_id", r.PathValue("boxID"))...)
http.Redirect(w, r, "/app", http.StatusSeeOther)
}
func (a *App) MoveUserBox(w http.ResponseWriter, r *http.Request) {
user, ok := a.requireUser(w, r)
if !ok || !a.validateCSRF(w, r) {
return
}
if err := r.ParseForm(); err != nil {
http.Redirect(w, r, "/app", http.StatusSeeOther)
return
}
collectionID := r.FormValue("collection_id")
if !a.authService.CollectionOwnedBy(collectionID, user.ID) {
a.logger.Warn("owned box move invalid collection", withRequestLogAttrs(r, "source", "user_activity", "severity", "warn", "code", 4412, "user_id", user.ID, "box_id", r.PathValue("boxID"), "collection_id", collectionID)...)
http.Error(w, "collection not found", http.StatusForbidden)
return
}
if err := a.uploadService.MoveOwnedBox(r.PathValue("boxID"), user.ID, collectionID); err != nil {
a.logger.Warn("owned box move failed", withRequestLogAttrs(r, "source", "user_activity", "severity", "warn", "code", 4413, "user_id", user.ID, "box_id", r.PathValue("boxID"), "error", err.Error())...)
a.handleUserBoxError(w, r, err)
return
}
a.logger.Info("owned box moved", withRequestLogAttrs(r, "source", "user_activity", "severity", "user_activity", "code", 2412, "user_id", user.ID, "box_id", r.PathValue("boxID"), "collection_id", collectionID)...)
http.Redirect(w, r, "/app", http.StatusSeeOther)
}
func (a *App) DeleteUserBox(w http.ResponseWriter, r *http.Request) {
user, ok := a.requireUser(w, r)
if !ok || !a.validateCSRF(w, r) {
return
}
if err := a.uploadService.DeleteOwnedBox(r.PathValue("boxID"), user.ID); err != nil {
a.logger.Warn("owned box delete failed", withRequestLogAttrs(r, "source", "user_activity", "severity", "warn", "code", 4414, "user_id", user.ID, "box_id", r.PathValue("boxID"), "error", err.Error())...)
a.handleUserBoxError(w, r, err)
return
}
a.logger.Info("owned box deleted", withRequestLogAttrs(r, "source", "user_activity", "severity", "user_activity", "code", 2413, "user_id", user.ID, "box_id", r.PathValue("boxID"))...)
http.Redirect(w, r, "/app", http.StatusSeeOther)
}
func (a *App) handleUserBoxError(w http.ResponseWriter, r *http.Request, err error) {
if os.IsPermission(err) {
http.Error(w, "not allowed", http.StatusForbidden)
return
}
if os.IsNotExist(err) {
http.NotFound(w, r)
return
}
http.Error(w, "unable to update box", http.StatusInternalServerError)
}