Files
WarpBox/lib/metastore/permissions.go
Daniel Legt a5d6d69be0 docs: expand configuration docs for admin and BadgerDB
Update README to explain startup config precedence (defaults/env/admin overrides),
document admin/bootstrap and feature toggles, and clarify storage locations under
WARPBOX_DATA_DIR including BadgerDB metadata. Also refresh project layout to
include new config and metastore packages.docs: expand configuration docs for admin and BadgerDB

Update README to explain startup config precedence (defaults/env/admin overrides),
document admin/bootstrap and feature toggles, and clarify storage locations under
WARPBOX_DATA_DIR including BadgerDB metadata. Also refresh project layout to
include new config and metastore packages.
2026-04-28 21:11:37 +03:00

142 lines
4.3 KiB
Go

package metastore
import (
"sort"
"warpbox/lib/config"
)
func ResolveUserPermissions(cfg *config.Config, user User, tags []Tag) EffectivePermissions {
perms := EffectivePermissions{
MaxFileSizeBytes: cfg.DefaultUserMaxFileSizeBytes,
MaxBoxSizeBytes: cfg.DefaultUserMaxBoxSizeBytes,
ZipDownloadAllowed: cfg.ZipDownloadsEnabled,
OneTimeDownloadAllowed: cfg.OneTimeDownloadsEnabled,
}
expirySet := make(map[int64]bool)
for _, tag := range tags {
tagPerms := tag.Permissions
perms.UploadAllowed = perms.UploadAllowed || tagPerms.UploadAllowed
perms.OneTimeDownloadAllowed = perms.OneTimeDownloadAllowed || tagPerms.OneTimeDownloadAllowed
perms.ZipDownloadAllowed = perms.ZipDownloadAllowed || tagPerms.ZipDownloadAllowed
perms.RenewableAllowed = perms.RenewableAllowed || tagPerms.RenewableAllowed
perms.AdminAccess = perms.AdminAccess || tagPerms.AdminAccess
perms.AdminUsersManage = perms.AdminUsersManage || tagPerms.AdminUsersManage
perms.AdminSettingsManage = perms.AdminSettingsManage || tagPerms.AdminSettingsManage
perms.AdminBoxesView = perms.AdminBoxesView || tagPerms.AdminBoxesView
perms.RenewOnAccessSeconds = maxInt64(perms.RenewOnAccessSeconds, tagPerms.RenewOnAccessSeconds)
perms.RenewOnDownloadSeconds = maxInt64(perms.RenewOnDownloadSeconds, tagPerms.RenewOnDownloadSeconds)
if tagPerms.MaxFileSizeBytes != nil {
perms.MaxFileSizeBytes = morePermissiveLimit(perms.MaxFileSizeBytes, *tagPerms.MaxFileSizeBytes)
}
if tagPerms.MaxBoxSizeBytes != nil {
perms.MaxBoxSizeBytes = morePermissiveLimit(perms.MaxBoxSizeBytes, *tagPerms.MaxBoxSizeBytes)
}
for _, seconds := range tagPerms.AllowedExpirySeconds {
if seconds >= 0 {
expirySet[seconds] = true
}
}
}
if user.MaxFileSizeBytes != nil {
perms.MaxFileSizeBytes = morePermissiveLimit(perms.MaxFileSizeBytes, *user.MaxFileSizeBytes)
}
if user.MaxBoxSizeBytes != nil {
perms.MaxBoxSizeBytes = morePermissiveLimit(perms.MaxBoxSizeBytes, *user.MaxBoxSizeBytes)
}
if user.MaxExpirySeconds != nil {
perms.MaxExpirySeconds = *user.MaxExpirySeconds
}
perms.MaxFileSizeBytes = capLimit(perms.MaxFileSizeBytes, cfg.GlobalMaxFileSizeBytes)
perms.MaxBoxSizeBytes = capLimit(perms.MaxBoxSizeBytes, cfg.GlobalMaxBoxSizeBytes)
perms.AllowedExpirySeconds = sortedExpirySet(expirySet)
if !cfg.ZipDownloadsEnabled {
perms.ZipDownloadAllowed = false
}
if !cfg.OneTimeDownloadsEnabled {
perms.OneTimeDownloadAllowed = false
}
return perms
}
func ResolveGuestPermissions(cfg *config.Config) EffectivePermissions {
return EffectivePermissions{
UploadAllowed: cfg.GuestUploadsEnabled,
AllowedExpirySeconds: guestExpirySeconds(cfg),
MaxFileSizeBytes: cfg.GlobalMaxFileSizeBytes,
MaxBoxSizeBytes: cfg.GlobalMaxBoxSizeBytes,
MaxExpirySeconds: cfg.MaxGuestExpirySeconds,
OneTimeDownloadAllowed: cfg.OneTimeDownloadsEnabled,
ZipDownloadAllowed: cfg.ZipDownloadsEnabled,
RenewableAllowed: cfg.RenewOnAccessEnabled || cfg.RenewOnDownloadEnabled,
}
}
func morePermissiveLimit(current int64, candidate int64) int64 {
if current == 0 || candidate == 0 {
return 0
}
if candidate > current {
return candidate
}
return current
}
func capLimit(value int64, globalMax int64) int64 {
if globalMax == 0 {
return value
}
if value == 0 || value > globalMax {
return globalMax
}
return value
}
func sortedExpirySet(expirySet map[int64]bool) []int64 {
values := make([]int64, 0, len(expirySet))
for value := range expirySet {
values = append(values, value)
}
sort.Slice(values, func(i int, j int) bool {
return values[i] < values[j]
})
return values
}
func guestExpirySeconds(cfg *config.Config) []int64 {
values := []int64{}
if cfg.DefaultGuestExpirySeconds >= 0 {
values = append(values, cfg.DefaultGuestExpirySeconds)
}
if cfg.MaxGuestExpirySeconds > 0 && cfg.MaxGuestExpirySeconds != cfg.DefaultGuestExpirySeconds {
values = append(values, cfg.MaxGuestExpirySeconds)
}
return uniqueInt64s(values)
}
func uniqueInt64s(values []int64) []int64 {
seen := make(map[int64]bool, len(values))
out := make([]int64, 0, len(values))
for _, value := range values {
if seen[value] {
continue
}
seen[value] = true
out = append(out, value)
}
sort.Slice(out, func(i int, j int) bool {
return out[i] < out[j]
})
return out
}
func maxInt64(a int64, b int64) int64 {
if b > a {
return b
}
return a
}