diff --git a/pkg/gcsql/bans.go b/pkg/gcsql/bans.go
index f0d4bdb3..18b5ec81 100644
--- a/pkg/gcsql/bans.go
+++ b/pkg/gcsql/bans.go
@@ -3,6 +3,7 @@ package gcsql
import (
"database/sql"
"regexp"
+ "strconv"
)
type Ban interface {
@@ -30,6 +31,45 @@ func CheckIPBan(ip string, boardID int) (*IPBan, error) {
return &ban, nil
}
+func GetIPBans(boardID int, limit int, onlyActive bool) ([]IPBan, error) {
+ 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`
+ if boardID > 0 {
+ query += " WHERE board_id = ?"
+ }
+ query += " LIMIT " + strconv.Itoa(limit)
+ var rows *sql.Rows
+ var err error
+ if boardID > 0 {
+ rows, err = QuerySQL(query, boardID)
+ } else {
+ rows, err = QuerySQL(query)
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var bans []IPBan
+ for rows.Next() {
+ 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,
+ ); err != nil {
+ return nil, err
+ }
+ if onlyActive && !ban.IsActive {
+ continue
+ }
+ bans = append(bans, ban)
+ }
+ return bans, nil
+}
+
// 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 {
return ipb.BoardID == nil
@@ -99,7 +139,9 @@ func CheckFilenameBan(filename string, boardID int) (*FilenameBan, error) {
}, nil
}
-func CheckFileBan(checksum string, boardID int) (*FileBan, error) {
+// CheckFileChecksumBan checks to see if the given checksum is banned on the given boardID, or on all boards.
+// It returns the ban info (or nil if it is not banned) and any errors
+func CheckFileChecksumBan(checksum string, boardID int) (*FileBan, error) {
const query = `SELECT
id, board_id, staff_id, staff_note, issued_at, checksum
FROM DBPREFIXfile_ban
@@ -117,6 +159,44 @@ func CheckFileBan(checksum string, boardID int) (*FileBan, error) {
return &ban, err
}
+func GetChecksumBans(boardID int, limit int) ([]FileBan, error) {
+ query := `SELECT
+ id, board_id, staff_id, staff_note, issued_at, checksum
+ FROM DBPREFIXfile_ban`
+ if boardID > 0 {
+ query += " WHERE board_id = ?"
+ }
+ query += " LIMIT " + strconv.Itoa(limit)
+ var rows *sql.Rows
+ var err error
+ if boardID > 0 {
+ rows, err = QuerySQL(query, boardID)
+ } else {
+ rows, err = QuerySQL(query)
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var bans []FileBan
+ for rows.Next() {
+ var ban FileBan
+ if err = rows.Scan(
+ &ban.ID, &ban.BoardID, &ban.StaffID, &ban.StaffNote, &ban.IssuedAt, &ban.Checksum,
+ ); err != nil {
+ return nil, err
+ }
+ bans = append(bans, ban)
+ }
+ return bans, nil
+}
+
func (fb *FileBan) IsGlobalBan() bool {
return fb.BoardID == nil
}
+
+// DeleteFileBanByID deletes the ban, given the id column value
+func DeleteFileBanByID(id int) error {
+ _, err := ExecSQL("DELETE FROM DBPREFIXfile_ban WHERE id = ?", id)
+ return err
+}
diff --git a/pkg/gcsql/boards.go b/pkg/gcsql/boards.go
index d13a470b..73b3b17b 100644
--- a/pkg/gcsql/boards.go
+++ b/pkg/gcsql/boards.go
@@ -103,6 +103,25 @@ func GetBoardFromID(id int) (*Board, error) {
return board, err
}
+// GetBoardURIs gets a list of all existing board URIs
+func GetBoardURIs() (URIS []string, err error) {
+ const sql = `SELECT uri FROM DBPREFIXboards`
+ rows, err := QuerySQL(sql)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var uris []string
+ for rows.Next() {
+ var uri string
+ if err = rows.Scan(&uri); err != nil {
+ return nil, err
+ }
+ uris = append(uris, uri)
+ }
+ return uris, nil
+}
+
// ResetBoardSectionArrays is run when the board list needs to be changed
// (board/section is added, deleted, etc)
func ResetBoardSectionArrays() error {
diff --git a/pkg/gcsql/staff.go b/pkg/gcsql/staff.go
index 86e7bbb2..d327334d 100644
--- a/pkg/gcsql/staff.go
+++ b/pkg/gcsql/staff.go
@@ -115,7 +115,7 @@ func DeactivateStaff(username string) error {
return s.SetActive(false)
}
-func getStaffUsernameFromID(id int) (string, error) {
+func GetStaffUsernameFromID(id int) (string, error) {
const query = `SELECT username FROM DBPREFIXstaff WHERE id = ?`
var username string
err := QueryRowSQL(query, interfaceSlice(id), interfaceSlice(&username))
diff --git a/pkg/gcsql/wordfilters.go b/pkg/gcsql/wordfilters.go
index 8186ce70..abc7ff47 100644
--- a/pkg/gcsql/wordfilters.go
+++ b/pkg/gcsql/wordfilters.go
@@ -102,7 +102,7 @@ func (wf *Wordfilter) OnBoard(dir string) bool {
}
func (wf *Wordfilter) StaffName() string {
- staff, err := getStaffUsernameFromID(wf.StaffID)
+ staff, err := GetStaffUsernameFromID(wf.StaffID)
if err != nil {
return "?"
}
diff --git a/pkg/gctemplates/funcs.go b/pkg/gctemplates/funcs.go
index 994b5c11..1be86424 100644
--- a/pkg/gctemplates/funcs.go
+++ b/pkg/gctemplates/funcs.go
@@ -159,6 +159,17 @@ var funcMap = template.FuncMap{
"isBanned": func(ban *gcsql.IPBan, board string) bool {
return ban.IsActive && ban.BoardID != nil
},
+ "getBoardDirFromID": func(id int) string {
+ dir, _ := gcsql.GetBoardDir(id)
+ return dir
+ },
+ "getStaffNameFromID": func(id int) string {
+ username, err := gcsql.GetStaffUsernameFromID(id)
+ if err != nil {
+ return "?"
+ }
+ return username
+ },
"getCatalogThumbnail": func(img string) string {
return gcutil.GetThumbnailPath("catalog", img)
},
diff --git a/pkg/manage/actions.go b/pkg/manage/actions.go
index 436d48ae..12a05118 100644
--- a/pkg/manage/actions.go
+++ b/pkg/manage/actions.go
@@ -211,134 +211,82 @@ var actions = []Action{
return manageRecentsBuffer.String(), nil
},
},
- /* {
- ID: "filebans",
- Title: "File bans",
+ {
+ ID: "checksumbans",
+ Title: "File checksum bans",
Permissions: ModPerms,
JSONoutput: OptionalJSON,
- Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (interface{}, error) {
- var err error
- fileBanType := request.PostForm.Get("bantype")
- delFnbStr := request.Form.Get("delfnb")
- if delFnbStr != "" {
- var delFilenameBanID int
- if delFilenameBanID, err = strconv.Atoi(delFnbStr); err != nil {
- errorEv.Err(err).
- Str("delfnb", delFnbStr).Caller().Send()
- return "", err
- }
- if err = gcsql.DeleteFilenameBanByID(delFilenameBanID); err != nil {
- errorEv.Err(err).
- Int("delfnb", delFilenameBanID).Caller().Send()
- return "", err
- }
- infoEv.Int("delFilenameBan", delFilenameBanID).Send()
- }
- delCsbStr := request.Form.Get("delcsb")
- if delCsbStr != "" {
- var delChecksumBanID int
- if delChecksumBanID, err = strconv.Atoi(delCsbStr); err != nil {
- errorEv.Err(err).
- Str("delcsb", delCsbStr).Send()
- return "", err
- }
- if err = gcsql.DeleteFileBanByID(delChecksumBanID); err != nil {
- errorEv.Err(err).
- Int("delcsb", delChecksumBanID).Send()
- return "", err
- }
- InfoEv.Int("delChecksumBan", delChecksumBanID).Send()
- }
- switch fileBanType {
- case "filename":
- // filename form used
- filename := request.PostForm.Get("filename")
- isWildcard := request.PostForm.Get("iswildcard") == "on"
- board := request.PostForm.Get("board")
- staffNote := request.PostForm.Get("staffnote")
- if filename == "" {
- err = errors.New("missing filename field in filename ban creation")
- errorEv.Err(err).Send()
- return "", err
- }
- if err = gcsql.CreateFileNameBan(filename, isWildcard, staff.Username, staffNote, board); err != nil {
- errorEv.Err(err).
- Str("filename", filename).
- Bool("iswildcard", isWildcard).
- Str("board", board).
- Str("staffnote", staffNote).Send()
- return "", err
- }
- gcutil.LogInfo().
- Str("action", "filebans").
- Str("staff", staff.Username).
- Str("newBanType", "filename").Send()
- case "checksum":
- // file checksum form used
- checksum := request.PostForm.Get("checksum")
- board := request.PostForm.Get("board")
- staffNote := request.PostForm.Get("staffnote")
- if checksum == "" {
- err = errors.New("missing checksum field in filename ban creation")
- errorEv.Err(err).Send()
- return "", err
- }
- if err = gcsql.CreateFileBan(checksum, staff.Username, staffNote, board); err != nil {
- errorEv.Err(err).
- Str("checksum", checksum).
- Str("board", board).
- Str("staffnote", staffNote).Send()
- return "", err
- }
- infoEv.Str("newBanType", "checksum").Send()
- case "":
- // no POST data sent
- default:
- err = fmt.Errorf(`invalid bantype value %q, valid values are "filename" and "checksum"`, fileBanType)
- errorEv.Err(err).Caller().Send()
- return "", err
- }
-
- filenameBans, err := gcsql.GetFilenameBans("", false)
- if err != nil {
- return "", err
- }
- checksumBans, err := gcsql.GetFileChecksumBans("")
- if err != nil {
- return "", err
- }
- if wantsJSON {
- return map[string]interface{}{
- "filenameBans": filenameBans,
- "checksumBans": checksumBans,
- }, nil
- }
-
- boardURIs, err := gcsql.GetBoardUris()
- if err != nil {
- return "", err
- }
- manageBansBuffer := bytes.NewBufferString("")
- if err = serverutil.MinifyTemplate(gctemplates.ManageFileBans, map[string]interface{}{
- "webroot": config.GetSystemCriticalConfig().WebRoot,
- "filenameBans": filenameBans,
- "checksumBans": checksumBans,
- "currentStaff": staff.Username,
- "boardURIs": boardURIs,
- }, manageBansBuffer, "text/html"); err != nil {
- errorEv.Err(err).Str("template", "manage_filebans.html").Caller().Send()
- return "", errors.New("failed executing file ban management page template: " + err.Error())
- }
- return manageBansBuffer.String(), nil
+ Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv, errEv *zerolog.Event) (output interface{}, err error) {
+ return "", gcutil.ErrNotImplemented
},
- }, */
+ },
{
- ID: "ipbans",
+ ID: "bans",
Title: "IP Bans",
Permissions: ModPerms,
JSONoutput: OptionalJSON,
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv *zerolog.Event, errEv *zerolog.Event) (output interface{}, err error) {
- return "", gcutil.ErrNotImplemented
+ var outputStr string
+ ip := request.FormValue("ip")
+ postid := request.FormValue("postid")
+ ban := gcsql.IPBan{
+ BoardID: new(int),
+ }
+ *ban.BoardID = 32
+
+ if request.FormValue("do") == "add" {
+ //
+ }
+
+ boardIDstr := request.FormValue("boardid")
+ var boardid int
+ if boardIDstr != "" {
+ if boardid, err = strconv.Atoi(boardIDstr); err != nil {
+ errEv.Err(err).
+ Str("boardid", boardIDstr).Caller().Send()
+ return "", err
+ }
+ }
+ filterBoardIDstr := request.FormValue("filterboardid")
+ var filterBoardID int
+ if filterBoardIDstr != "" {
+ if filterBoardID, err = strconv.Atoi(filterBoardIDstr); err != nil {
+ errEv.Err(err).
+ Str("filterboardid", filterBoardIDstr).Caller().Send()
+ return "", err
+ }
+ }
+ limitStr := request.FormValue("limit")
+ limit := 200
+ if limitStr != "" {
+ if limit, err = strconv.Atoi(limitStr); err != nil {
+ errEv.Err(err).
+ Str("limit", limitStr).Caller().Send()
+ return "", err
+ }
+ }
+ banlist, err := gcsql.GetIPBans(filterBoardID, limit, true)
+ if err != nil {
+ errEv.Err(err).Msg("Error getting ban list")
+ err = errors.New("Error getting ban list: " + err.Error())
+ return "", err
+ }
+ manageBansBuffer := bytes.NewBufferString("")
+
+ if err = serverutil.MinifyTemplate(gctemplates.ManageBans, map[string]interface{}{
+ "systemCritical": config.GetSystemCriticalConfig(),
+ "banlist": banlist,
+ "allBoards": gcsql.AllBoards,
+ "boardid": boardid,
+ "ip": ip,
+ "postid": postid,
+ "filterboardid": filterBoardID,
+ }, manageBansBuffer, "text/html"); err != nil {
+ errEv.Err(err).Str("template", "manage_bans.html").Caller().Send()
+ return "", errors.New("Error executing ban management page template: " + err.Error())
+ }
+ outputStr += manageBansBuffer.String()
+ return outputStr, nil
},
},
/* {
diff --git a/pkg/posting/bans.go b/pkg/posting/bans.go
index 27a0b55f..40c36dee 100644
--- a/pkg/posting/bans.go
+++ b/pkg/posting/bans.go
@@ -129,7 +129,7 @@ func checkFilenameBan(upload *gcsql.Upload, post *gcsql.Post, postBoard *gcsql.B
}
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)
+ fileBan, err := gcsql.CheckFileChecksumBan(upload.Checksum, postBoard.ID)
if err != nil {
gcutil.LogError(err).
Str("IP", post.IP).
diff --git a/templates/manage_bans.html b/templates/manage_bans.html
index 0f803120..16743311 100644
--- a/templates/manage_bans.html
+++ b/templates/manage_bans.html
@@ -1,32 +1,44 @@
-
- IP | Name!Tripcode | Reason | Staff note | Boards | Staff | Set | Expires | Permaban |
-{{range $b, $ban := $.banlist}} {{$ban.IP}} | {{$ban.Name}} | {{$ban.Reason}} | {{$ban.StaffNote}} | {{if eq $ban.Boards ""}}all boards{{else}}{{$ban.Boards}}{{end}} | {{$ban.Staff}} | {{$ban.Timestamp}} | {{if $ban.Permaban}}never{{else}}{{$ban.Expires}}{{end}} | {{$ban.Permaban}} |
+
+ IP | Board | Reason | Staff | Staff note | Banned post text | Set | Expires | Appeal at |
+{{range $_, $ban := $.banlist -}}
+
+ {{$ban.IP}} |
+ {{if not $ban.BoardID}}all{{else}}/{{getBoardDirFromID $ban.BoardID}}/{{end}} |
+ {{$ban.Message}} |
+ {{getStaffNameFromID $ban.StaffID}} |
+ {{$ban.StaffNote}} |
+ {{if not $ban.BannedForPostID}}N/A{{else}}{{$ban.CopyPostText}}{{end}} |
+ {{formatTimestamp $ban.IssuedAt}} |
+
+ {{- if $ban.Permanent}}Never{{else}}{{formatTimestamp $ban.ExpiresAt}}{{end -}}
+ |
+
+ {{- if $ban.CanAppeal}}{{formatTimestamp $ban.AppealAt}}{{else}}Never{{end -}}
+ |
+
{{end}}
\ No newline at end of file