mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-09-05 11:06:23 -07:00
Replace IP field of IPBan with RangeStart and RangeEnd
This commit is contained in:
parent
04c892bba8
commit
57693ba549
16 changed files with 178 additions and 100 deletions
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
const (
|
||||
// if the database version is less than this, it is assumed to be out of date, and the schema needs to be adjusted
|
||||
latestDatabaseVersion = 2
|
||||
latestDatabaseVersion = 3
|
||||
)
|
||||
|
||||
type GCDatabaseUpdater struct {
|
||||
|
@ -94,7 +94,7 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
|
|||
}
|
||||
if numColumns == 0 {
|
||||
query = `ALTER TABLE DBPREFIXwordfilters ADD COLUMN board_dirs varchar(255) DEFAULT '*'`
|
||||
if _, err = gcsql.ExecTxSQL(tx, query); err != nil {
|
||||
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
@ -137,9 +137,9 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
|
|||
if numColumns > 0 {
|
||||
// add range_start and range_end columns
|
||||
query = `ALTER TABLE DBPREFIXip_ban
|
||||
ADD COLUMN IF NOT EXISTS range_start VARBINARY(16) NOT NULL
|
||||
ADD COLUMN IF NOT EXISTS range_start VARBINARY(16) NOT NULL,
|
||||
ADD COLUMN IF NOT EXISTS range_end VARBINARY(16) NOT NULL`
|
||||
if _, err = gcsql.ExecTxSQL(tx, query); err != nil {
|
||||
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
|
||||
return false, err
|
||||
}
|
||||
// convert string to IP range
|
||||
|
@ -157,12 +157,13 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
|
|||
if rangeStart, rangeEnd, err = gcutil.ParseIPRange(ipOrCIDR); err != nil {
|
||||
return false, err
|
||||
}
|
||||
query = `UPDATE DBPREFIXip_ban SET range_start = INET6_ATON(?), range_end = ? WHERE id = ?`
|
||||
if _, err = gcsql.ExecTxSQL(tx, query, rangeStart, rangeEnd, id); err != nil {
|
||||
query = `UPDATE DBPREFIXip_ban
|
||||
SET range_start = INET6_ATON(?), range_end = INET6_ATON(?) WHERE id = ?`
|
||||
if _, err = dbu.db.ExecTxSQL(tx, query, rangeStart, rangeEnd, id); err != nil {
|
||||
return false, err
|
||||
}
|
||||
query = `ALTER TABLE DBPREFIXip_ban DROP COLUMN ip`
|
||||
if _, err = gcsql.ExecTxSQL(tx, query); err != nil {
|
||||
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +179,7 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
case "sqlite3":
|
||||
_, err = gcsql.ExecSQL(`PRAGMA foreign_keys = ON`)
|
||||
_, err = dbu.db.ExecSQL(`PRAGMA foreign_keys = ON`)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ macros = [
|
|||
"BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY",
|
||||
"INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"),
|
||||
macro("fk to serial", "BIGINT", "BIGINT", "BIGINT"),
|
||||
macro("drop fk", "DROP CONSTRAINT", "DROP FOREIGN KEY", "DROP CONSTRAINT")
|
||||
macro("drop fk", "DROP CONSTRAINT", "DROP FOREIGN KEY", "DROP CONSTRAINT"),
|
||||
macro("inet", "INET", "VARBINARY(16)", "VARCHAR(45)")
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -5,13 +5,15 @@ import (
|
|||
"errors"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
)
|
||||
|
||||
const (
|
||||
ipBanQueryBase = `SELECT
|
||||
id, staff_id, board_id, banned_for_post_id, copy_post_text, is_thread_ban,
|
||||
is_active, ip, issued_at, appeal_at, expires_at, permanent, staff_note,
|
||||
message, can_appeal
|
||||
is_active, INET_START, INET_END, issued_at, appeal_at, expires_at,
|
||||
permanent, staff_note, message, can_appeal
|
||||
FROM DBPREFIXip_ban`
|
||||
)
|
||||
|
||||
|
@ -26,9 +28,10 @@ type Ban interface {
|
|||
|
||||
func NewIPBan(ban *IPBan) error {
|
||||
const query = `INSERT INTO DBPREFIXip_ban
|
||||
(staff_id, board_id, banned_for_post_id, copy_post_text, is_thread_ban, is_active, ip,
|
||||
appeal_at, expires_at, permanent, staff_note, message, can_appeal)
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
(staff_id, board_id, banned_for_post_id, copy_post_text, is_thread_ban,
|
||||
is_active, INET_RANGE_START, INET_RANGE_END, appeal_at, expires_at,
|
||||
permanent, staff_note, message, can_appeal)
|
||||
VALUES(?, ?, ?, ?, ?, ?, INET_PARAM, INET_PARAM, ?, ?, ?, ?, ?, ?)`
|
||||
if ban.ID > 0 {
|
||||
return ErrBanAlreadyInserted
|
||||
}
|
||||
|
@ -43,8 +46,9 @@ func NewIPBan(ban *IPBan) error {
|
|||
}
|
||||
defer stmt.Close()
|
||||
if _, err = stmt.Exec(
|
||||
ban.StaffID, ban.BoardID, ban.BannedForPostID, ban.CopyPostText, ban.IsThreadBan, ban.IsActive, ban.IP,
|
||||
ban.AppealAt, ban.ExpiresAt, ban.Permanent, ban.StaffNote, ban.Message, ban.CanAppeal,
|
||||
ban.StaffID, ban.BoardID, ban.BannedForPostID, ban.CopyPostText,
|
||||
ban.IsThreadBan, ban.IsActive, ban.RangeStart, ban.RangeEnd, ban.AppealAt,
|
||||
ban.ExpiresAt, ban.Permanent, ban.StaffNote, ban.Message, ban.CanAppeal,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -55,17 +59,26 @@ func NewIPBan(ban *IPBan) error {
|
|||
return tx.Commit()
|
||||
}
|
||||
|
||||
// CheckIPBan returns the latest active IP ban for the given IP, as well as any errors. If the
|
||||
// IPBan pointer is nil, the IP has no active bans
|
||||
// CheckIPBan returns the latest active IP ban for the given IP, as well as any
|
||||
// errors. If the IPBan pointer is nil, the IP has no active bans. Because
|
||||
// SQLite 3 does not support a native IP type, range bans are not supported if
|
||||
// DBtype == "sqlite3"
|
||||
func CheckIPBan(ip string, boardID int) (*IPBan, error) {
|
||||
const query = ipBanQueryBase + ` WHERE ip = ? AND (board_id IS NULL OR board_id = ?) AND
|
||||
is_active AND (expires_at > CURRENT_TIMESTAMP OR permanent)
|
||||
query := ipBanQueryBase + " WHERE "
|
||||
if config.GetSystemCriticalConfig().DBtype == "sqlite3" {
|
||||
query += "INET_RANGE_START = ? OR INET_RANGE_END = ?"
|
||||
} else {
|
||||
query += "INET_RANGE_START <= INET_PARAM AND INET_PARAM <= INET_RANGE_END"
|
||||
}
|
||||
query += ` AND (board_id IS NULL OR board_id = ?) AND is_active AND
|
||||
(expires_at > CURRENT_TIMESTAMP OR permanent)
|
||||
ORDER BY id DESC LIMIT 1`
|
||||
var ban IPBan
|
||||
err := QueryRowSQL(query, interfaceSlice(ip, boardID), interfaceSlice(
|
||||
&ban.ID, &ban.StaffID, &ban.BoardID, &ban.BannedForPostID, &ban.CopyPostText, &ban.IsThreadBan,
|
||||
&ban.IsActive, &ban.IP, &ban.IssuedAt, &ban.AppealAt, &ban.ExpiresAt, &ban.Permanent, &ban.StaffNote,
|
||||
&ban.Message, &ban.CanAppeal))
|
||||
&ban.ID, &ban.StaffID, &ban.BoardID, &ban.BannedForPostID, &ban.CopyPostText,
|
||||
&ban.IsThreadBan, &ban.IsActive, &ban.RangeStart, &ban.RangeEnd, &ban.IssuedAt,
|
||||
&ban.AppealAt, &ban.ExpiresAt, &ban.Permanent, &ban.StaffNote, &ban.Message,
|
||||
&ban.CanAppeal))
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -76,9 +89,10 @@ func GetIPBanByID(id int) (*IPBan, error) {
|
|||
const query = ipBanQueryBase + " WHERE id = ?"
|
||||
var ban IPBan
|
||||
err := QueryRowSQL(query, interfaceSlice(id), interfaceSlice(
|
||||
&ban.ID, &ban.StaffID, &ban.BoardID, &ban.BannedForPostID, &ban.CopyPostText, &ban.IsThreadBan,
|
||||
&ban.IsActive, &ban.IP, &ban.IssuedAt, &ban.AppealAt, &ban.ExpiresAt, &ban.Permanent, &ban.StaffNote,
|
||||
&ban.Message, &ban.CanAppeal))
|
||||
&ban.ID, &ban.StaffID, &ban.BoardID, &ban.BannedForPostID, &ban.CopyPostText,
|
||||
&ban.IsThreadBan, &ban.IsActive, &ban.RangeStart, &ban.RangeEnd, &ban.IssuedAt,
|
||||
&ban.AppealAt, &ban.ExpiresAt, &ban.Permanent, &ban.StaffNote, &ban.Message,
|
||||
&ban.CanAppeal))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -106,8 +120,8 @@ func GetIPBans(boardID int, limit int, onlyActive bool) ([]IPBan, error) {
|
|||
var ban IPBan
|
||||
if err = rows.Scan(
|
||||
&ban.ID, &ban.StaffID, &ban.BoardID, &ban.BannedForPostID, &ban.CopyPostText, &ban.IsThreadBan,
|
||||
&ban.IsActive, &ban.IP, &ban.IssuedAt, &ban.AppealAt, &ban.ExpiresAt, &ban.Permanent, &ban.StaffNote,
|
||||
&ban.Message, &ban.CanAppeal,
|
||||
&ban.IsActive, &ban.RangeStart, &ban.RangeEnd, &ban.IssuedAt, &ban.AppealAt, &ban.ExpiresAt,
|
||||
&ban.Permanent, &ban.StaffNote, &ban.Message, &ban.CanAppeal,
|
||||
); err != nil {
|
||||
rows.Close()
|
||||
return nil, err
|
||||
|
@ -199,7 +213,9 @@ func CheckNameBan(name string, boardID int) (*UsernameBan, error) {
|
|||
}
|
||||
|
||||
func NewNameBan(name string, isRegex bool, boardID int, staffID int, staffNote string) (*UsernameBan, error) {
|
||||
const query = `INSERT INTO DBPREFIXusername_ban (board_id, staff_id, staff_note, username, is_regex) VALUES(?,?,?,?,?)`
|
||||
const query = `INSERT INTO DBPREFIXusername_ban
|
||||
(board_id, staff_id, staff_note, username, is_regex)
|
||||
VALUES(?,?,?,?,?)`
|
||||
var ban UsernameBan
|
||||
if boardID > 0 {
|
||||
ban.BoardID = new(int)
|
||||
|
@ -234,7 +250,9 @@ func NewNameBan(name string, isRegex bool, boardID int, staffID int, staffNote s
|
|||
}
|
||||
|
||||
func GetNameBans(boardID int, limit int) ([]UsernameBan, error) {
|
||||
query := `SELECT id, board_id, staff_id, staff_note, issued_at, username, is_regex FROM DBPREFIXusername_ban`
|
||||
query := `SELECT
|
||||
id, board_id, staff_id, staff_note, issued_at, username, is_regex
|
||||
FROM DBPREFIXusername_ban`
|
||||
limitStr := ""
|
||||
if limit > 0 {
|
||||
limitStr = " LIMIT " + strconv.Itoa(limit)
|
||||
|
@ -446,7 +464,8 @@ func GetChecksumBans(boardID int, limit int) ([]FileBan, error) {
|
|||
}
|
||||
|
||||
func NewFileChecksumBan(checksum string, boardID int, staffID int, staffNote string) (*FileBan, error) {
|
||||
const query = `INSERT INTO DBPREFIXfile_ban (board_id, staff_id, staff_note, checksum) VALUES(?,?,?,?)`
|
||||
const query = `INSERT INTO DBPREFIXfile_ban
|
||||
(board_id, staff_id, staff_note, checksum) VALUES(?,?,?,?)`
|
||||
var ban FileBan
|
||||
var err error
|
||||
|
||||
|
|
|
@ -195,10 +195,23 @@ func (db *GCDB) QuerySQL(query string, a ...interface{}) (*sql.Rows, error) {
|
|||
func Open(host, dbDriver, dbName, username, password, prefix string) (db *GCDB, err error) {
|
||||
db = &GCDB{
|
||||
driver: dbDriver,
|
||||
replacer: strings.NewReplacer(
|
||||
}
|
||||
if dbDriver == "mysql" {
|
||||
db.replacer = strings.NewReplacer(
|
||||
"DBNAME", dbName,
|
||||
"DBPREFIX", prefix,
|
||||
"\n", " "),
|
||||
"INET_RANGE_START", "INET6_ATON(range_start)",
|
||||
"INET_RANGE_END", "INET6_ATON(range_end)",
|
||||
"INET_PARAM", "INET6_ATON(?)",
|
||||
"\n", " ")
|
||||
} else {
|
||||
db.replacer = strings.NewReplacer(
|
||||
"DBNAME", dbName,
|
||||
"DBPREFIX", prefix,
|
||||
"INET_RANGE_START", "range_start",
|
||||
"INET_RANGE_END", "range_end",
|
||||
"INET_PARAM", "?",
|
||||
"\n", " ")
|
||||
}
|
||||
|
||||
if dbDriver != "sqlite3" {
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"html/template"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
)
|
||||
|
||||
// table: DBPREFIXannouncements
|
||||
|
@ -113,13 +117,24 @@ type IPBan struct {
|
|||
BoardID *int
|
||||
BannedForPostID *int
|
||||
CopyPostText template.HTML
|
||||
IP string
|
||||
IPRangeStart string
|
||||
IPRangeEnd string
|
||||
RangeStart string
|
||||
RangeEnd string
|
||||
IssuedAt time.Time
|
||||
ipBanBase
|
||||
}
|
||||
|
||||
func (ipb *IPBan) IsBanned(ipStr string) (bool, error) {
|
||||
ipn, err := gcutil.GetIPRangeSubnet(ipb.RangeStart, ipb.RangeEnd)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
return false, errors.New("invalid IP address")
|
||||
}
|
||||
return ipn.Contains(ip), nil
|
||||
}
|
||||
|
||||
// table: DBPREFIXip_ban_audit
|
||||
type IPBanAudit struct {
|
||||
IPBanID int // sql: `ip_ban_id`
|
||||
|
|
|
@ -179,7 +179,14 @@ var funcMap = template.FuncMap{
|
|||
if err != nil || ban == nil {
|
||||
return "?"
|
||||
}
|
||||
return ban.IP
|
||||
if ban.RangeStart == ban.RangeEnd {
|
||||
return ban.RangeStart
|
||||
}
|
||||
ipn, err := gcutil.GetIPRangeSubnet(ban.RangeStart, ban.RangeEnd)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return ipn.String()
|
||||
},
|
||||
"getCatalogThumbnail": func(img string) string {
|
||||
_, catalogThumb := uploads.GetThumbnailFilenames(img)
|
||||
|
|
|
@ -192,22 +192,19 @@ func ParseIPRange(ipOrCIDR string) (string, string, error) {
|
|||
return ipStart.String(), ipStart.String(), nil
|
||||
}
|
||||
|
||||
// GetIPRangeString returns an IP address if start == end, or the subnet of all IP
|
||||
// addresses between start and end
|
||||
func GetIPRangeString(start string, end string) (string, error) {
|
||||
if start == end {
|
||||
return start, nil
|
||||
}
|
||||
// GetIPRangeSubnet returns the smallest subnet that contains the start and end
|
||||
// IP addresses, and any errors that occured
|
||||
func GetIPRangeSubnet(start string, end string) (*net.IPNet, error) {
|
||||
startIP := net.ParseIP(start)
|
||||
endIP := net.ParseIP(end)
|
||||
if startIP == nil {
|
||||
return "", fmt.Errorf("invalid IP address %s", start)
|
||||
return nil, fmt.Errorf("invalid IP address %s", start)
|
||||
}
|
||||
if endIP == nil {
|
||||
return "", fmt.Errorf("invalid IP address %s", end)
|
||||
return nil, fmt.Errorf("invalid IP address %s", end)
|
||||
}
|
||||
if len(startIP) != len(endIP) {
|
||||
return "", errors.New("ip addresses must both be IPv4 or IPv6")
|
||||
return nil, errors.New("ip addresses must both be IPv4 or IPv6")
|
||||
}
|
||||
|
||||
if startIP.To4() != nil {
|
||||
|
@ -216,7 +213,7 @@ func GetIPRangeString(start string, end string) (string, error) {
|
|||
}
|
||||
|
||||
bits := 0
|
||||
var ipn net.IPNet
|
||||
var ipn *net.IPNet
|
||||
for b := range startIP {
|
||||
if startIP[b] == endIP[b] {
|
||||
bits += 8
|
||||
|
@ -227,12 +224,11 @@ func GetIPRangeString(start string, end string) (string, error) {
|
|||
bits++
|
||||
continue
|
||||
}
|
||||
ipn = net.IPNet{IP: startIP, Mask: net.CIDRMask(bits, len(startIP)*8)}
|
||||
return ipn.String(), nil
|
||||
ipn = &net.IPNet{IP: startIP, Mask: net.CIDRMask(bits, len(startIP)*8)}
|
||||
return ipn, nil
|
||||
}
|
||||
}
|
||||
ipn = net.IPNet{IP: startIP, Mask: net.CIDRMask(bits, len(startIP)*8)}
|
||||
return ipn.String(), nil
|
||||
return &net.IPNet{IP: startIP, Mask: net.CIDRMask(bits, len(startIP)*8)}, nil
|
||||
}
|
||||
|
||||
// ParseName takes a name string from a request object and returns the name and tripcode parts
|
||||
|
|
|
@ -50,21 +50,19 @@ func registerModeratorPages() {
|
|||
}
|
||||
|
||||
} else if request.FormValue("do") == "add" {
|
||||
gcutil.LogStr("banIP", ban.IP, infoEv, errEv)
|
||||
gcutil.LogStr("reason", ban.Message, infoEv, errEv)
|
||||
if ban.Permanent {
|
||||
gcutil.LogBool("permanent", true, infoEv, errEv)
|
||||
} else {
|
||||
gcutil.LogTime("expiresAt", ban.ExpiresAt)
|
||||
}
|
||||
gcutil.LogBool("appealable", ban.CanAppeal, infoEv, errEv)
|
||||
if ban.CanAppeal {
|
||||
gcutil.LogTime("appealAt", ban.AppealAt)
|
||||
}
|
||||
err := ipBanFromRequest(&ban, request, errEv)
|
||||
ip := request.PostFormValue("ip")
|
||||
ban.RangeStart, ban.RangeEnd, err = gcutil.ParseIPRange(ip)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().
|
||||
Msg("Unable to create new ban")
|
||||
Str("ip", ip)
|
||||
return "", err
|
||||
}
|
||||
gcutil.LogStr("rangeStart", ban.RangeStart, infoEv, errEv)
|
||||
gcutil.LogStr("rangeEnd", ban.RangeEnd, infoEv, errEv)
|
||||
gcutil.LogStr("reason", ban.Message, infoEv, errEv)
|
||||
gcutil.LogBool("appealable", ban.CanAppeal, infoEv, errEv)
|
||||
err := ipBanFromRequest(&ban, request, infoEv, errEv)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
infoEv.Msg("Added IP ban")
|
||||
|
@ -74,11 +72,12 @@ func registerModeratorPages() {
|
|||
errEv.Err(err).Caller().Send()
|
||||
return "", err
|
||||
}
|
||||
if ban.IP, err = gcsql.GetPostIP(postID); err != nil {
|
||||
if ban.RangeStart, err = gcsql.GetPostIP(postID); err != nil {
|
||||
errEv.Err(err).Caller().
|
||||
Int("postID", postID).Send()
|
||||
return "", err
|
||||
}
|
||||
ban.RangeEnd = ban.RangeStart
|
||||
}
|
||||
|
||||
filterBoardIDstr := request.FormValue("filterboardid")
|
||||
|
|
|
@ -9,31 +9,39 @@ import (
|
|||
|
||||
"github.com/Eggbertx/durationutil"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func ipBanFromRequest(ban *gcsql.IPBan, request *http.Request, errEv *zerolog.Event) error {
|
||||
func ipBanFromRequest(ban *gcsql.IPBan, request *http.Request, infoEv *zerolog.Event, errEv *zerolog.Event) error {
|
||||
now := time.Now()
|
||||
banIDStr := request.FormValue("edit")
|
||||
if banIDStr != "" && request.FormValue("do") == "edit" {
|
||||
banID, err := strconv.Atoi(banIDStr)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
Str("editBanID", banIDStr).
|
||||
Caller().Send()
|
||||
errEv.Err(err).Caller().
|
||||
Str("editBanID", banIDStr).Send()
|
||||
return errors.New("invalid 'edit' field value (must be int)")
|
||||
}
|
||||
editing, err := gcsql.GetIPBanByID(banID)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
Int("editBanID", banID).
|
||||
Caller().Send()
|
||||
errEv.Err(err).Caller().
|
||||
Int("editBanID", banID).Send()
|
||||
return errors.New("Unable to get ban with id " + banIDStr + " (SQL error)")
|
||||
}
|
||||
*ban = *editing
|
||||
return nil
|
||||
}
|
||||
ban.IP = request.FormValue("ip")
|
||||
var err error
|
||||
ip := request.PostFormValue("ip")
|
||||
ban.RangeStart, ban.RangeEnd, err = gcutil.ParseIPRange(ip)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().
|
||||
Str("ip", ip)
|
||||
}
|
||||
gcutil.LogStr("rangeStart", ban.RangeStart, infoEv, errEv)
|
||||
gcutil.LogStr("rangeEnd", ban.RangeEnd, infoEv, errEv)
|
||||
|
||||
ban.Permanent = request.FormValue("permanent") == "on"
|
||||
if ban.Permanent {
|
||||
ban.ExpiresAt = now
|
||||
|
@ -55,9 +63,9 @@ func ipBanFromRequest(ban *gcsql.IPBan, request *http.Request, errEv *zerolog.Ev
|
|||
if appealWaitStr != "" {
|
||||
appealDuration, err := durationutil.ParseLongerDuration(appealWaitStr)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
errEv.Err(err).Caller().
|
||||
Str("appealwait", appealWaitStr).
|
||||
Caller().Msg("Invalid appeal delay duration string")
|
||||
Msg("Invalid appeal delay duration string")
|
||||
return err
|
||||
}
|
||||
ban.AppealAt = now.Add(appealDuration)
|
||||
|
@ -73,16 +81,18 @@ func ipBanFromRequest(ban *gcsql.IPBan, request *http.Request, errEv *zerolog.Ev
|
|||
if boardIDstr != "" && boardIDstr != "0" {
|
||||
boardID, err := strconv.Atoi(boardIDstr)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
Str("boardid", boardIDstr).
|
||||
Caller().Send()
|
||||
errEv.Err(err).Caller().
|
||||
Str("boardid", boardIDstr).Send()
|
||||
return err
|
||||
}
|
||||
gcutil.LogInt("boardID", boardID, infoEv, errEv)
|
||||
ban.BoardID = new(int)
|
||||
*ban.BoardID = boardID
|
||||
}
|
||||
ban.Message = html.EscapeString(request.FormValue("reason"))
|
||||
ban.StaffNote = html.EscapeString(request.FormValue("staffnote"))
|
||||
ban.IsActive = true
|
||||
gcutil.LogStr("banMessage", request.FormValue("reason"), infoEv, errEv)
|
||||
gcutil.LogStr("staffNote", request.FormValue("staffnote"), infoEv, errEv)
|
||||
return gcsql.NewIPBan(ban)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/Eggbertx/durationutil"
|
||||
"github.com/gochan-org/gochan/pkg/gcplugin/luautil"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
"github.com/rs/zerolog"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
@ -18,15 +19,20 @@ const (
|
|||
)
|
||||
|
||||
func luaBanIP(l *lua.LState) int {
|
||||
ban := &gcsql.IPBan{
|
||||
IP: l.CheckString(1),
|
||||
ban := &gcsql.IPBan{}
|
||||
ip := l.CheckString(1)
|
||||
var err error
|
||||
ban.RangeStart, ban.RangeEnd, err = gcutil.ParseIPRange(ip)
|
||||
if err != nil {
|
||||
l.Push(luar.New(l, err))
|
||||
return 1
|
||||
}
|
||||
|
||||
ban.IsActive = true
|
||||
ban.AppealAt = time.Now()
|
||||
ban.CanAppeal = true
|
||||
|
||||
durOrNil := l.CheckAny(2)
|
||||
var err error
|
||||
switch durOrNil.Type() {
|
||||
case lua.LTNil:
|
||||
ban.Permanent = true
|
||||
|
|
|
@ -94,7 +94,7 @@ func checkUsernameBan(post *gcsql.Post, postBoard *gcsql.Board, writer http.Resp
|
|||
return true
|
||||
}
|
||||
|
||||
func handleAppeal(writer http.ResponseWriter, request *http.Request, errEv *zerolog.Event) {
|
||||
func handleAppeal(writer http.ResponseWriter, request *http.Request, infoEv *zerolog.Event, errEv *zerolog.Event) {
|
||||
banIDstr := request.FormValue("banid")
|
||||
if banIDstr == "" {
|
||||
errEv.Caller().Msg("Appeal sent without banid field")
|
||||
|
@ -114,7 +114,8 @@ func handleAppeal(writer http.ResponseWriter, request *http.Request, errEv *zero
|
|||
server.ServeErrorPage(writer, fmt.Sprintf("Invalid banid value %q", banIDstr))
|
||||
return
|
||||
}
|
||||
errEv.Int("banID", banID)
|
||||
gcutil.LogInt("banID", banID, infoEv, errEv)
|
||||
|
||||
ban, err := gcsql.GetIPBanByID(banID)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
|
@ -124,14 +125,21 @@ func handleAppeal(writer http.ResponseWriter, request *http.Request, errEv *zero
|
|||
}
|
||||
if ban == nil {
|
||||
errEv.Caller().Msg("GetIPBanByID returned a nil ban (presumably not banned)")
|
||||
server.ServeErrorPage(writer, fmt.Sprintf("Invalid banid %d", banID))
|
||||
server.ServeErrorPage(writer, fmt.Sprintf("Invalid ban ID %d", banID))
|
||||
return
|
||||
}
|
||||
if ban.IP != gcutil.GetRealIP(request) {
|
||||
gcutil.LogStr("rangeStart", ban.RangeStart, infoEv, errEv)
|
||||
gcutil.LogStr("rangeEnd", ban.RangeEnd, infoEv, errEv)
|
||||
|
||||
isCorrectIP, err := ban.IsBanned(gcutil.GetRealIP(request))
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
server.ServeErrorPage(writer, err.Error())
|
||||
}
|
||||
if !isCorrectIP {
|
||||
errEv.Caller().
|
||||
Str("banIP", ban.IP).
|
||||
Msg("User tried to appeal a ban from a different IP")
|
||||
server.ServeErrorPage(writer, fmt.Sprintf("Invalid banid %d", banID))
|
||||
server.ServeErrorPage(writer, fmt.Sprintf("Invalid ban id", banID))
|
||||
return
|
||||
}
|
||||
if !ban.IsActive {
|
||||
|
@ -157,10 +165,6 @@ func handleAppeal(writer http.ResponseWriter, request *http.Request, errEv *zero
|
|||
return
|
||||
}
|
||||
board := request.FormValue("board")
|
||||
gcutil.LogInfo().
|
||||
Str("IP", gcutil.GetRealIP(request)).
|
||||
Int("banID", banID).
|
||||
Str("board", board).
|
||||
Msg("Appeal submitted")
|
||||
infoEv.Str("board", board).Msg("Appeal submitted")
|
||||
http.Redirect(writer, request, config.WebPath(request.FormValue("board")), http.StatusFound)
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
}
|
||||
|
||||
if request.FormValue("doappeal") != "" {
|
||||
handleAppeal(writer, request, errEv)
|
||||
handleAppeal(writer, request, infoEv, errEv)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -146,8 +146,8 @@ CREATE TABLE DBPREFIXip_ban(
|
|||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
range_start VARBINARY(16) NOT NULL,
|
||||
range_end VARBINARY(16) NOT NULL,
|
||||
range_start {inet} NOT NULL,
|
||||
range_end {inet} NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
appeal_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -146,8 +146,8 @@ CREATE TABLE DBPREFIXip_ban(
|
|||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
range_start VARBINARY(16) NOT NULL,
|
||||
range_end VARBINARY(16) NOT NULL,
|
||||
range_start INET NOT NULL,
|
||||
range_end INET NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
appeal_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -146,8 +146,8 @@ CREATE TABLE DBPREFIXip_ban(
|
|||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
range_start VARBINARY(16) NOT NULL,
|
||||
range_end VARBINARY(16) NOT NULL,
|
||||
range_start VARCHAR(45) NOT NULL,
|
||||
range_end VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
appeal_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<table border="1">
|
||||
<tr><th>Action</th><th>Appeal Text</th><th>Banned IP</th></tr>
|
||||
{{range $_,$appeal := $.appeals}}
|
||||
<tr><td><a href="{{webPath "manage/appeals"}}?approve={{$appeal.ID}}">Approve</a> | <a href="{{webPath "manage/appeals"}}?deny={{$appeal.ID}}">Deny</a></td><td>{{$appeal.AppealText}}</td><td>{{getAppealBanIP $appeal.IPBanID}}</td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{webPath "manage/appeals"}}?approve={{$appeal.ID}}">Approve</a> |
|
||||
<a href="{{webPath "manage/appeals"}}?deny={{$appeal.ID}}">Deny</a>
|
||||
</td>
|
||||
<td>{{$appeal.AppealText}}</td>
|
||||
<td>{{getAppealBanIP $appeal.IPBanID}}</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
{{end}}
|
||||
</table>
|
Loading…
Add table
Add a link
Reference in a new issue