1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-17 10:56:24 -07:00

Convert DBPREFIXposts.ip and DBPREFIXreports.ip to VARBINARY

This commit is contained in:
Eggbertx 2024-01-01 13:30:32 -08:00
parent 204ae9506f
commit 121959fa15
12 changed files with 131 additions and 30 deletions

View file

@ -1,4 +1,4 @@
Copyright (c) 2013-2023, Gochan development group
Copyright (c) 2013-2024, Gochan development group
All rights reserved.
Redistribution and use in source and binary forms, with or without

View file

@ -56,6 +56,11 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
}
var query string
var tableName string
var numConstraints int
var numColumns int
var rangeStart string
var rangeEnd string
criticalConfig := config.GetSystemCriticalConfig()
ctx := context.Background()
tx, err := dbu.db.BeginTx(ctx, &sql.TxOptions{
@ -74,7 +79,6 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
query = `SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME = 'wordfilters_board_id_fk'
AND TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'DBPREFIXwordfilters'`
var numConstraints int
if err = dbu.db.QueryRowTxSQL(tx, query, nil, []any{&numConstraints}); err != nil {
return false, err
@ -88,7 +92,6 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'DBPREFIXwordfilters'
AND COLUMN_NAME = 'board_dirs'`
var numColumns int
if err = dbu.db.QueryRowTxSQL(tx, query, nil, []any{&numColumns}); err != nil {
return false, err
}
@ -114,7 +117,6 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
rows.Close()
}()
for rows.Next() {
var tableName string
err = rows.Scan(&tableName)
if err != nil {
return false, err
@ -142,12 +144,10 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
// convert string to IP range
// convert ban IP string to IP range
if rows, err = dbu.db.QuerySQL(`SELECT id, ip FROM DBPREFIXip_ban`); err != nil {
return false, err
}
var rangeStart string
var rangeEnd string
for rows.Next() {
var id int
var ipOrCIDR string
@ -162,11 +162,82 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (bool, error) {
if _, err = dbu.db.ExecTxSQL(tx, query, rangeStart, rangeEnd, id); err != nil {
return false, err
}
query = `ALTER TABLE DBPREFIXip_ban DROP COLUMN ip`
query = `ALTER TABLE DBPREFIXip_ban DROP COLUMN IF EXISTS ip`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
}
if err = rows.Close(); err != nil {
return false, err
}
}
// Convert DBPREFIXposts.ip to from varchar to varbinary
query = `SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'DBPREFIXposts'
AND COLUMN_NAME = 'ip'
AND DATA_TYPE = 'varchar'`
if err = dbu.db.QueryRowTxSQL(tx, query, nil, []any{&numColumns}); err != nil {
return false, err
}
if numColumns == 1 {
// rename `ip` to a temporary column to then be removed
query = `ALTER TABLE DBPREFIXposts CHANGE ip ip_str varchar(45)`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
query = `ALTER TABLE DBPREFIXposts
ADD COLUMN IF NOT EXISTS ip VARBINARY(16) NOT NULL`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
// convert post IP VARCHAR(45) to VARBINARY(16)
query = `UPDATE DBPREFIXposts SET ip = INET6_ATON(ip_str)`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
query = `ALTER TABLE DBPREFIXposts DROP COLUMN IF EXISTS ip_str`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
}
// Convert DBPREFIXreports.ip to from varchar to varbinary
query = `SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'DBPREFIXreports'
AND COLUMN_NAME = 'ip'
AND DATA_TYPE = 'varchar'`
if err = dbu.db.QueryRowTxSQL(tx, query, nil, []any{&numColumns}); err != nil {
return false, err
}
if numColumns == 1 {
// rename `ip` to a temporary column to then be removed
query = `ALTER TABLE DBPREFIXreports CHANGE ip ip_str varchar(45)`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
query = `ALTER TABLE DBPREFIXreports
ADD COLUMN IF NOT EXISTS ip VARBINARY(16) NOT NULL`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
// convert post IP VARCHAR(45) to VARBINARY(16)
query = `UPDATE DBPREFIXreports SET ip = INET6_ATON(ip_str)`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
query = `ALTER TABLE DBPREFIXreports DROP COLUMN IF EXISTS ip_str`
if _, err = dbu.db.ExecTxSQL(tx, query); err != nil {
return false, err
}
}
err = nil
case "postgres":

View file

@ -2,6 +2,7 @@ package building
import (
"html/template"
"net"
"path"
"strconv"
"time"
@ -53,7 +54,7 @@ type Post struct {
IsTopPost bool `json:"-"`
BoardID int `json:"-"`
BoardDir string `json:"-"`
IP string `json:"-"`
IP net.IP `json:"-"`
Name string `json:"name"`
Tripcode string `json:"trip"`
Email string `json:"email"`

View file

@ -31,7 +31,7 @@ func NewIPBan(ban *IPBan) error {
(staff_id, board_id, banned_for_post_id, copy_post_text, is_thread_ban,
is_active, range_start, range_end, appeal_at, expires_at,
permanent, staff_note, message, can_appeal)
VALUES(?, ?, ?, ?, ?, ?, INET_PARAM_ATON, INET_PARAM_ATON, ?, ?, ?, ?, ?, ?)`
VALUES(?, ?, ?, ?, ?, ?, PARAM_ATON, PARAM_ATON, ?, ?, ?, ?, ?, ?)`
if ban.ID > 0 {
return ErrBanAlreadyInserted
}
@ -68,7 +68,7 @@ func CheckIPBan(ip string, boardID int) (*IPBan, error) {
if config.GetSystemCriticalConfig().DBtype == "sqlite3" {
query += "range_start = ? OR range_end = ?"
} else {
query += "range_start <= INET_PARAM_ATON AND INET_PARAM_ATON <= range_end"
query += "range_start <= PARAM_ATON AND PARAM_ATON <= range_end"
}
query += ` AND (board_id IS NULL OR board_id = ?) AND is_active AND
(expires_at > CURRENT_TIMESTAMP OR permanent)

View file

@ -192,6 +192,31 @@ func (db *GCDB) QuerySQL(query string, a ...interface{}) (*sql.Rows, error) {
return stmt.Query(a...)
}
/*
QueryTxSQL gets all rows from the db with the values in values[] and fills the respective pointers in out[]
Automatically escapes the given values and caches the query
Example:
tx, _ := db.Begin()
rows, err := db.QueryTxSQL(tx, "SELECT * FROM table")
if err == nil {
for rows.Next() {
var intVal int
var stringVal string
rows.Scan(&intVal, &stringVal)
// do something with intVal and stringVal
}
}
*/
func (db *GCDB) QueryTxSQL(tx *sql.Tx, query string, a ...interface{}) (*sql.Rows, error) {
stmt, err := db.PrepareSQL(query, tx)
if err != nil {
return nil, err
}
defer stmt.Close()
return stmt.Query(a...)
}
func Open(host, dbDriver, dbName, username, password, prefix string) (db *GCDB, err error) {
db = &GCDB{
driver: dbDriver,
@ -204,8 +229,10 @@ func Open(host, dbDriver, dbName, username, password, prefix string) (db *GCDB,
"RANGE_START_NTOA", "INET6_NTOA(range_start)",
"RANGE_END_ATON", "INET6_ATON(range_end)",
"RANGE_END_NTOA", "INET6_NTOA(range_end)",
"INET_PARAM_ATON", "INET6_ATON(?)",
"INET_PARAM_NTOA", "INET6_NTOA(?)",
"IP_ATON", "INET6_ATON(ip)",
"IP_NTOA", "INET6_NTOA(ip)",
"PARAM_ATON", "INET6_ATON(?)",
"PARAM_NTOA", "INET6_NTOA(?)",
"\n", " ")
} else {
db.replacer = strings.NewReplacer(
@ -215,8 +242,10 @@ func Open(host, dbDriver, dbName, username, password, prefix string) (db *GCDB,
"RANGE_START_NTOA", "range_start",
"RANGE_END_ATON", "range_end",
"RANGE_END_NTOA", "range_end",
"INET_PARAM_ATON", "?",
"INET_PARAM_NTOA", "?",
"IP_ATON", "ip",
"IP_NTOA", "ip",
"PARAM_ATON", "?",
"PARAM_NTOA", "?",
"\n", " ")
}

View file

@ -16,7 +16,7 @@ const (
SELECT board_id FROM DBPREFIXthreads WHERE id = (
SELECT thread_id FROM DBPREFIXposts WHERE id = ?))`
selectPostsBaseSQL = `SELECT
id, thread_id, is_top_post, ip, created_on, name, tripcode, is_role_signature,
id, thread_id, is_top_post, IP_NTOA, created_on, name, tripcode, is_role_signature,
email, subject, message, message_raw, password, deleted_at, is_deleted, COALESCE(banned_message,'') AS banned_message
FROM DBPREFIXposts `
)
@ -49,7 +49,7 @@ func GetPostFromID(id int, onlyNotDeleted bool) (*Post, error) {
}
func GetPostIP(postID int) (string, error) {
sql := "SELECT ip FROM DBPREFIXposts WHERE id = ?"
sql := "SELECT IP_NTOA FROM DBPREFIXposts WHERE id = ?"
var ip string
err := QueryRowSQL(sql, []interface{}{postID}, []interface{}{&ip})
return ip, err
@ -58,7 +58,7 @@ func GetPostIP(postID int) (string, error) {
// GetPostsFromIP gets the posts from the database with a matching IP address, specifying
// optionally requiring them to not be deleted
func GetPostsFromIP(ip string, limit int, onlyNotDeleted bool) ([]Post, error) {
sql := selectPostsBaseSQL + ` WHERE DBPREFIXposts.ip = ?`
sql := selectPostsBaseSQL + ` WHERE DBPREFIXposts.ip = PARAM_ATON`
if onlyNotDeleted {
sql += " AND is_deleted = FALSE"
}
@ -346,7 +346,7 @@ func (p *Post) Insert(bumpThread bool, boardID int, locked bool, stickied bool,
insertSQL := `INSERT INTO DBPREFIXposts
(thread_id, is_top_post, ip, created_on, name, tripcode, is_role_signature, email, subject,
message, message_raw, password)
VALUES(?,?,?,CURRENT_TIMESTAMP,?,?,?,?,?,?,?,?)`
VALUES(?,?,PARAM_ATON,CURRENT_TIMESTAMP,?,?,?,?,?,?,?,?)`
bumpSQL := `UPDATE DBPREFIXthreads SET last_bump = CURRENT_TIMESTAMP WHERE id = ?`
tx, err := BeginTx()

View file

@ -6,7 +6,7 @@ import "time"
// errors encountered
func CreateReport(postID int, ip string, reason string) (*Report, error) {
currentTime := time.Now()
sql := `INSERT INTO DBPREFIXreports (post_id, ip, reason, is_cleared) VALUES(?, ?, ?, FALSE)`
sql := `INSERT INTO DBPREFIXreports (post_id, ip, reason, is_cleared) VALUES(?, PARAM_ATON, ?, FALSE)`
result, err := ExecSQL(sql, postID, ip, reason)
if err != nil {
return nil, err
@ -67,7 +67,7 @@ func CheckPostReports(postID int, reason string) (bool, bool, error) {
// GetReports returns a Report array and any errors encountered. If `includeCleared` is true,
// the array will include reports that have already been dismissed
func GetReports(includeCleared bool) ([]Report, error) {
sql := `SELECT id,handled_by_staff_id,post_id,ip,reason,is_cleared FROM DBPREFIXreports`
sql := `SELECT id,handled_by_staff_id,post_id,IP_NTOA,reason,is_cleared FROM DBPREFIXreports`
if !includeCleared {
sql += ` WHERE is_cleared = FALSE`
}

View file

@ -467,7 +467,7 @@ func registerModeratorPages() {
rows, err := gcsql.QuerySQL(`SELECT id,
handled_by_staff_id as staff_id,
(SELECT username FROM DBPREFIXstaff WHERE id = DBPREFIXreports.handled_by_staff_id) as staff_user,
post_id, ip, reason, is_cleared from DBPREFIXreports WHERE is_cleared = FALSE`)
post_id, IP_NTOA, reason, is_cleared from DBPREFIXreports WHERE is_cleared = FALSE`)
if err != nil {
return nil, err
}

View file

@ -67,7 +67,7 @@ CREATE TABLE DBPREFIXposts(
id {serial pk},
thread_id {fk to serial} NOT NULL,
is_top_post BOOL NOT NULL DEFAULT FALSE,
ip VARCHAR(45) NOT NULL,
ip {inet} NOT NULL,
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
name VARCHAR(50) NOT NULL DEFAULT '',
tripcode VARCHAR(10) NOT NULL DEFAULT '',
@ -204,7 +204,7 @@ CREATE TABLE DBPREFIXreports(
id {serial pk},
handled_by_staff_id {fk to serial},
post_id {fk to serial} NOT NULL,
ip VARCHAR(45) NOT NULL,
ip {inet} NOT NULL,
reason TEXT NOT NULL,
is_cleared BOOL NOT NULL,
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),

View file

@ -67,7 +67,7 @@ CREATE TABLE DBPREFIXposts(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
thread_id BIGINT NOT NULL,
is_top_post BOOL NOT NULL DEFAULT FALSE,
ip VARCHAR(45) NOT NULL,
ip VARBINARY(16) NOT NULL,
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
name VARCHAR(50) NOT NULL DEFAULT '',
tripcode VARCHAR(10) NOT NULL DEFAULT '',
@ -204,7 +204,7 @@ CREATE TABLE DBPREFIXreports(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
handled_by_staff_id BIGINT,
post_id BIGINT NOT NULL,
ip VARCHAR(45) NOT NULL,
ip VARBINARY(16) NOT NULL,
reason TEXT NOT NULL,
is_cleared BOOL NOT NULL,
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),

View file

@ -67,7 +67,7 @@ CREATE TABLE DBPREFIXposts(
id BIGSERIAL PRIMARY KEY,
thread_id BIGINT NOT NULL,
is_top_post BOOL NOT NULL DEFAULT FALSE,
ip VARCHAR(45) NOT NULL,
ip INET NOT NULL,
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
name VARCHAR(50) NOT NULL DEFAULT '',
tripcode VARCHAR(10) NOT NULL DEFAULT '',
@ -204,7 +204,7 @@ CREATE TABLE DBPREFIXreports(
id BIGSERIAL PRIMARY KEY,
handled_by_staff_id BIGINT,
post_id BIGINT NOT NULL,
ip VARCHAR(45) NOT NULL,
ip INET NOT NULL,
reason TEXT NOT NULL,
is_cleared BOOL NOT NULL,
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),

View file

@ -24,10 +24,10 @@ if [ "$DBTYPE" == "mysql" ]; then
apt-get -y install mariadb-server mariadb-client
fi
mysql -uroot <<- EOF
CREATE USER 'gochan'@'%' IDENTIFIED BY 'gochan';
CREATE DATABASE IF NOT EXISTS gochan;
GRANT USAGE ON *.* TO gochan IDENTIFIED BY 'gochan'; \
GRANT USAGE ON *.* TO gochan; \
GRANT ALL PRIVILEGES ON gochan.* TO gochan; \
SET PASSWORD FOR 'gochan'@'%' = PASSWORD('gochan');
FLUSH PRIVILEGES;
EOF
if [ "$MYSQL_MAINLINE" == "1" ]; then