Rate limit the user Mark Explicit endpoint

main
Noah Petherbridge 2024-03-29 22:59:13 -07:00
parent 2ab34a39a3
commit 535e96b491
2 changed files with 28 additions and 0 deletions

View File

@ -66,6 +66,13 @@ const (
ContactRateLimitCooldownAt = 1
ContactRateLimitCooldown = 2 * time.Minute
// "Mark Explicit" rate limit to curb a mischievous user just bulk marking the
// whole gallery as explicit.
MarkExplicitRateLimitWindow = 1 * time.Hour
MarkExplicitRateLimit = 20 // 10 failed MarkExplicit attempts = locked for full hour
MarkExplicitRateLimitCooldownAt = 10 // 10 photos in an hour, start throttling.
MarkExplicitRateLimitCooldown = time.Minute
// How frequently to refresh LastLoginAt since sessions are long-lived.
LastLoginAtCooldown = time.Hour

View File

@ -4,8 +4,10 @@ import (
"fmt"
"net/http"
"code.nonshy.com/nonshy/website/pkg/config"
"code.nonshy.com/nonshy/website/pkg/log"
"code.nonshy.com/nonshy/website/pkg/models"
"code.nonshy.com/nonshy/website/pkg/ratelimit"
"code.nonshy.com/nonshy/website/pkg/session"
"code.nonshy.com/nonshy/website/pkg/templates"
)
@ -61,6 +63,25 @@ func MarkPhotoExplicit() http.HandlerFunc {
}
if !photo.Explicit {
// Rate limit how frequently they are tagging photos, in case a user is just going around
// and tagging EVERYTHING.
if !currentUser.IsAdmin {
limiter := &ratelimit.Limiter{
Namespace: "mark_explicit",
ID: currentUser.ID,
Limit: config.MarkExplicitRateLimit,
Window: config.MarkExplicitRateLimitWindow,
CooldownAt: config.MarkExplicitRateLimitCooldownAt,
Cooldown: config.MarkExplicitRateLimitCooldown,
}
if err := limiter.Ping(); err != nil {
SendJSON(w, http.StatusTooManyRequests, Response{
Error: "We appreciate the enthusiasm, but you seem to be marking an unusually high number of photos!\n\n" + err.Error(),
})
return
}
}
photo.Explicit = true
if err := photo.Save(); err != nil {
SendJSON(w, http.StatusBadRequest, Response{