107 lines
3.6 KiB
Go
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)
|
||
|
|
}
|