Files
mailgoserver/internal/webui/blacklist.go
T

107 lines
3.6 KiB
Go

package webui
import (
"net"
"net/http"
)
// blacklistPage lists both currently/recently blacklisted IPs (auto or manual) and the
// abuse-detection whitelist — global-admin only, since a blacklist entry isn't
// attributable to one domain the way a mailbox or relay-whitelist row is.
func (a *App) blacklistPage(w http.ResponseWriter, r *http.Request) {
entries, err := a.DB.ListBlacklist()
if err != nil {
setFlash(w, "error", "Error loading blacklist")
}
whitelist, err := a.DB.ListAbuseWhitelist()
if err != nil {
setFlash(w, "error", "Error loading abuse whitelist")
}
a.render(w, r, "blacklist.html", M{"active": "blacklist", "entries": entries, "whitelist": whitelist})
}
// addBlacklistEntry is an admin-initiated manual block: fixed duration, no escalation.
func (a *App) addBlacklistEntry(w http.ResponseWriter, r *http.Request) {
ip := r.FormValue("ip_address")
reason := r.FormValue("reason")
hours := atoi(r.FormValue("hours"))
if net.ParseIP(ip) == nil || hours <= 0 {
setFlash(w, "error", "A valid IP address and a positive duration in hours are required")
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
return
}
if err := a.DB.AddManualBlacklistEntry(ip, reason, hours); err != nil {
setFlash(w, "error", "Error blacklisting IP")
} else {
setFlash(w, "success", "IP blacklisted")
}
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
}
func (a *App) removeBlacklistEntry(w http.ResponseWriter, r *http.Request) {
if err := a.DB.RemoveBlacklistEntry(pathID(r)); err != nil {
setFlash(w, "error", "Error removing blacklist entry")
} else {
setFlash(w, "success", "Blacklist entry removed")
}
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
}
// whitelistBlacklistedIP removes ip from the blacklist and adds it to the abuse
// whitelist in one action, so an admin can undo a false-positive auto-block without
// two separate trips.
func (a *App) whitelistBlacklistedIP(w http.ResponseWriter, r *http.Request) {
id := pathID(r)
entries, err := a.DB.ListBlacklist()
if err != nil {
setFlash(w, "error", "Error loading blacklist")
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
return
}
var ip string
for _, e := range entries {
if e.ID == id {
ip = e.IPAddress
break
}
}
if ip == "" {
http.NotFound(w, r)
return
}
if err := a.DB.AddAbuseWhitelist(ip, "whitelisted from a blacklist entry"); err != nil {
setFlash(w, "error", "Error whitelisting IP")
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
return
}
_ = a.DB.RemoveBlacklistEntry(id)
setFlash(w, "success", ip+" whitelisted and removed from the blacklist")
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
}
func (a *App) addAbuseWhitelistEntry(w http.ResponseWriter, r *http.Request) {
ip := r.FormValue("ip_address")
note := r.FormValue("note")
if net.ParseIP(ip) == nil {
setFlash(w, "error", "A valid IP address is required")
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
return
}
if err := a.DB.AddAbuseWhitelist(ip, note); err != nil {
setFlash(w, "error", "Error adding to abuse whitelist")
} else {
setFlash(w, "success", "IP added to the abuse-detection whitelist")
}
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
}
func (a *App) removeAbuseWhitelistEntry(w http.ResponseWriter, r *http.Request) {
if err := a.DB.RemoveAbuseWhitelist(pathID(r)); err != nil {
setFlash(w, "error", "Error removing abuse whitelist entry")
} else {
setFlash(w, "success", "Removed from the abuse-detection whitelist")
}
http.Redirect(w, r, Prefix+"/blacklist", http.StatusFound)
}