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:
parent
204ae9506f
commit
121959fa15
12 changed files with 131 additions and 30 deletions
2
LICENSE
2
LICENSE
|
@ -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
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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", " ")
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue