176 lines
5.6 KiB
Go
176 lines
5.6 KiB
Go
package web
|
|
|
|
import (
|
|
"ResendIt/internal/config"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type ConfigPageData struct {
|
|
Success bool
|
|
Error string
|
|
|
|
UploadMaxFileSizeMB int64
|
|
UploadMultiMaxFiles int
|
|
UploadMaxHours int
|
|
|
|
RateLimitLoginPerMinute int
|
|
RateLimitLoginBurst int
|
|
RateLimitApiPerMinute int
|
|
RateLimitApiBurst int
|
|
|
|
NtfyUse bool
|
|
NtfyUrl string
|
|
NtfyTopic string
|
|
}
|
|
|
|
// ConfigPage renders a modular admin config screen.
|
|
func (h *Handler) ConfigPage(c *gin.Context) {
|
|
cfg := h.configService
|
|
|
|
maxBytes := cfg.GetInt64Default(config.KeyUploadMaxFileSizeBytes, config.DefaultUploadMaxFileSizeBytes)
|
|
data := ConfigPageData{
|
|
Success: c.Query("saved") == "1",
|
|
UploadMaxFileSizeMB: maxBytes / (1024 * 1024),
|
|
UploadMultiMaxFiles: cfg.GetIntDefault(config.KeyUploadMultiMaxFiles, config.DefaultUploadMultiMaxFiles),
|
|
UploadMaxHours: cfg.GetIntDefault(config.KeyUploadMaxHours, config.DefaultUploadMaxHours),
|
|
RateLimitLoginPerMinute: cfg.GetIntDefault(config.KeyRateLimitLoginPerMinute, config.DefaultRateLimitLoginPerMinute),
|
|
RateLimitLoginBurst: cfg.GetIntDefault(config.KeyRateLimitLoginBurst, config.DefaultRateLimitLoginBurst),
|
|
RateLimitApiPerMinute: cfg.GetIntDefault(config.KeyRateLimitApiPerMinute, config.DefaultRateLimitApiPerMinute),
|
|
RateLimitApiBurst: cfg.GetIntDefault(config.KeyRateLimitApiBurst, config.DefaultRateLimitApiBurst),
|
|
NtfyUse: cfg.GetIntDefault(config.KeyUseNtfy, 0) != 0,
|
|
NtfyUrl: cfg.GetStringDefault(config.KeyNtfyUrl, config.DefaultNtfyUrl),
|
|
NtfyTopic: cfg.GetStringDefault(config.KeyNtfyTopic, config.DefaultNtfyTopic),
|
|
}
|
|
|
|
c.HTML(http.StatusOK, "config.html", data)
|
|
}
|
|
|
|
func (h *Handler) ConfigSave(c *gin.Context) {
|
|
cfg := h.configService
|
|
|
|
// Parse + validate.
|
|
parseInt := func(name string, min, max int) (int, error) {
|
|
v := c.PostForm(name)
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if n < min {
|
|
n = min
|
|
}
|
|
if max > 0 && n > max {
|
|
n = max
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
parseInt64 := func(name string, min int64, max int64) (int64, error) {
|
|
v := c.PostForm(name)
|
|
n, err := strconv.ParseInt(v, 10, 64)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if n < min {
|
|
n = min
|
|
}
|
|
if max > 0 && n > max {
|
|
n = max
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
maxMB, err := parseInt64("upload_max_file_size_mb", 1, 1024*1024)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid max file size")
|
|
return
|
|
}
|
|
maxFiles, err := parseInt("upload_multi_max_files", 1, 500)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid max files")
|
|
return
|
|
}
|
|
maxHours, err := parseInt("upload_max_hours", 1, 24*365)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid max hours")
|
|
return
|
|
}
|
|
|
|
// Rate limits: stored, but not applied dynamically yet.
|
|
loginPerMin, err := parseInt("ratelimit_login_per_minute", 1, 10000)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid login rate")
|
|
return
|
|
}
|
|
loginBurst, err := parseInt("ratelimit_login_burst", 1, 10000)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid login burst")
|
|
return
|
|
}
|
|
apiPerMin, err := parseInt("ratelimit_api_per_minute", 1, 100000)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid api rate")
|
|
return
|
|
}
|
|
apiBurst, err := parseInt("ratelimit_api_burst", 1, 100000)
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid api burst")
|
|
return
|
|
}
|
|
|
|
useNTFY, err := strconv.ParseBool(c.PostForm("ntfy_use"))
|
|
if err != nil {
|
|
h.renderConfigError(c, "invalid ntfy use value")
|
|
return
|
|
}
|
|
ntfyUrl := c.PostForm("ntfy_url")
|
|
ntfyTopic := c.PostForm("ntfy_topic")
|
|
|
|
// Persist.
|
|
if err := cfg.SetString(config.KeyUploadMaxFileSizeBytes, strconv.FormatInt(maxMB*1024*1024, 10)); err != nil {
|
|
h.renderConfigError(c, err.Error())
|
|
return
|
|
}
|
|
if err := cfg.SetString(config.KeyUploadMultiMaxFiles, strconv.Itoa(maxFiles)); err != nil {
|
|
h.renderConfigError(c, err.Error())
|
|
return
|
|
}
|
|
if err := cfg.SetString(config.KeyUploadMaxHours, strconv.Itoa(maxHours)); err != nil {
|
|
h.renderConfigError(c, err.Error())
|
|
return
|
|
}
|
|
|
|
_ = cfg.SetString(config.KeyRateLimitLoginPerMinute, strconv.Itoa(loginPerMin))
|
|
_ = cfg.SetString(config.KeyRateLimitLoginBurst, strconv.Itoa(loginBurst))
|
|
_ = cfg.SetString(config.KeyRateLimitApiPerMinute, strconv.Itoa(apiPerMin))
|
|
_ = cfg.SetString(config.KeyRateLimitApiBurst, strconv.Itoa(apiBurst))
|
|
|
|
// shitty ah fix
|
|
actualBool := 0
|
|
if useNTFY {
|
|
actualBool = 1
|
|
}
|
|
_ = cfg.SetString(config.KeyUseNtfy, strconv.Itoa(actualBool))
|
|
_ = cfg.SetString(config.KeyNtfyUrl, ntfyUrl)
|
|
_ = cfg.SetString(config.KeyNtfyTopic, ntfyTopic)
|
|
|
|
c.Redirect(http.StatusFound, "/config?saved=1")
|
|
}
|
|
|
|
func (h *Handler) renderConfigError(c *gin.Context, msg string) {
|
|
maxBytes := h.configService.GetInt64Default(config.KeyUploadMaxFileSizeBytes, config.DefaultUploadMaxFileSizeBytes)
|
|
data := ConfigPageData{
|
|
Error: msg,
|
|
UploadMaxFileSizeMB: maxBytes / (1024 * 1024),
|
|
UploadMultiMaxFiles: h.configService.GetIntDefault(config.KeyUploadMultiMaxFiles, config.DefaultUploadMultiMaxFiles),
|
|
UploadMaxHours: h.configService.GetIntDefault(config.KeyUploadMaxHours, config.DefaultUploadMaxHours),
|
|
RateLimitLoginPerMinute: h.configService.GetIntDefault(config.KeyRateLimitLoginPerMinute, config.DefaultRateLimitLoginPerMinute),
|
|
RateLimitLoginBurst: h.configService.GetIntDefault(config.KeyRateLimitLoginBurst, config.DefaultRateLimitLoginBurst),
|
|
RateLimitApiPerMinute: h.configService.GetIntDefault(config.KeyRateLimitApiPerMinute, config.DefaultRateLimitApiPerMinute),
|
|
RateLimitApiBurst: h.configService.GetIntDefault(config.KeyRateLimitApiBurst, config.DefaultRateLimitApiBurst),
|
|
}
|
|
c.HTML(http.StatusBadRequest, "config.html", data)
|
|
}
|