feat(config): add box owner policy settings
Adds configuration options and environment variables to manage box owner policies, including settings for refresh counts and expiry.
This commit is contained in:
238
lib/server/account_pages.go
Normal file
238
lib/server/account_pages.go
Normal file
@@ -0,0 +1,238 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user