diff --git a/pkg/gcsql/bans.go b/pkg/gcsql/bans.go index 7cefe15c..f0d4bdb3 100644 --- a/pkg/gcsql/bans.go +++ b/pkg/gcsql/bans.go @@ -98,3 +98,25 @@ func CheckFilenameBan(filename string, boardID int) (*FilenameBan, error) { filenameOrUsernameBanBase: *banBase, }, nil } + +func CheckFileBan(checksum string, boardID int) (*FileBan, error) { + const query = `SELECT + id, board_id, staff_id, staff_note, issued_at, checksum + FROM DBPREFIXfile_ban + WHERE checksum = ? AND (board_id IS NULL OR board_id = ?) ORDER BY id DESC LIMIT 1` + var ban FileBan + err := QueryRowSQL(query, interfaceSlice(checksum, boardID), interfaceSlice( + &ban.ID, &ban.BoardID, &ban.StaffID, &ban.StaffNote, &ban.IssuedAt, &ban.Checksum, + )) + if err == sql.ErrNoRows { + return nil, nil + } + if err != nil { + return nil, err + } + return &ban, err +} + +func (fb *FileBan) IsGlobalBan() bool { + return fb.BoardID == nil +} diff --git a/pkg/gcsql/tables.go b/pkg/gcsql/tables.go index 37622c49..2e057d65 100644 --- a/pkg/gcsql/tables.go +++ b/pkg/gcsql/tables.go @@ -52,12 +52,12 @@ type Board struct { // FileBan contains the information associated with a specific file ban. // table: DBPREFIXfile_ban type FileBan 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` - Checksum string `json:"checksum"` // sql: `checksum` + 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` + Checksum string // sql: `checksum` } type filenameOrUsernameBanBase struct { @@ -97,26 +97,26 @@ type Upload struct { // used to composition IPBan and IPBanAudit type ipBanBase struct { - IsActive bool `json:"is_active"` - IsThreadBan bool `json:"is_thread_ban"` - ExpiresAt time.Time `json:"expires_at"` - StaffID int `json:"staff_id"` - AppealAt time.Time `json:"appeal_at"` - Permanent bool `json:"permanent"` - StaffNote string `json:"staff_note"` - Message string `json:"message"` - CanAppeal bool `json:"can_appeal"` + IsActive bool + IsThreadBan bool + ExpiresAt time.Time + StaffID int + AppealAt time.Time + Permanent bool + StaffNote string + Message string + CanAppeal bool } // IPBan contains the information association with a specific ip ban. // table: DBPREFIXip_ban type IPBan struct { - ID int `json:"id"` - BoardID *int `json:"board"` - BannedForPostID *int `json:"banned_for_post_id"` - CopyPostText template.HTML `json:"copy_post_text"` - IP string `json:"ip"` - IssuedAt time.Time `json:"issued_at"` + ID int + BoardID *int + BannedForPostID *int + CopyPostText template.HTML + IP string + IssuedAt time.Time ipBanBase } diff --git a/pkg/posting/bans.go b/pkg/posting/bans.go index 0cdc16bd..27a0b55f 100644 --- a/pkg/posting/bans.go +++ b/pkg/posting/bans.go @@ -10,15 +10,19 @@ import ( "github.com/gochan-org/gochan/pkg/serverutil" ) -func showBanpage(ban gcsql.Ban, banType string, filename string, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) { +func showBanpage(ban gcsql.Ban, banType string, upload *gcsql.Upload, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) { // TODO: possibly split file/username/filename bans into separate page template - err := serverutil.MinifyTemplate(gctemplates.Banpage, map[string]interface{}{ + tmplMap := map[string]interface{}{ "systemCritical": config.GetSystemCriticalConfig(), "siteConfig": config.GetSiteConfig(), "boardConfig": config.GetBoardConfig(postBoard.Dir), "ban": ban, "board": postBoard, - }, writer, "text/html") + } + if upload != nil { + tmplMap["filename"] = upload.OriginalFilename + } + err := serverutil.MinifyTemplate(gctemplates.Banpage, tmplMap, writer, "text/html") if err != nil { gcutil.LogError(err). Str("IP", post.IP). @@ -42,8 +46,13 @@ func showBanpage(ban gcsql.Ban, banType string, filename string, post *gcsql.Pos Msg("Rejected post with banned name/tripcode") case "filename": ev. - Str("filename", filename). + Str("filename", upload.OriginalFilename). Msg("Rejected post with banned filename") + case "checksum": + ev. + Str("filename", upload.OriginalFilename). + Str("checksum", upload.Checksum). + Msg("Rejected post with banned checksum") } } @@ -75,7 +84,7 @@ func checkIpBan(post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWr return false // ip is not banned and there were no errors, keep going } // IP is banned - showBanpage(ipBan, "ip", "", post, postBoard, writer, request) + showBanpage(ipBan, "ip", nil, post, postBoard, writer, request) return true } @@ -97,19 +106,16 @@ func checkUsernameBan(formName string, post *gcsql.Post, postBoard *gcsql.Board, if nameBan == nil { return false // name is not banned } - showBanpage(nameBan, "username", "", post, postBoard, writer, request) + showBanpage(nameBan, "username", nil, post, postBoard, writer, request) return true } -func checkFilenameBan(filename string, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) bool { - if filename == "" { - return false - } - filenameBan, err := gcsql.CheckFilenameBan(filename, postBoard.ID) +func checkFilenameBan(upload *gcsql.Upload, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) bool { + filenameBan, err := gcsql.CheckFilenameBan(upload.OriginalFilename, postBoard.ID) if err != nil { gcutil.LogError(err). Str("IP", post.IP). - Str("filename", filename). + Str("filename", upload.OriginalFilename). Str("boardDir", postBoard.Dir). Msg("Error getting name banned status") serverutil.ServeErrorPage(writer, "Error getting filename ban info") @@ -118,6 +124,24 @@ func checkFilenameBan(filename string, post *gcsql.Post, postBoard *gcsql.Board, if filenameBan == nil { return false } - showBanpage(filenameBan, "filename", filename, post, postBoard, writer, request) + showBanpage(filenameBan, "filename", upload, post, postBoard, writer, request) + return true +} + +func checkChecksumBan(upload *gcsql.Upload, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) bool { + fileBan, err := gcsql.CheckFileBan(upload.Checksum, postBoard.ID) + if err != nil { + gcutil.LogError(err). + Str("IP", post.IP). + Str("boardDir", postBoard.Dir). + Str("checksum", upload.Checksum). + Msg("Error getting file checksum ban status") + serverutil.ServeErrorPage(writer, "Error processing file: "+err.Error()) + return true + } + if fileBan == nil { + return false + } + showBanpage(fileBan, "checksum", upload, post, postBoard, writer, request) return true }