mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-06 21:46:24 -07:00
Add filename and username banning, add more de-deprecation stuff to posting/post.go
This commit is contained in:
parent
b69536b772
commit
379e846daf
10 changed files with 531 additions and 405 deletions
|
@ -1,18 +1,26 @@
|
|||
package gcsql
|
||||
|
||||
import "database/sql"
|
||||
import (
|
||||
"database/sql"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type Ban interface {
|
||||
IsGlobalBan() bool
|
||||
}
|
||||
|
||||
// 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
|
||||
func CheckIPBan(ip string) (*IPBan, error) {
|
||||
func CheckIPBan(ip string, boardID int) (*IPBan, error) {
|
||||
const query = `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
|
||||
FROM DBPREFIXip_ban WHERE ip = ? AND is_active AND (expires_at > CURRENT_TIMESTAMP OR permanent)
|
||||
FROM DBPREFIXip_ban WHERE ip = ? 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), interfaceSlice(
|
||||
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))
|
||||
|
@ -23,6 +31,70 @@ func CheckIPBan(ip string) (*IPBan, error) {
|
|||
}
|
||||
|
||||
// IsGlobalBan returns true if BoardID is a nil int, meaning they are banned on all boards, as opposed to a specific one
|
||||
func (ipb *IPBan) IsGlobalBan() bool {
|
||||
func (ipb IPBan) IsGlobalBan() bool {
|
||||
return ipb.BoardID == nil
|
||||
}
|
||||
|
||||
func checkUsernameOrFilename(usernameFilename string, check string, boardID int) (*filenameOrUsernameBanBase, error) {
|
||||
query := `SELECT
|
||||
id, board_id, staff_id, staff_note, issued_at, ` + usernameFilename + `, is_regex
|
||||
FROM DBPREFIX` + usernameFilename + `_ban WHERE (` + usernameFilename + ` = ? OR is_regex) AND (board_id IS NULL OR board_id = ?)`
|
||||
rows, err := QuerySQL(query, check, boardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var ban filenameOrUsernameBanBase
|
||||
err = rows.Scan(&ban.ID, &ban.BoardID, &ban.StaffID, &ban.StaffNote, &ban.IssuedAt, &ban.check, &ban.IsRegex)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ban.IsRegex {
|
||||
match, err := regexp.MatchString(ban.check, check)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if match {
|
||||
return &ban, nil
|
||||
}
|
||||
} else if ban.check == check {
|
||||
return &ban, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func CheckNameBan(name string, boardID int) (*UsernameBan, error) {
|
||||
banBase, err := checkUsernameOrFilename("username", name, boardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if banBase == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return &UsernameBan{
|
||||
Username: banBase.check,
|
||||
filenameOrUsernameBanBase: *banBase,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ub filenameOrUsernameBanBase) IsGlobalBan() bool {
|
||||
return ub.BoardID == nil
|
||||
}
|
||||
|
||||
func CheckFilenameBan(filename string, boardID int) (*FilenameBan, error) {
|
||||
banBase, err := checkUsernameOrFilename("filename", filename, boardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if banBase == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return &FilenameBan{
|
||||
Filename: banBase.check,
|
||||
filenameOrUsernameBanBase: *banBase,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"time"
|
||||
|
||||
|
@ -231,6 +232,18 @@ func (p *Post) GetUpload() (*Upload, error) {
|
|||
return upload, err
|
||||
}
|
||||
|
||||
// Sanitize escapes HTML strings in a post. This should be run immediately before
|
||||
// the post is inserted into the database
|
||||
func (p *Post) Sanitize() {
|
||||
if !p.sanitized {
|
||||
p.Name = html.EscapeString(p.Name)
|
||||
p.Email = html.EscapeString(p.Email)
|
||||
p.Subject = html.EscapeString(p.Subject)
|
||||
p.Password = html.EscapeString(p.Password)
|
||||
p.sanitized = true
|
||||
}
|
||||
}
|
||||
|
||||
// UnlinkUploads disassociates the post with any uploads in DBPREFIXfiles
|
||||
// that may have been uploaded with it, optionally leaving behind a "File Deleted"
|
||||
// frame where the thumbnail appeared
|
||||
|
|
|
@ -60,16 +60,22 @@ type FileBan struct {
|
|||
Checksum string `json:"checksum"` // sql: `checksum`
|
||||
}
|
||||
|
||||
type filenameOrUsernameBanBase struct {
|
||||
ID int // sql: id
|
||||
BoardID *int // sql: board_id
|
||||
StaffID int // sql: staff_id
|
||||
StaffNote string // sql: staff_note
|
||||
IssuedAt time.Time // sql: issued_at
|
||||
check string // replaced with username or filename
|
||||
IsRegex bool // sql: is_regex
|
||||
}
|
||||
|
||||
// FilenameBan represents a ban on a specific filename or filename regular expression.
|
||||
// table: DBPREFIXfilename_ban
|
||||
type FilenameBan struct {
|
||||
ID int `json:"id"` // sql: `id`
|
||||
BoardID int `json:"board_id"` // sql: `board_id`
|
||||
StaffID int `json:"staff_id"` // sql: `staff_id`
|
||||
StaffNote string `json:"staff_note"` // sql: `staff_note`
|
||||
IssuedAt time.Time `json:"issued_at"` // sql: `issued_at`
|
||||
Filename string `json:"filename"` // sql: `filename`
|
||||
IsRegex bool `json:"is_regex"` // sql: `is_regex`
|
||||
filenameOrUsernameBanBase
|
||||
Filename string // sql: `filename`
|
||||
IsRegex bool // sql: `is_regex`
|
||||
}
|
||||
|
||||
// Upload represents a file attached to a post.
|
||||
|
@ -161,6 +167,8 @@ type Post struct {
|
|||
DeletedAt time.Time // sql: `deleted_at`
|
||||
IsDeleted bool // sql: `is_deleted`
|
||||
BannedMessage string // sql: `banned_message`
|
||||
|
||||
sanitized bool
|
||||
}
|
||||
|
||||
// table: DBPREFIXreports
|
||||
|
@ -224,13 +232,8 @@ type Thread struct {
|
|||
|
||||
// table: DBPREFIXusername_ban
|
||||
type UsernameBan struct {
|
||||
ID int `json:"id"` // sql: `id`
|
||||
BoardID *int `json:"board"` // sql: `board_id`
|
||||
StaffID int `json:"staff_id"` // sql: `staff_id`
|
||||
StaffNote string `json:"staff_note"` // sql: `staff_note`
|
||||
IssuedAt time.Time `json:"issued_at"` // sql: `issued_at`
|
||||
Username string `json:"username"` // sql: `username`
|
||||
IsRegex bool `json:"is_regex"` // sql: `is_regex`
|
||||
filenameOrUsernameBanBase
|
||||
Username string // sql: `username`
|
||||
}
|
||||
|
||||
// table DBPREFIXwordfilters
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/gcsql.bak"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
)
|
||||
|
@ -12,10 +14,9 @@ const (
|
|||
FROM DBPREFIXfiles `
|
||||
)
|
||||
|
||||
// ThumbnailPath returns the thumbnail path of the upload, given an thumbnail type ("thumbnail" or "catalog")
|
||||
func (u *Upload) ThumbnailPath(thumbType string) string {
|
||||
return gcutil.GetThumbnailPath(thumbType, u.Filename)
|
||||
}
|
||||
var (
|
||||
ErrAlreadyAttached = errors.New("upload already processed")
|
||||
)
|
||||
|
||||
// GetThreadFiles gets a list of the files owned by posts in the thread, including thumbnails for convenience.
|
||||
func GetThreadFiles(post *Post) ([]Upload, error) {
|
||||
|
@ -40,3 +41,30 @@ func GetThreadFiles(post *Post) ([]Upload, error) {
|
|||
}
|
||||
return uploads, nil
|
||||
}
|
||||
|
||||
func (p *Post) AttachFile(upload *Upload) error {
|
||||
const query = `INSERT INTO DBPREFIXfiles (
|
||||
post_id, file_order, original_filename, filename, checksum, file_size,
|
||||
is_spoilered, thumbnail_width, thumbnail_height, width, height)
|
||||
VALUES(?,?,?,?,?,?,?,?,?,?,?)`
|
||||
if upload.ID > 0 {
|
||||
return ErrAlreadyAttached
|
||||
}
|
||||
uploadID, err := getNextFreeID("DBPREFIXfiles")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(query,
|
||||
&upload.PostID, &upload.FileOrder, &upload.OriginalFilename, &upload.Filename, &upload.Checksum, &upload.FileSize,
|
||||
&upload.IsSpoilered, &upload.ThumbnailWidth, &upload.ThumbnailHeight, &upload.Width, &upload.Height,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
upload.ID = uploadID
|
||||
return nil
|
||||
}
|
||||
|
||||
// ThumbnailPath returns the thumbnail path of the upload, given an thumbnail type ("thumbnail" or "catalog")
|
||||
func (u *Upload) ThumbnailPath(thumbType string) string {
|
||||
return gcutil.GetThumbnailPath(thumbType, u.Filename)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue