1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-05 11:06:23 -07:00

Start adding filter mgmt page and some more ERD updates

This commit is contained in:
Eggbertx 2024-08-10 01:14:21 -07:00
parent a0fa938669
commit 6b3d8e8aeb
13 changed files with 506 additions and 269 deletions

View file

@ -64,4 +64,10 @@ textarea.viewlog, textarea.template-text {
display: block;
margin-left: auto;
margin-right: auto;
}
td#boardslist, td#conditions {
label {
display:block;
}
}

View file

@ -14,6 +14,7 @@ import { initFlags } from "./dom/flags";
import { initQR } from "./dom/qr";
import { getBooleanStorageVal } from "./storage";
import { replaceBrowseButton } from "./dom/uploaddata";
import "./management/filters";
export function toTop() {
window.scrollTo(0,0);

View file

@ -0,0 +1,72 @@
import $ from "jquery";
function onAddCondition(e:JQuery.ClickEvent) {
e.preventDefault();
const newFieldsetNum = $("fieldset").length + 1;
const $newFieldset = $(e.target).parents("fieldset").clone(true, true);
$newFieldset.find("legend").text(`Condition ${newFieldsetNum}`);
$newFieldset.find<HTMLInputElement>("input,select").each((_i,el) => {
const matches = /^([^0-9]+)\d+$/.exec(el.name);
if(matches !== null) {
el.name = matches[1] + newFieldsetNum;
}
});
// applyConditionEvents($newFieldset);
$newFieldset.appendTo("td#conditions");
}
function onRemoveCondition(e:JQuery.ClickEvent) {
e.preventDefault();
const $allConditionalGroups = $("fieldset.fld-cndtns");
if($allConditionalGroups.length > 1)
$(e.target).parents("fieldset").remove();
}
function onFieldChange(e:JQuery.ChangeEvent) {
const $fieldset = $(e.target).parents("fieldset");
const isCheckbox = e.target.value === "firsttime" || e.target.value === "hasfile" || e.target.value === "isop";
const noRegex = isCheckbox || e.target.value === "filechecksum" || e.target.value === "imgfingerprint";
const $searchInput = $("tr.search-cndtn input");
$searchInput.attr("type", isCheckbox?"checkbox":"text");
$fieldset.find("tr.search-cndtn th").text(isCheckbox?"":"Search");
if(noRegex) {
$fieldset.find(".regex-cndtn").hide();
} else {
$fieldset.find(".regex-cndtn").show();
}
}
function applyConditionEvents($fieldset:JQuery<HTMLElement>) {
$fieldset.find("button.add-cndtn").on("click", onAddCondition);
$fieldset.find("button.rem-cndtn").on("click", onRemoveCondition);
$fieldset.find("select.sel-field").on("change", onFieldChange);
$fieldset.find("input#allboards").on("change", () => {
$<HTMLInputElement>("td#boardslist input[type=checkbox]").each((_i, el) => {
if(el.id !== "allboards") el.disabled = $<HTMLInputElement>("input#allboards")[0].checked;
});
});
}
$(() => {
applyConditionEvents($("form#filterform fieldset.fld-cndtns"));
$<HTMLSelectElement>("select#action").on("change", e => {
switch(e.target.value) {
case "reject":
$("th#reason").parent().show();
$("th#reason").text("Reason");
break;
case "ban":
$("th#reason").parent().show();
$("th#reason").text("Ban message");
break;
case "audit":
$("th#reason").parent().hide();
break;
default:
console.log(e.target.value);
break;
}
});
});

View file

@ -362,6 +362,10 @@ textarea.viewlog, textarea.template-text {
margin-right: auto;
}
td#boardslist label, td#conditions label {
display: block;
}
.lightbox {
background: #CDCDCD;
border: 1px solid #000;

View file

@ -25,25 +25,26 @@ const (
ManageBans = "manage_bans.html"
ManageBoards = "manage_boards.html"
ManageDashboard = "manage_dashboard.html"
ManageFileBans = "manage_filebans.html"
// ManageFileBans = "manage_filebans.html"
ManageFilters = "manage_filters.html"
ManageFixThumbnails = "manage_fixthumbnails.html"
ManageIPSearch = "manage_ipsearch.html"
ManageLogin = "manage_login.html"
ManageNameBans = "manage_namebans.html"
ManageRecentPosts = "manage_recentposts.html"
ManageReports = "manage_reports.html"
ManageSections = "manage_sections.html"
ManageStaff = "manage_staff.html"
ManageTemplates = "manage_templateoverride.html"
ManageThreadAttrs = "manage_threadattrs.html"
ManageViewLog = "manage_viewlog.html"
ManageWordfilters = "manage_wordfilters.html"
MoveThreadPage = "movethreadpage.html"
PageFooter = "page_footer.html"
PageHeader = "page_header.html"
PostEdit = "post_edit.html"
PostFlag = "flag.html"
ThreadPage = "threadpage.html"
// ManageNameBans = "manage_namebans.html"
ManageRecentPosts = "manage_recentposts.html"
ManageReports = "manage_reports.html"
ManageSections = "manage_sections.html"
ManageStaff = "manage_staff.html"
ManageTemplates = "manage_templateoverride.html"
ManageThreadAttrs = "manage_threadattrs.html"
ManageViewLog = "manage_viewlog.html"
ManageWordfilters = "manage_wordfilters.html"
MoveThreadPage = "movethreadpage.html"
PageFooter = "page_footer.html"
PageHeader = "page_header.html"
PostEdit = "post_edit.html"
PostFlag = "flag.html"
ThreadPage = "threadpage.html"
)
var (
@ -89,8 +90,11 @@ var (
ManageDashboard: {
files: []string{"manage_dashboard.html"},
},
ManageFileBans: {
files: []string{"manage_filebans.html"},
// ManageFileBans: {
// files: []string{"manage_filebans.html"},
// },
ManageFilters: {
files: []string{"manage_filters.html"},
},
ManageFixThumbnails: {
files: []string{"manage_fixthumbnails.html"},
@ -101,9 +105,9 @@ var (
ManageLogin: {
files: []string{"manage_login.html"},
},
ManageNameBans: {
files: []string{"manage_namebans.html"},
},
// ManageNameBans: {
// files: []string{"manage_namebans.html"},
// },
ManageRecentPosts: {
files: []string{"manage_recentposts.html"},
},

View file

@ -2,7 +2,6 @@ package manage
import (
"bytes"
"database/sql"
"errors"
"fmt"
"net/http"
@ -665,98 +664,6 @@ func reparseHTMLCallback(_ http.ResponseWriter, _ *http.Request, _ *gcsql.Staff,
return outputStr, nil
}
func wordfiltersCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, _ bool, infoEv *zerolog.Event, errEv *zerolog.Event) (output interface{}, err error) {
managePageBuffer := bytes.NewBufferString("")
editIDstr := request.FormValue("edit")
deleteIDstr := request.FormValue("delete")
if deleteIDstr != "" {
var result sql.Result
if result, err = gcsql.ExecSQL(`DELETE FROM DBPREFIXwordfilters WHERE id = ?`, deleteIDstr); err != nil {
return err, err
}
if numRows, _ := result.RowsAffected(); numRows < 1 {
err = invalidWordfilterID(deleteIDstr)
errEv.Err(err).Caller().Send()
return err, err
}
infoEv.Str("deletedWordfilterID", deleteIDstr)
}
submitBtn := request.FormValue("dowordfilter")
switch submitBtn {
case "Edit wordfilter":
regexCheckStr := request.FormValue("isregex")
if regexCheckStr == "on" {
regexCheckStr = "1"
} else {
regexCheckStr = "0"
}
_, err = gcsql.ExecSQL(`UPDATE DBPREFIXwordfilters
SET board_dirs = ?,
staff_note = ?,
search = ?,
is_regex = ?,
change_to = ?
WHERE id = ?`,
request.FormValue("boarddirs"),
request.FormValue("staffnote"),
request.FormValue("find"),
regexCheckStr,
request.FormValue("replace"),
editIDstr)
infoEv.Str("do", "update")
case "Create new wordfilter":
_, err = gcsql.CreateWordFilter(
request.FormValue("find"),
request.FormValue("replace"),
request.FormValue("isregex") == "on",
request.FormValue("boarddirs"),
staff.ID,
request.FormValue("staffnote"))
infoEv.Str("do", "create")
case "":
infoEv.Discard()
}
if err == nil {
infoEv.
Str("find", request.FormValue("find")).
Str("replace", request.FormValue("replace")).
Str("staffnote", request.FormValue("staffnote")).
Str("boarddirs", request.FormValue("boarddirs"))
} else {
return err, err
}
wordfilters, err := gcsql.GetWordfilters()
if err != nil {
errEv.Err(err).Caller().Msg("Unable to get wordfilters")
return wordfilters, err
}
var editFilter *gcsql.Wordfilter
if editIDstr != "" {
editID := gcutil.HackyStringToInt(editIDstr)
for w, filter := range wordfilters {
if filter.ID == editID {
editFilter = &wordfilters[w]
break
}
}
}
filterMap := map[string]interface{}{
"wordfilters": wordfilters,
"edit": editFilter,
}
err = serverutil.MinifyTemplate(gctemplates.ManageWordfilters,
filterMap, managePageBuffer, "text/html")
if err != nil {
errEv.Err(err).Str("template", "manage_wordfilters.html").Caller().Send()
}
infoEv.Send()
return managePageBuffer.String(), err
}
func viewLogCallback(_ http.ResponseWriter, _ *http.Request, _ *gcsql.Staff, _ bool, _ *zerolog.Event,
errEv *zerolog.Event) (output interface{}, err error) {
logPath := path.Join(config.GetSystemCriticalConfig().LogDir, "gochan.log")
@ -840,12 +747,6 @@ func registerAdminPages() {
Permissions: AdminPerms,
Callback: reparseHTMLCallback,
},
Action{
ID: "wordfilters",
Title: "Wordfilters",
Permissions: AdminPerms,
Callback: wordfiltersCallback,
},
Action{
ID: "viewlog",
Title: "View log",

View file

@ -8,7 +8,6 @@ import (
"net"
"net/http"
"net/url"
"regexp"
"strconv"
"github.com/gochan-org/gochan/pkg/building"
@ -172,7 +171,7 @@ func appealsCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.
return manageAppealsBuffer.String(), err
}
func fileBansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv, errEv *zerolog.Event) (output interface{}, err error) {
/* func fileBansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv, errEv *zerolog.Event) (output interface{}, err error) {
delFilenameBanIDStr := request.FormValue("delfnb") // filename ban deletion
delChecksumBanIDStr := request.FormValue("delcsb") // checksum ban deletion
@ -324,9 +323,45 @@ func fileBansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql
}
outputStr := manageBansBuffer.String()
return outputStr, nil
} */
type searchField struct {
Value string
Text string
}
func nameBansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, _ bool, _, errEv *zerolog.Event) (output interface{}, err error) {
func filtersCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv, errEv *zerolog.Event) (output any, err error) {
// doFilterAdd = request.PostFormValue("dofilteradd")
// filterID := request.FormValue("filterid")
// editFilter := request.FormValue("editfilter")
// delFilter := request.FormValue("delfilter")
searchFields := []searchField{
{Value: "name", Text: "Name"},
{Value: "trip", Text: `Tripcode (excluding prefix "!")`},
{Value: "email", Text: "Email"},
{Value: "subject", Text: "Subject"},
{Value: "body", Text: "Message body"},
{Value: "firsttime", Text: "First time poster"},
{Value: "isop", Text: "OP"},
{Value: "hasfile", Text: "Has file"},
{Value: "filename", Text: "Filename"},
{Value: "filechecksum", Text: "File checksum"},
{Value: "imgfingerprint", Text: "Image fingerprint"},
{Value: "useragent", Text: "User agent"},
}
var buf bytes.Buffer
if err = serverutil.MinifyTemplate(gctemplates.ManageFilters, map[string]any{
"allBoards": gcsql.AllBoards,
"fields": searchFields,
}, &buf, "text/html"); err != nil {
errEv.Err(err).Caller().Str("template", gctemplates.ManageFilters).Send()
return "", errors.New("Unable to execute filter management template: " + err.Error())
}
return buf.String(), nil
}
/* func nameBansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, _ bool, _, errEv *zerolog.Event) (output interface{}, err error) {
doNameBan := request.FormValue("donameban")
deleteIDstr := request.FormValue("del")
if deleteIDstr != "" {
@ -376,7 +411,7 @@ func nameBansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql
return "", errors.New("Error executing name ban management page template: " + err.Error())
}
return buf.String(), nil
}
} */
func ipSearchCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, _ bool, _ *zerolog.Event, errEv *zerolog.Event) (output interface{}, err error) {
ipQuery := request.FormValue("ip")
@ -705,6 +740,98 @@ func fingerprintCallback(_ http.ResponseWriter, request *http.Request, _ *gcsql.
}, nil
}
func wordfiltersCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, _ bool, infoEv *zerolog.Event, errEv *zerolog.Event) (output interface{}, err error) {
managePageBuffer := bytes.NewBufferString("")
editIDstr := request.FormValue("edit")
deleteIDstr := request.FormValue("delete")
if deleteIDstr != "" {
var result sql.Result
if result, err = gcsql.ExecSQL(`DELETE FROM DBPREFIXwordfilters WHERE id = ?`, deleteIDstr); err != nil {
return err, err
}
if numRows, _ := result.RowsAffected(); numRows < 1 {
err = invalidWordfilterID(deleteIDstr)
errEv.Err(err).Caller().Send()
return err, err
}
infoEv.Str("deletedWordfilterID", deleteIDstr)
}
submitBtn := request.FormValue("dowordfilter")
switch submitBtn {
case "Edit wordfilter":
regexCheckStr := request.FormValue("isregex")
if regexCheckStr == "on" {
regexCheckStr = "1"
} else {
regexCheckStr = "0"
}
_, err = gcsql.ExecSQL(`UPDATE DBPREFIXwordfilters
SET board_dirs = ?,
staff_note = ?,
search = ?,
is_regex = ?,
change_to = ?
WHERE id = ?`,
request.FormValue("boarddirs"),
request.FormValue("staffnote"),
request.FormValue("find"),
regexCheckStr,
request.FormValue("replace"),
editIDstr)
infoEv.Str("do", "update")
case "Create new wordfilter":
_, err = gcsql.CreateWordFilter(
request.FormValue("find"),
request.FormValue("replace"),
request.FormValue("isregex") == "on",
request.FormValue("boarddirs"),
staff.ID,
request.FormValue("staffnote"))
infoEv.Str("do", "create")
case "":
infoEv.Discard()
}
if err == nil {
infoEv.
Str("find", request.FormValue("find")).
Str("replace", request.FormValue("replace")).
Str("staffnote", request.FormValue("staffnote")).
Str("boarddirs", request.FormValue("boarddirs"))
} else {
return err, err
}
wordfilters, err := gcsql.GetWordfilters()
if err != nil {
errEv.Err(err).Caller().Msg("Unable to get wordfilters")
return wordfilters, err
}
var editFilter *gcsql.Wordfilter
if editIDstr != "" {
editID := gcutil.HackyStringToInt(editIDstr)
for w, filter := range wordfilters {
if filter.ID == editID {
editFilter = &wordfilters[w]
break
}
}
}
filterMap := map[string]interface{}{
"wordfilters": wordfilters,
"edit": editFilter,
}
err = serverutil.MinifyTemplate(gctemplates.ManageWordfilters,
filterMap, managePageBuffer, "text/html")
if err != nil {
errEv.Err(err).Str("template", "manage_wordfilters.html").Caller().Send()
}
infoEv.Send()
return managePageBuffer.String(), err
}
func registerModeratorPages() {
actions = append(actions,
Action{
@ -721,18 +848,25 @@ func registerModeratorPages() {
Callback: appealsCallback,
},
Action{
ID: "filebans",
Title: "Filename and checksum bans",
ID: "filters",
Title: "Post filters",
Permissions: ModPerms,
JSONoutput: OptionalJSON,
Callback: fileBansCallback,
},
Action{
ID: "namebans",
Title: "Name bans",
Permissions: ModPerms,
Callback: nameBansCallback,
JSONoutput: NoJSON,
Callback: filtersCallback,
},
// Action{
// ID: "filebans",
// Title: "Filename and checksum bans",
// Permissions: ModPerms,
// JSONoutput: OptionalJSON,
// Callback: fileBansCallback,
// },
// Action{
// ID: "namebans",
// Title: "Name bans",
// Permissions: ModPerms,
// Callback: nameBansCallback,
// },
Action{
ID: "ipsearch",
Title: "IP Search",
@ -768,5 +902,11 @@ func registerModeratorPages() {
JSONoutput: AlwaysJSON,
Callback: fingerprintCallback,
},
Action{
ID: "wordfilters",
Title: "Wordfilters",
Permissions: ModPerms,
Callback: wordfiltersCallback,
},
)
}

View file

@ -1,6 +1,6 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0" version="24.7.6">
<diagram id="TVQ4taKJlGjEfO4J5nL0" name="Page-1">
<mxGraphModel dx="2097" dy="1803" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<mxGraphModel dx="2537" dy="2051" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />

View file

@ -244,34 +244,6 @@ CREATE TABLE DBPREFIXreports_audit(
FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilename_ban(
id {serial pk},
board_id {fk to serial},
staff_id {fk to serial} NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
filename VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT filename_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT filename_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXusername_ban(
id {serial pk},
board_id {fk to serial},
staff_id {fk to serial} NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
username VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT username_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT username_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXfile_ban(
id {serial pk},
board_id {fk to serial},
@ -288,9 +260,54 @@ CREATE TABLE DBPREFIXfile_ban(
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXwordfilters(
CREATE TABLE DBPREFIXfilters(
id {serial pk},
board_dirs VARCHAR(255) DEFAULT '*',
staff_id {fk to serial},
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
match_action VARCHAR(45) NOT NULL DEFAULT 'replace',
match_detail TEXT NOT NULL,
CONSTRAINT filters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
ON DELETE SET NULL
);
CREATE TABLE DBPREFIXfilter_boards(
id {serial pk},
filter_id {fk to serial} NOT NULL,
board_id {fk to serial} NOT NULL,
CONSTRAINT filter_boards_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE
CONSTRAINT filter_boards_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id)
ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilter_conditions(
id {serial pk},
filter_id {fk to serial} NOT NULL,
is_regex SMALLINT NOT NULL,
search VARCHAR(75) NOT NULL,
field VARCHAR(75) NOT NULL,
CONSTRAINT filter_conditions_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE,
CONSTRAINT wordfilter_conditions_search_check CHECK (search <> '')
);
CREATE TABLE DBPREFIXfilter_hits(
id {serial pk},
condition_id {fk to serial} NOT NULL,
post_data TEXT,
CONSTRAINT filter_hits_condition_id_fk
FOREIGN KEY(condition_id) REFERENCES DBPREFIXfilter_conditions(id)
ON DELETE CASCADE
);
CREATE TABLE DBPREFIXwordfilters(
id {serial pk},
staff_id {fk to serial} NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
@ -302,5 +319,17 @@ CREATE TABLE DBPREFIXwordfilters(
CONSTRAINT wordfilters_search_check CHECK (search <> '')
);
CREATE TABLE DBPREFIXwordfilter_boards(
id {serial pk},
filter_id {fk to serial} NOT NULL,
board_id {fk to serial} NOT NULL,
CONSTRAINT wordfilter_boards_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE
CONSTRAINT wordfilter_boards_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id)
ON DELETE CASCADE
);
INSERT INTO DBPREFIXdatabase_version(component, version)
VALUES('gochan', 3);

View file

@ -244,34 +244,6 @@ CREATE TABLE DBPREFIXreports_audit(
FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilename_ban(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
board_id BIGINT,
staff_id BIGINT NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
filename VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT filename_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT filename_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXusername_ban(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
board_id BIGINT,
staff_id BIGINT NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
username VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT username_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT username_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXfile_ban(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
board_id BIGINT,
@ -288,18 +260,50 @@ CREATE TABLE DBPREFIXfile_ban(
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXwordfilters(
CREATE TABLE DBPREFIXfilters(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
board_dirs VARCHAR(255) DEFAULT '*',
staff_id BIGINT NOT NULL,
staff_id BIGINT,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
match_action VARCHAR(45) NOT NULL DEFAULT 'replace',
match_detail TEXT NOT NULL,
CONSTRAINT filters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
ON DELETE SET NULL
);
CREATE TABLE DBPREFIXfilter_boards(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
filter_id BIGINT NOT NULL,
board_id BIGINT NOT NULL,
CONSTRAINT filter_boards_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE
CONSTRAINT filter_boards_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id)
ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilter_conditions(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
filter_id BIGINT NOT NULL,
is_regex SMALLINT NOT NULL,
search VARCHAR(75) NOT NULL,
is_regex BOOL NOT NULL,
change_to VARCHAR(75) NOT NULL,
CONSTRAINT wordfilters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
CONSTRAINT wordfilters_search_check CHECK (search <> '')
field VARCHAR(75) NOT NULL,
CONSTRAINT filter_conditions_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE,
CONSTRAINT wordfilter_conditions_search_check CHECK (search <> '')
);
CREATE TABLE DBPREFIXfilter_hits(
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
condition_id BIGINT NOT NULL,
post_data TEXT,
CONSTRAINT filter_hits_condition_id_fk
FOREIGN KEY(condition_id) REFERENCES DBPREFIXfilter_conditions(id)
ON DELETE CASCADE
);
INSERT INTO DBPREFIXdatabase_version(component, version)

View file

@ -244,34 +244,6 @@ CREATE TABLE DBPREFIXreports_audit(
FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilename_ban(
id BIGSERIAL PRIMARY KEY,
board_id BIGINT,
staff_id BIGINT NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
filename VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT filename_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT filename_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXusername_ban(
id BIGSERIAL PRIMARY KEY,
board_id BIGINT,
staff_id BIGINT NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
username VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT username_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT username_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXfile_ban(
id BIGSERIAL PRIMARY KEY,
board_id BIGINT,
@ -288,18 +260,50 @@ CREATE TABLE DBPREFIXfile_ban(
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXwordfilters(
CREATE TABLE DBPREFIXfilters(
id BIGSERIAL PRIMARY KEY,
board_dirs VARCHAR(255) DEFAULT '*',
staff_id BIGINT NOT NULL,
staff_id BIGINT,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
match_action VARCHAR(45) NOT NULL DEFAULT 'replace',
match_detail TEXT NOT NULL,
CONSTRAINT filters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
ON DELETE SET NULL
);
CREATE TABLE DBPREFIXfilter_boards(
id BIGSERIAL PRIMARY KEY,
filter_id BIGINT NOT NULL,
board_id BIGINT NOT NULL,
CONSTRAINT filter_boards_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE
CONSTRAINT filter_boards_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id)
ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilter_conditions(
id BIGSERIAL PRIMARY KEY,
filter_id BIGINT NOT NULL,
is_regex SMALLINT NOT NULL,
search VARCHAR(75) NOT NULL,
is_regex BOOL NOT NULL,
change_to VARCHAR(75) NOT NULL,
CONSTRAINT wordfilters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
CONSTRAINT wordfilters_search_check CHECK (search <> '')
field VARCHAR(75) NOT NULL,
CONSTRAINT filter_conditions_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE,
CONSTRAINT wordfilter_conditions_search_check CHECK (search <> '')
);
CREATE TABLE DBPREFIXfilter_hits(
id BIGSERIAL PRIMARY KEY,
condition_id BIGINT NOT NULL,
post_data TEXT,
CONSTRAINT filter_hits_condition_id_fk
FOREIGN KEY(condition_id) REFERENCES DBPREFIXfilter_conditions(id)
ON DELETE CASCADE
);
INSERT INTO DBPREFIXdatabase_version(component, version)

View file

@ -244,34 +244,6 @@ CREATE TABLE DBPREFIXreports_audit(
FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilename_ban(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
board_id BIGINT,
staff_id BIGINT NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
filename VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT filename_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT filename_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXusername_ban(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
board_id BIGINT,
staff_id BIGINT NOT NULL,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
username VARCHAR(255) NOT NULL,
is_regex BOOL NOT NULL,
CONSTRAINT username_ban_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
CONSTRAINT username_ban_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXfile_ban(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
board_id BIGINT,
@ -288,18 +260,50 @@ CREATE TABLE DBPREFIXfile_ban(
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
);
CREATE TABLE DBPREFIXwordfilters(
CREATE TABLE DBPREFIXfilters(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
board_dirs VARCHAR(255) DEFAULT '*',
staff_id BIGINT NOT NULL,
staff_id BIGINT,
staff_note VARCHAR(255) NOT NULL,
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
match_action VARCHAR(45) NOT NULL DEFAULT 'replace',
match_detail TEXT NOT NULL,
CONSTRAINT filters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
ON DELETE SET NULL
);
CREATE TABLE DBPREFIXfilter_boards(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
filter_id BIGINT NOT NULL,
board_id BIGINT NOT NULL,
CONSTRAINT filter_boards_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE
CONSTRAINT filter_boards_board_id_fk
FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id)
ON DELETE CASCADE
);
CREATE TABLE DBPREFIXfilter_conditions(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
filter_id BIGINT NOT NULL,
is_regex SMALLINT NOT NULL,
search VARCHAR(75) NOT NULL,
is_regex BOOL NOT NULL,
change_to VARCHAR(75) NOT NULL,
CONSTRAINT wordfilters_staff_id_fk
FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
CONSTRAINT wordfilters_search_check CHECK (search <> '')
field VARCHAR(75) NOT NULL,
CONSTRAINT filter_conditions_filter_id_fk
FOREIGN KEY(filter_id) REFERENCES DBPREFIXfilters(id)
ON DELETE CASCADE,
CONSTRAINT wordfilter_conditions_search_check CHECK (search <> '')
);
CREATE TABLE DBPREFIXfilter_hits(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
condition_id BIGINT NOT NULL,
post_data TEXT,
CONSTRAINT filter_hits_condition_id_fk
FOREIGN KEY(condition_id) REFERENCES DBPREFIXfilter_conditions(id)
ON DELETE CASCADE
);
INSERT INTO DBPREFIXdatabase_version(component, version)

View file

@ -0,0 +1,68 @@
<h2>{{with $.edit}}Edit filter{{else}}New filter{{end}}</h2>
<form id="filterform" action="{{webPath "/manage/filters"}}{{with $.edit}}?edit={{.ID}}{{end}}" method="POST">
<table>
<tr>
<th>Conditions</th>
<td id="conditions">
<fieldset class="fld-cndtns">
<legend>Condition 1</legend>
<table>
<tr class="field-cndtn">
<th>Field:</th>
<td>
<select name="field1" class="sel-field">
{{- range $_,$field := .fields}}<option value="{{$field.Value}}">{{$field.Text}}</option>{{end -}}
</select>
</td>
</tr>
<tr class="search-cndtn">
<th>Search:</th>
<td><input type="text" name="search1"></td>
</tr>
<tr class="regex-cndtn">
<th></th>
<td><label>Is regex <input type="checkbox" name="isregex1"/></label></td>
</tr>
<tr class="btns-cndtn">
<td></td>
<td>
<button class="add-cndtn">Add condition</button>
<button class="rem-cndtn">Remove condition</button>
</td>
</tr>
</table>
</fieldset>
</td>
</tr>
<tr>
<th>Action</th>
<td>
<select name="action" id="action">
<option value="reject">Reject</option>
<option value="ban">Ban IP</option>
<option value="audit">Audit</option>
</select>
</td>
</tr>
<tr>
<th id="reason">Reason</th>
<td><textarea name="reason" rows="5" cols="35"></textarea></td>
</tr>
<tr>
<th>Board(s):</th>
<td id="boardslist">
<label for="allboards">All boards <input type="checkbox" name="allboards" id="allboards"></label>
{{- range $_,$board := .allBoards -}}
<label for="board{{$board.ID}}">/{{$board.Dir}}/ - {{$board.Title}} <input type="checkbox" name="applyboard{{$board.ID}}" id="applyboard{{$board.ID}}"></label>
{{- end -}}
</td>
</tr>
</table>
<input type="submit" name="dofilter" value="Submit Filter">
</form>
<h2>Filter list</h2>
<table>
TODO
</table>