Adds configuration options and environment variables to manage box owner policies, including settings for refresh counts and expiry.
239 lines
5.8 KiB
Go
239 lines
5.8 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"warpbox/lib/boxstore"
|
|
"warpbox/lib/helpers"
|
|
"warpbox/lib/metastore"
|
|
)
|
|
|
|
type AccountDashboardView struct {
|
|
PageTitle string
|
|
WindowTitle string
|
|
WindowIcon string
|
|
PageScripts []string
|
|
AccountNav AccountNavView
|
|
CSRFToken string
|
|
Stats AccountDashboardStats
|
|
Statuses []accountStatusRow
|
|
Alerts []accountAlertPreviewRow
|
|
RecentBoxes []accountDashboardBoxRow
|
|
RecentActivity []accountActivityRow
|
|
ShowUsersStat bool
|
|
CanManageBoxes bool
|
|
CanManageUsers bool
|
|
CanViewSettings bool
|
|
HasAlertsPreview bool
|
|
}
|
|
|
|
type AccountDashboardStats struct {
|
|
ActiveBoxes int
|
|
StorageUsedLabel string
|
|
AlertCount int
|
|
TotalUsers int
|
|
ActiveUsers int
|
|
DisabledUsers int
|
|
}
|
|
|
|
type accountStatusRow struct {
|
|
Label string
|
|
Value string
|
|
Severity string
|
|
}
|
|
|
|
type accountAlertPreviewRow struct {
|
|
Severity string
|
|
Title string
|
|
Detail string
|
|
}
|
|
|
|
type accountDashboardBoxRow struct {
|
|
ID string
|
|
FileCount int
|
|
TotalSizeLabel string
|
|
CreatedAt string
|
|
ExpiresAt string
|
|
Flags string
|
|
CanManage bool
|
|
}
|
|
|
|
type accountActivityRow struct {
|
|
Time string
|
|
Title string
|
|
Meta string
|
|
}
|
|
|
|
func (app *App) handleAccountDashboard(ctx *gin.Context) {
|
|
actor, ok := currentAccountUser(ctx)
|
|
if !ok {
|
|
ctx.Redirect(http.StatusSeeOther, "/account/login")
|
|
return
|
|
}
|
|
|
|
view, err := app.GetAccountDashboard(ctx, actor)
|
|
if err != nil {
|
|
ctx.String(http.StatusInternalServerError, "Could not load account dashboard")
|
|
return
|
|
}
|
|
ctx.HTML(http.StatusOK, "account_dashboard.html", view)
|
|
}
|
|
|
|
func (app *App) GetAccountDashboard(ctx *gin.Context, actor metastore.User) (AccountDashboardView, error) {
|
|
perms := currentAccountPermissions(ctx)
|
|
nav := app.accountNavView(ctx, "dashboard")
|
|
|
|
totalSize := int64(0)
|
|
activeBoxes := 0
|
|
recentBoxes := []accountDashboardBoxRow{}
|
|
if perms.AdminBoxesView {
|
|
summaries, err := boxstore.ListBoxSummaries()
|
|
if err != nil {
|
|
return AccountDashboardView{}, err
|
|
}
|
|
|
|
recentBoxes = make([]accountDashboardBoxRow, 0, minInt(len(summaries), 10))
|
|
for _, summary := range summaries {
|
|
totalSize += summary.TotalSize
|
|
if !summary.Expired {
|
|
activeBoxes++
|
|
}
|
|
if len(recentBoxes) < 10 {
|
|
recentBoxes = append(recentBoxes, accountDashboardBoxRow{
|
|
ID: summary.ID,
|
|
FileCount: summary.FileCount,
|
|
TotalSizeLabel: summary.TotalSizeLabel,
|
|
CreatedAt: formatAdminTime(summary.CreatedAt),
|
|
ExpiresAt: formatAdminTime(summary.ExpiresAt),
|
|
Flags: accountBoxFlags(summary.Expired, summary.OneTimeDownload, summary.PasswordProtected),
|
|
CanManage: true,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
stats := AccountDashboardStats{
|
|
ActiveBoxes: activeBoxes,
|
|
StorageUsedLabel: helpers.FormatBytes(totalSize),
|
|
}
|
|
|
|
showUsersStat := perms.AdminUsersManage
|
|
if showUsersStat {
|
|
users, err := app.store.ListUsers()
|
|
if err != nil {
|
|
return AccountDashboardView{}, err
|
|
}
|
|
stats.TotalUsers = len(users)
|
|
for _, user := range users {
|
|
if user.Disabled {
|
|
stats.DisabledUsers++
|
|
} else {
|
|
stats.ActiveUsers++
|
|
}
|
|
}
|
|
}
|
|
|
|
return AccountDashboardView{
|
|
PageTitle: "WarpBox Account",
|
|
WindowTitle: "WarpBox Account Control Panel",
|
|
WindowIcon: "W",
|
|
AccountNav: nav,
|
|
CSRFToken: app.currentCSRFToken(ctx),
|
|
Stats: stats,
|
|
Statuses: app.accountDashboardStatuses(),
|
|
Alerts: accountPlaceholderAlerts(),
|
|
RecentBoxes: recentBoxes,
|
|
RecentActivity: accountPlaceholderActivity(actor, ctx),
|
|
ShowUsersStat: showUsersStat,
|
|
CanManageBoxes: perms.AdminBoxesView,
|
|
CanManageUsers: perms.AdminUsersManage,
|
|
CanViewSettings: perms.AdminSettingsManage,
|
|
HasAlertsPreview: true,
|
|
}, nil
|
|
}
|
|
|
|
func (app *App) accountDashboardStatuses() []accountStatusRow {
|
|
return []accountStatusRow{
|
|
{Label: "Guest uploads", Value: enabledLabel(app.config.GuestUploadsEnabled), Severity: boolSeverity(app.config.GuestUploadsEnabled)},
|
|
{Label: "API", Value: enabledLabel(app.config.APIEnabled), Severity: boolSeverity(app.config.APIEnabled)},
|
|
{Label: "ZIP downloads", Value: enabledLabel(app.config.ZipDownloadsEnabled), Severity: boolSeverity(app.config.ZipDownloadsEnabled)},
|
|
{Label: "One-time boxes", Value: enabledLabel(app.config.OneTimeDownloadsEnabled), Severity: boolSeverity(app.config.OneTimeDownloadsEnabled)},
|
|
}
|
|
}
|
|
|
|
func accountPlaceholderAlerts() []accountAlertPreviewRow {
|
|
return []accountAlertPreviewRow{
|
|
{
|
|
Severity: "info",
|
|
Title: "Alerts system pending",
|
|
Detail: "Dedicated alert storage arrives in the alerts implementation pass.",
|
|
},
|
|
}
|
|
}
|
|
|
|
func accountPlaceholderActivity(actor metastore.User, ctx *gin.Context) []accountActivityRow {
|
|
now := time.Now().UTC()
|
|
if value, ok := ctx.Get("accountSession"); ok {
|
|
if session, ok := value.(metastore.Session); ok {
|
|
now = session.CreatedAt
|
|
}
|
|
}
|
|
return []accountActivityRow{
|
|
{
|
|
Time: formatAdminTime(now),
|
|
Title: "Signed in",
|
|
Meta: actor.Username + " opened the account dashboard.",
|
|
},
|
|
{
|
|
Time: "pending",
|
|
Title: "Audit log not implemented",
|
|
Meta: "Recent account activity will use the audit model in a later pass.",
|
|
},
|
|
}
|
|
}
|
|
|
|
func accountBoxFlags(expired bool, oneTime bool, passwordProtected bool) string {
|
|
flags := []string{}
|
|
if expired {
|
|
flags = append(flags, "expired")
|
|
}
|
|
if oneTime {
|
|
flags = append(flags, "one-time")
|
|
}
|
|
if passwordProtected {
|
|
flags = append(flags, "password")
|
|
}
|
|
if len(flags) == 0 {
|
|
return "normal"
|
|
}
|
|
out := flags[0]
|
|
for _, flag := range flags[1:] {
|
|
out += ", " + flag
|
|
}
|
|
return out
|
|
}
|
|
|
|
func enabledLabel(enabled bool) string {
|
|
if enabled {
|
|
return "enabled"
|
|
}
|
|
return "disabled"
|
|
}
|
|
|
|
func boolSeverity(enabled bool) string {
|
|
if enabled {
|
|
return "ok"
|
|
}
|
|
return "warn"
|
|
}
|
|
|
|
func minInt(a int, b int) int {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|