mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-02 10:56:25 -07:00
Add filter enabling/disabling
This commit is contained in:
parent
e3a4efd9c0
commit
fa56d500b8
5 changed files with 147 additions and 30 deletions
|
@ -25,8 +25,12 @@ h1, h2 {
|
|||
table.mgmt-table {
|
||||
margin-top: 4px;
|
||||
width: 100%;
|
||||
td.table-actions {
|
||||
td.table-actions,col.row-actions,col.row-staff {
|
||||
text-align: center;
|
||||
width: 7%;
|
||||
}
|
||||
col.row-date {
|
||||
width: 20%;
|
||||
}
|
||||
th {
|
||||
padding: 4px;
|
||||
|
|
|
@ -324,8 +324,12 @@ table.mgmt-table {
|
|||
margin-top: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
table.mgmt-table td.table-actions {
|
||||
table.mgmt-table td.table-actions, table.mgmt-table col.row-actions, table.mgmt-table col.row-staff {
|
||||
text-align: center;
|
||||
width: 7%;
|
||||
}
|
||||
table.mgmt-table col.row-date {
|
||||
width: 20%;
|
||||
}
|
||||
table.mgmt-table th {
|
||||
padding: 4px;
|
||||
|
|
|
@ -5,26 +5,43 @@ import (
|
|||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
AllFilters ShowFilters = iota
|
||||
OnlyActiveFilters
|
||||
OnlyInactiveFilters
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidConditionField = errors.New("unrecognized conditional field")
|
||||
ErrInvalidMatchAction = errors.New("unrecognized filter action")
|
||||
ErrInvalidFilter = errors.New("unrecognized filter id")
|
||||
)
|
||||
|
||||
type ShowFilters int
|
||||
|
||||
func GetFilterByID(id int) (*Filter, error) {
|
||||
var filter Filter
|
||||
err := QueryRowTimeoutSQL(nil,
|
||||
`SELECT id, staff_id, staff_note, issued_at, match_action, match_detail, is_active FROM DBPREFIXfilters WHERE id = ?`,
|
||||
[]any{id}, []any{&filter.ID, &filter.StaffID, &filter.StaffNote, &filter.IssuedAt, &filter.MatchAction, &filter.MatchDetail, &filter.IsActive},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrInvalidFilter
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &filter, nil
|
||||
}
|
||||
|
||||
// GetAllFilters returns an array of all post filters, and an error if one occured
|
||||
func GetAllFilters() ([]Filter, error) {
|
||||
// GetAllFilters returns an array of all post filters, and an error if one occured. It can optionally return only the active or
|
||||
// only the inactive filters (or return all)
|
||||
func GetAllFilters(show ShowFilters) ([]Filter, error) {
|
||||
query := `SELECT id, staff_id, staff_note, issued_at, match_action, match_detail, is_active FROM DBPREFIXfilters`
|
||||
if show == OnlyActiveFilters {
|
||||
query += " WHERE is_active = TRUE"
|
||||
} else if show == OnlyInactiveFilters {
|
||||
query += " WHERE is_active = FALSE"
|
||||
}
|
||||
rows, cancel, err := QueryTimeoutSQL(nil, query)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
|
@ -133,7 +150,9 @@ func (f *Filter) BoardDirs() ([]string, error) {
|
|||
|
||||
func (f *Filter) BoardIDs() ([]int, error) {
|
||||
rows, cancel, err := QueryTimeoutSQL(nil, `SELECT board_id FROM DBPREFIXfilter_boards WHERE filter_id = ?`, f.ID)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
|
@ -150,3 +169,14 @@ func (f *Filter) BoardIDs() ([]int, error) {
|
|||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// SetFilterActive updates the filter with the given id, setting its active status and returning an error if one occured
|
||||
func SetFilterActive(id int, active bool) error {
|
||||
_, err := ExecTimeoutSQL(nil, `UPDATE DBPREFIXfilters SET is_active = ? WHERE id = ?`, active, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteFilter(id int) error {
|
||||
_, err := ExecTimeoutSQL(nil, `DELETE FROM DBPREFIXfilters WHERE id = ?`, id)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/building"
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
|
@ -36,10 +37,15 @@ var (
|
|||
{Value: "hasfile", Text: "Has file"},
|
||||
{Value: "nofile", Text: "No file"},
|
||||
{Value: "filename", Text: "Filename"},
|
||||
{Value: "filechecksum", Text: "File checksum"},
|
||||
{Value: "imgfingerprint", Text: "Image fingerprint"},
|
||||
{Value: "checksum", Text: "File checksum"},
|
||||
{Value: "ahash", Text: "Image fingerprint"},
|
||||
{Value: "useragent", Text: "User agent"},
|
||||
}
|
||||
filterActionsMap = map[string]string{
|
||||
"reject": "Reject post",
|
||||
"ban": "Ban IP",
|
||||
"log": "Log match",
|
||||
}
|
||||
)
|
||||
|
||||
func bansCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.Staff, _ bool, infoEv *zerolog.Event, errEv *zerolog.Event) (output interface{}, err error) {
|
||||
|
@ -354,12 +360,82 @@ func filtersCallback(_ http.ResponseWriter, request *http.Request, staff *gcsql.
|
|||
// doFilterAdd = request.PostFormValue("dofilteradd")
|
||||
// filterID := request.FormValue("filterid")
|
||||
// editFilter := request.FormValue("editfilter")
|
||||
// delFilter := request.FormValue("delfilter")
|
||||
disableFilterIDStr := request.FormValue("disable")
|
||||
enableFilterIDStr := request.FormValue("enable")
|
||||
if disableFilterIDStr != "" {
|
||||
disableFilterID, err := strconv.Atoi(disableFilterIDStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gcsql.SetFilterActive(disableFilterID, false)
|
||||
} else if enableFilterIDStr != "" {
|
||||
enableFilterID, err := strconv.Atoi(enableFilterIDStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gcsql.SetFilterActive(enableFilterID, true)
|
||||
}
|
||||
|
||||
showStr := request.FormValue("show")
|
||||
var show gcsql.ShowFilters
|
||||
switch showStr {
|
||||
case "active":
|
||||
show = gcsql.OnlyActiveFilters
|
||||
case "inactive":
|
||||
show = gcsql.OnlyInactiveFilters
|
||||
default:
|
||||
show = gcsql.AllFilters
|
||||
}
|
||||
|
||||
filters, err := gcsql.GetAllFilters(show)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Msg("Unable to get filter list")
|
||||
return nil, err
|
||||
}
|
||||
fieldsMap := make(map[string]string)
|
||||
for _, ff := range filterFields {
|
||||
fieldsMap[ff.Value] = ff.Text
|
||||
}
|
||||
var staffUsernames []string
|
||||
|
||||
var conditionsText []string
|
||||
for _, filter := range filters {
|
||||
if _, ok := filterActionsMap[filter.MatchAction]; !ok {
|
||||
return nil, gcsql.ErrInvalidMatchAction
|
||||
}
|
||||
conditions, err := filter.Conditions()
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Int("filterID", filter.ID).Msg("Unable to get filter conditions")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var filterConditionsText string
|
||||
for _, condition := range conditions {
|
||||
text, ok := fieldsMap[condition.Field]
|
||||
if !ok {
|
||||
return nil, gcsql.ErrInvalidConditionField
|
||||
}
|
||||
filterConditionsText += text + ","
|
||||
}
|
||||
filterConditionsText = strings.TrimRight(filterConditionsText, ",")
|
||||
conditionsText = append(conditionsText, filterConditionsText)
|
||||
|
||||
username, err := gcsql.GetStaffUsernameFromID(*filter.StaffID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
staffUsernames = append(staffUsernames, username)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err = serverutil.MinifyTemplate(gctemplates.ManageFilters, map[string]any{
|
||||
"allBoards": gcsql.AllBoards,
|
||||
"fields": filterFields,
|
||||
"allBoards": gcsql.AllBoards,
|
||||
"fields": filterFields,
|
||||
"filters": filters,
|
||||
"conditions": conditionsText,
|
||||
"actions": filterActionsMap,
|
||||
"staff": staffUsernames,
|
||||
"show": showStr,
|
||||
}, &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())
|
||||
|
|
|
@ -66,34 +66,37 @@
|
|||
</form>
|
||||
<hr/>
|
||||
<h2>Filter list</h2>
|
||||
<form action="{{webPath `/manage/filters`}}" method="GET">
|
||||
<select name="show" id="">
|
||||
<option value="all" {{if or (eq $.show `all`) (eq $.show ``)}}selected{{end}}>All filters</option>
|
||||
<option value="active" {{if eq $.show `active`}}selected{{end}}>Only active</option>
|
||||
<option value="inactive" {{if eq $.show `inactive`}}selected{{end}}>Only inactive</option>
|
||||
</select>
|
||||
<input type="submit" value="Show">
|
||||
</form>
|
||||
</form>
|
||||
<table class="mgmt-table filterlist">
|
||||
<colgroup>
|
||||
<col class="row-actions">
|
||||
<col class="filter-action">
|
||||
<col class="filter-conditions">
|
||||
<col class="staff-note">
|
||||
<col class="row-staff">
|
||||
<col class="is-active">
|
||||
<col class="row-date">
|
||||
</colgroup>
|
||||
<tr>
|
||||
<th>Actions</th><th>Filter action</th><th>Conditions</th><th>Staff</th><th>Last modified</th>
|
||||
<th>Actions</th><th>Filter action</th><th>Conditions</th><th>Staff note</th><th>Staff</th><th>Is active</th><th>Last modified</th>
|
||||
</tr>
|
||||
<!-- TODO: replace dummy data with actual data -->
|
||||
{{- range $f, $filter := $.filters -}}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{webPath `/manage/filters?edit=1`}}">Edit</a> | <a href="{{webPath `/manage/filters?delete=1`}}">Delete</a>
|
||||
</td>
|
||||
<td>Ban IP</td>
|
||||
<td>User agent, Name, Tripcode, First time poster</td>
|
||||
<td>admin</td>
|
||||
<td>2024-07-01 12:00:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{webPath `/manage/filters?edit=2`}}">Edit</a> |
|
||||
<a href="{{webPath `/manage/filters?delete=2`}}">Delete</a>
|
||||
</td>
|
||||
<td>Reject post</td>
|
||||
<td>Name, Tripcode, Email, Subject, Message body, First time poster, Not a first time poster, Is OP, Is reply, Has file, No file, Filename, File checksum, Image fingerprint, User agent</td>
|
||||
<td>admin</td>
|
||||
<td>2024-07-01 12:00:00</td>
|
||||
<td><a href="{{webPath `/manage/filters`}}?edit={{$filter.ID}}">Edit</a> | <a href="{{webPath `/manage/filters`}}?{{if $filter.IsActive}}disable{{else}}enable{{end}}={{$filter.ID}}">{{if $filter.IsActive}}Disable{{else}}Enable{{end}}</a></td>
|
||||
<td>{{index $.actions $filter.MatchAction}}</td>
|
||||
<td>{{index $.conditions $f}}</td>
|
||||
<td>{{$filter.StaffNote}}</td>
|
||||
<td>{{index $.staff $f}}</td>
|
||||
<td>{{$filter.IsActive}}</td>
|
||||
<td>{{formatTimestamp $filter.IssuedAt}}</td>
|
||||
</tr>
|
||||
{{- end -}}
|
||||
</table>
|
Loading…
Add table
Add a link
Reference in a new issue