2020-04-29 17:44:29 -07:00
package manage
import (
"bytes"
2022-01-31 22:35:47 -08:00
"database/sql"
2020-06-06 09:28:45 -07:00
"errors"
2020-04-29 17:44:29 -07:00
"fmt"
"html"
2022-08-27 23:37:59 -07:00
"net"
2020-04-29 17:44:29 -07:00
"net/http"
2022-09-03 14:13:49 -07:00
"os"
2020-04-29 17:44:29 -07:00
"path"
"regexp"
"strconv"
2022-07-21 16:11:23 -07:00
"strings"
2020-04-29 17:44:29 -07:00
"time"
"github.com/gochan-org/gochan/pkg/building"
"github.com/gochan-org/gochan/pkg/config"
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/gochan-org/gochan/pkg/gctemplates"
"github.com/gochan-org/gochan/pkg/gcutil"
"github.com/gochan-org/gochan/pkg/posting"
"github.com/gochan-org/gochan/pkg/serverutil"
)
2020-10-10 16:17:36 -07:00
const (
// NoPerms allows anyone to access this Action
NoPerms = iota
// JanitorPerms allows anyone with at least a janitor-level account to access this Action
JanitorPerms
// ModPerms allows anyone with at least a moderator-level account to access this Action
ModPerms
// AdminPerms allows only the site administrator to view this Action
AdminPerms
)
2021-12-23 14:41:49 -08:00
const (
// NoJSON actions will return an error if JSON is requested by the user
NoJSON = iota
// OptionalJSON actions have an optional JSON output if requested
OptionalJSON
// AlwaysJSON actions always return JSON whether or not it is requested
AlwaysJSON
)
2020-04-29 17:44:29 -07:00
var (
chopPortNumRegex = regexp . MustCompile ( ` (.+|\w+):(\d+)$ ` )
)
2020-10-10 16:17:36 -07:00
// Action represents the functions accessed by staff members at /manage?action=<functionname>.
type Action struct {
2022-01-01 16:03:39 -08:00
// the string used when the user requests /manage?action=<id>
ID string ` json:"id" `
// The text shown in the staff menu and the window title
2021-12-23 14:41:49 -08:00
Title string ` json:"title" `
2022-01-01 16:03:39 -08:00
2021-12-23 14:41:49 -08:00
// Permissions represent who can access the page. 0 for anyone,
// 1 requires the user to have a janitor, mod, or admin account. 2 requires mod or admin,
// and 3 is only accessible by admins
Permissions int ` json:"perms" `
2022-01-01 16:03:39 -08:00
2022-01-16 13:30:33 -08:00
// JSONoutput sets what the action can output. If it is 0, it will throw an error if
// JSON is requested. If it is 1, it can output JSON if requested, and if 2, it always
2021-12-23 14:41:49 -08:00
// outputs JSON whether it is requested or not
JSONoutput int ` json:"jsonOutput" ` // if it can sometimes return JSON, this should still be false
2022-01-01 16:03:39 -08:00
2022-01-31 22:35:47 -08:00
// Callback executes the staff page. if wantsJSON is true, it should return an object
// to be marshalled into JSON. Otherwise, a string assumed to be valid HTML is returned.
//
// IMPORTANT: the writer parameter should only be written to if absolutely necessary (for example,
// if a redirect wouldn't work in handler.go) and even then, it should be done sparingly
2022-09-04 14:27:14 -07:00
Callback func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) ` json:"-" `
2020-04-29 17:44:29 -07:00
}
2022-01-01 16:03:39 -08:00
var actions = [ ] Action {
2022-01-07 14:44:42 -08:00
{
ID : "logout" ,
Title : "Logout" ,
Permissions : JanitorPerms ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-09-03 15:25:50 -07:00
if err = gcsql . EndStaffSession ( writer , request ) ; err != nil {
return "" , err
}
2022-01-31 22:35:47 -08:00
http . Redirect ( writer , request ,
config . GetSystemCriticalConfig ( ) . WebRoot + "manage" ,
http . StatusSeeOther )
return "Logged out successfully" , nil
2022-01-07 14:44:42 -08:00
} } ,
2022-01-31 22:35:47 -08:00
{
ID : "clearmysessions" ,
Title : "Log me out everywhere" ,
Permissions : JanitorPerms ,
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-31 22:35:47 -08:00
session , err := request . Cookie ( "sessiondata" )
if err != nil {
// doesn't have a login session cookie, return with no errors
if ! wantsJSON {
http . Redirect ( writer , request ,
config . GetSystemCriticalConfig ( ) . WebRoot + "manage" ,
http . StatusSeeOther )
return
}
return "You are not logged in" , nil
}
2022-09-04 14:27:14 -07:00
_ , err = gcsql . GetStaffBySession ( session . Value )
2022-01-31 22:35:47 -08:00
if err != nil {
// staff session doesn't exist, probably a stale cookie
if ! wantsJSON {
http . Redirect ( writer , request ,
config . GetSystemCriticalConfig ( ) . WebRoot + "manage" ,
http . StatusSeeOther )
return
}
return "You are not logged in" , err
}
numSessions , err := staff . CleanSessions ( )
if err != nil && err != sql . ErrNoRows {
2022-09-04 14:27:14 -07:00
// something went wrong when trying to clean out sessions for this user
2022-01-31 22:35:47 -08:00
return nil , err
}
serverutil . DeleteCookie ( writer , request , "sessiondata" )
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "clearSessions" , staff . Username ) .
Int64 ( "cleared" , numSessions )
2022-01-31 22:35:47 -08:00
if ! wantsJSON {
http . Redirect ( writer , request ,
config . GetSystemCriticalConfig ( ) . WebRoot + "manage" ,
http . StatusSeeOther )
return "" , nil
}
return "Logged out successfully" , nil
} ,
} ,
2022-01-01 16:03:39 -08:00
{
ID : "cleanup" ,
2020-04-29 17:44:29 -07:00
Title : "Cleanup" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-29 23:47:13 -08:00
outputStr := ""
2020-04-29 17:44:29 -07:00
if request . FormValue ( "run" ) == "Run Cleanup" {
2021-12-22 21:13:04 -08:00
outputStr += "Removing deleted posts from the database.<hr />"
2020-04-29 17:44:29 -07:00
if err = gcsql . PermanentlyRemoveDeletedPosts ( ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "cleanup" , "removeDeletedPosts" ) .
Str ( "action" , "cleanup" ) .
Str ( "IP" , gcutil . GetRealIP ( request ) )
err = errors . New ( "Error removing deleted posts from database: " + err . Error ( ) )
2021-12-22 21:13:04 -08:00
return outputStr + "<tr><td>" + err . Error ( ) + "</td></tr></table>" , err
2020-04-29 17:44:29 -07:00
}
2021-12-22 21:13:04 -08:00
outputStr += "Optimizing all tables in database.<hr />"
2020-04-29 17:44:29 -07:00
err = gcsql . OptimizeDatabase ( )
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "sql" , "optimization" ) .
Str ( "action" , "cleanup" ) .
Str ( "staff" , staff . Username ) . Send ( )
err = errors . New ( "Error optimizing SQL tables: " + err . Error ( ) )
2021-12-22 21:13:04 -08:00
return outputStr + "<tr><td>" + err . Error ( ) + "</td></tr></table>" , err
2020-04-29 17:44:29 -07:00
}
2021-12-22 21:13:04 -08:00
outputStr += "Cleanup finished"
2020-04-29 17:44:29 -07:00
} else {
2021-12-22 21:13:04 -08:00
outputStr += ` <form action="/manage?action=cleanup" method="post"> ` +
2020-04-29 17:44:29 -07:00
` <input name="run" id="run" type="submit" value="Run Cleanup" /> ` +
` </form> `
}
2021-12-22 21:13:04 -08:00
return outputStr , nil
2020-04-29 17:44:29 -07:00
} } ,
2022-01-07 14:44:42 -08:00
{
ID : "recentposts" ,
Title : "Recent posts" ,
Permissions : JanitorPerms ,
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-07 14:44:42 -08:00
limit := gcutil . HackyStringToInt ( request . FormValue ( "limit" ) )
if limit == 0 {
limit = 50
}
recentposts , err := gcsql . GetRecentPostsGlobal ( limit , false ) //only uses boardname, boardid, postid, parentid, message, ip and timestamp
2022-01-29 23:47:13 -08:00
if wantsJSON || err != nil {
2022-01-07 14:44:42 -08:00
return recentposts , err
}
2022-01-29 23:47:13 -08:00
manageRecentsBuffer := bytes . NewBufferString ( "" )
2022-09-04 14:27:14 -07:00
if err = serverutil . MinifyTemplate ( gctemplates . ManageRecentPosts , map [ string ] interface { } {
"recentposts" : recentposts ,
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
} , manageRecentsBuffer , "text/html" ) ; err != nil {
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "recentposts" ) . Send ( )
return "" , errors . New ( "Error executing ban management page template: " + err . Error ( ) )
2022-01-07 14:44:42 -08:00
}
2022-01-29 23:47:13 -08:00
return manageRecentsBuffer . String ( ) , nil
2022-01-07 14:44:42 -08:00
} } ,
2022-09-15 21:37:56 -07:00
{
ID : "filebans" ,
Title : "File bans" ,
Permissions : ModPerms ,
JSONoutput : OptionalJSON ,
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( interface { } , error ) {
2022-09-15 22:50:45 -07:00
errorEv := gcutil . LogError ( nil ) .
Str ( "action" , "filebans" ) .
Str ( "staff" , staff . Username )
defer errorEv . Discard ( )
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 ) . Send ( )
return "" , err
}
if err = gcsql . DeleteFilenameBanByID ( delFilenameBanID ) ; err != nil {
errorEv . Err ( err ) .
Int ( "delfnb" , delFilenameBanID ) . Send ( )
return "" , err
}
gcutil . LogInfo ( ) .
Str ( "action" , "filebans" ) .
Str ( "staff" , staff . Username ) .
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
}
gcutil . LogInfo ( ) .
Str ( "action" , "filebans" ) .
Str ( "staff" , staff . Username ) .
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
}
gcutil . LogInfo ( ) .
Str ( "action" , "filebans" ) .
Str ( "staff" , staff . Username ) .
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 ) . Send ( )
return "" , err
}
2022-09-15 21:37:56 -07:00
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
}
2022-09-15 22:50:45 -07:00
2022-09-15 21:37:56 -07:00
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 ,
2022-09-15 22:50:45 -07:00
"currentStaff" : staff . Username ,
2022-09-15 21:37:56 -07:00
"boardURIs" : boardURIs ,
} , manageBansBuffer , "text/html" ) ; err != nil {
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "filebans" ) .
Str ( "template" , "manage_filebans.html" ) .
Msg ( "failed executing file ban management page template" )
return "" , errors . New ( "failed executing file ban management page template: " + err . Error ( ) )
}
return manageBansBuffer . String ( ) , nil
} ,
} ,
{
ID : "ipbans" ,
Title : "IP Bans" ,
Permissions : ModPerms ,
JSONoutput : OptionalJSON ,
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
return "" , gcutil . ErrNotImplemented
} ,
} ,
2022-01-07 14:44:42 -08:00
{
ID : "bans" ,
Title : "Bans" ,
Permissions : ModPerms ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) { //TODO whatever this does idk man
2022-01-07 14:44:42 -08:00
var outputStr string
var post gcsql . Post
2022-09-04 14:27:14 -07:00
errorEv := gcutil . LogError ( nil ) .
Str ( "action" , "bans" ) .
Str ( "staff" , staff . Username )
defer errorEv . Discard ( )
2022-01-07 14:44:42 -08:00
if request . FormValue ( "do" ) == "add" {
ip := request . FormValue ( "ip" )
name := request . FormValue ( "name" )
nameIsRegex := ( request . FormValue ( "nameregex" ) == "on" )
checksum := request . FormValue ( "checksum" )
filename := request . FormValue ( "filename" )
durationForm := request . FormValue ( "duration" )
permaban := ( durationForm == "" || durationForm == "0" || durationForm == "forever" )
duration , err := gcutil . ParseDurationString ( durationForm )
if err != nil {
2022-09-15 22:50:45 -07:00
errorEv . Err ( err ) . Send ( )
2022-01-07 14:44:42 -08:00
return "" , err
}
expires := time . Now ( ) . Add ( duration )
boards := request . FormValue ( "boards" )
reason := html . EscapeString ( request . FormValue ( "reason" ) )
staffNote := html . EscapeString ( request . FormValue ( "staffnote" ) )
if filename != "" {
2022-09-15 22:50:45 -07:00
err = gcsql . CreateFileNameBan ( filename , nameIsRegex , staff . Username , staffNote , boards )
2022-01-07 14:44:42 -08:00
}
if err != nil {
outputStr += err . Error ( )
2022-09-15 22:50:45 -07:00
errorEv . Err ( err ) . Send ( )
2022-01-07 14:44:42 -08:00
err = nil
}
if name != "" {
2022-09-04 14:27:14 -07:00
if err = gcsql . CreateUserNameBan ( name , nameIsRegex , staff . Username , permaban , staffNote , boards ) ; err != nil {
errorEv .
Str ( "banType" , "username" ) .
Str ( "user" , name ) . Send ( )
2022-01-07 14:44:42 -08:00
return "" , err
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "action" , "bans" ) .
Str ( "staff" , staff . Username ) .
Str ( "banType" , "username" ) .
Str ( "user" , name ) .
Bool ( "permaban" , permaban ) . Send ( )
2022-01-07 14:44:42 -08:00
}
if request . FormValue ( "fullban" ) == "on" {
2022-09-04 14:27:14 -07:00
err = gcsql . CreateUserBan ( ip , false , staff . Username , boards , expires , permaban , staffNote , reason , true , time . Now ( ) )
2022-01-07 14:44:42 -08:00
if err != nil {
2022-09-04 14:27:14 -07:00
errorEv .
Str ( "banType" , "ip" ) .
Str ( "banIP" , ip ) .
Bool ( "threadBan" , false ) .
Str ( "bannedFromBoards" , boards ) . Send ( )
2022-01-07 14:44:42 -08:00
return "" , err
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "staff" , staff . Username ) .
Str ( "banType" , "ip" ) .
Str ( "banIP" , ip ) .
Bool ( "threadBan" , true ) .
Str ( "bannedFromBoards" , boards ) . Send ( )
2022-01-07 14:44:42 -08:00
} else {
if request . FormValue ( "threadban" ) == "on" {
2022-09-04 14:27:14 -07:00
err = gcsql . CreateUserBan ( ip , true , staff . Username , boards , expires , permaban , staffNote , reason , true , time . Now ( ) )
2022-01-07 14:44:42 -08:00
if err != nil {
2022-09-04 14:27:14 -07:00
errorEv .
Str ( "banType" , "ip" ) .
Str ( "banIP" , ip ) .
Bool ( "threadBan" , true ) .
Str ( "bannedFromBoards" , boards ) . Send ( )
2022-01-07 14:44:42 -08:00
return "" , err
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "staff" , staff . Username ) .
Str ( "banType" , "ip" ) .
Str ( "banIP" , ip ) .
Bool ( "threadBan" , true ) .
Str ( "bannedFromBoards" , boards ) . Send ( )
2022-01-07 14:44:42 -08:00
}
if request . FormValue ( "imageban" ) == "on" {
2022-09-15 22:50:45 -07:00
err = gcsql . CreateFileBan ( checksum , staff . Username , staffNote , boards )
2022-01-07 14:44:42 -08:00
if err != nil {
2022-09-04 14:27:14 -07:00
errorEv .
Str ( "banType" , "fileBan" ) .
Str ( "checksum" , checksum ) . Send ( )
2022-01-07 14:44:42 -08:00
return "" , err
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "staff" , staff . Username ) .
Str ( "banType" , "fileBan" ) .
Str ( "checksum" , checksum ) . Send ( )
2022-01-07 14:44:42 -08:00
}
}
}
if request . FormValue ( "postid" ) != "" {
var err error
2022-08-28 11:55:08 -07:00
post , err = gcsql . GetSpecificPostByString ( request . FormValue ( "postid" ) , true )
2022-01-07 14:44:42 -08:00
if err != nil {
2022-09-04 14:27:14 -07:00
errorEv . Err ( err ) . Str ( "postid" , request . FormValue ( "postid" ) ) . Msg ( "Error getting post" )
2022-01-07 14:44:42 -08:00
err = errors . New ( "Error getting post: " + err . Error ( ) )
return "" , err
}
}
banlist , err := gcsql . GetAllBans ( )
if err != nil {
2022-09-04 14:27:14 -07:00
errorEv . Err ( err ) . Msg ( "Error getting ban list" )
2022-01-07 14:44:42 -08:00
err = errors . New ( "Error getting ban list: " + err . Error ( ) )
return "" , err
}
manageBansBuffer := bytes . NewBufferString ( "" )
2022-09-04 14:27:14 -07:00
if err = serverutil . MinifyTemplate ( gctemplates . ManageBans , map [ string ] interface { } {
// "systemCritical": config.GetSystemCriticalConfig(),
"banlist" : banlist ,
"post" : post ,
} , manageBansBuffer , "text/html" ) ; err != nil {
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "bans" ) .
Str ( "template" , "manage_bans.html" ) . Send ( )
return "" , errors . New ( "Error executing ban management page template: " + err . Error ( ) )
2022-01-07 14:44:42 -08:00
}
outputStr += manageBansBuffer . String ( )
return outputStr , nil
} } ,
2022-08-27 23:37:59 -07:00
{
ID : "ipsearch" ,
Title : "IP Search" ,
Permissions : ModPerms ,
JSONoutput : NoJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-08-27 23:37:59 -07:00
ipQuery := request . Form . Get ( "ip" )
limitStr := request . Form . Get ( "limit" )
data := map [ string ] interface { } {
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
"ipQuery" : ipQuery ,
"limit" : 10 ,
}
if ipQuery != "" && limitStr != "" {
var limit int
if limit , err = strconv . Atoi ( request . Form . Get ( "limit" ) ) ; err != nil || limit < 1 {
limit = 20
}
data [ "limit" ] = limit
var names [ ] string
if names , err = net . LookupAddr ( ipQuery ) ; err == nil {
data [ "reverseAddrs" ] = names
} else {
data [ "reverseAddrs" ] = [ ] string { err . Error ( ) }
}
data [ "posts" ] , err = gcsql . GetPostsFromIP ( ipQuery , limit , true )
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "ipsearch" ) .
Str ( "ipQuery" , ipQuery ) .
Int ( "limit" , limit ) .
Bool ( "onlyNotDeleted" , true ) . Send ( )
return "" , fmt . Errorf ( "Error getting list of posts from %q by staff %s: %s" , ipQuery , staff . Username , err . Error ( ) )
2022-08-27 23:37:59 -07:00
}
}
manageIpBuffer := bytes . NewBufferString ( "" )
if err = serverutil . MinifyTemplate ( gctemplates . ManageIPSearch , data , manageIpBuffer , "text/html" ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "ipsearch" ) .
Str ( "template" , "manage_ipsearch.html" ) . Send ( )
return "" , errors . New ( "Error executing IP search page template:" + err . Error ( ) )
2022-08-27 23:37:59 -07:00
}
return manageIpBuffer . String ( ) , nil
} } ,
2022-07-26 12:13:27 -07:00
{
ID : "reports" ,
Title : "Reports" ,
Permissions : ModPerms ,
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-07-27 11:19:03 -07:00
dismissIDstr := request . FormValue ( "dismiss" )
if dismissIDstr != "" {
// staff is dismissing a report
dismissID := gcutil . HackyStringToInt ( dismissIDstr )
block := request . FormValue ( "block" )
if block != "" && staff . Rank != 3 {
serveError ( writer , "permission" , "reports" , "Only the administrator can block reports" , wantsJSON )
2022-09-04 14:27:14 -07:00
gcutil . LogWarning ( ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "reports" ) .
Int ( "postID" , dismissID ) .
Str ( "rejected" , "not an admin" ) . Send ( )
2022-07-27 11:19:03 -07:00
return "" , nil
}
found , err := gcsql . ClearReport ( dismissID , staff . ID , block != "" && staff . Rank == 3 )
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "reports" ) .
Int ( "postID" , dismissID ) . Send ( )
2022-07-27 11:19:03 -07:00
return nil , err
}
if ! found {
return nil , errors . New ( "no matching reports" )
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "reports" ) .
Int ( "reportID" , dismissID ) .
Bool ( "blocked" , block != "" ) .
Msg ( "Report cleared" )
2022-07-27 11:19:03 -07:00
}
2022-07-26 12:13:27 -07:00
rows , err := gcsql . QuerySQL ( ` SELECT id ,
handled_by_staff_id as staff_id ,
( SELECT username FROM DBPREFIXstaff WHERE id = DBPREFIXreports . handled_by_staff_id ) as staff_user ,
post_id , ip , reason , is_cleared from DBPREFIXreports WHERE is_cleared = 0 ` )
if err != nil {
return nil , err
}
2022-07-27 11:19:03 -07:00
reports := make ( [ ] map [ string ] interface { } , 0 )
2022-07-26 12:13:27 -07:00
for rows . Next ( ) {
var id int
var staff_id interface { }
var staff_user [ ] byte
var post_id int
var ip string
var reason string
2022-07-27 11:19:03 -07:00
var is_cleared int
2022-07-26 12:13:27 -07:00
err = rows . Scan ( & id , & staff_id , & staff_user , & post_id , & ip , & reason , & is_cleared )
if err != nil {
return nil , err
}
post , err := gcsql . GetSpecificPost ( post_id , true )
if err != nil {
return nil , err
}
2022-08-01 16:08:57 -07:00
2022-07-26 12:13:27 -07:00
staff_id_int , _ := staff_id . ( int64 )
reports = append ( reports , map [ string ] interface { } {
"id" : id ,
"staff_id" : int ( staff_id_int ) ,
"staff_user" : string ( staff_user ) ,
"post_link" : post . GetURL ( false ) ,
"ip" : ip ,
"reason" : reason ,
"is_cleared" : is_cleared ,
} )
}
if wantsJSON {
return reports , err
}
reportsBuffer := bytes . NewBufferString ( "" )
2022-07-27 11:19:03 -07:00
err = serverutil . MinifyTemplate ( gctemplates . ManageReports ,
2022-07-26 12:13:27 -07:00
map [ string ] interface { } {
"reports" : reports ,
2022-07-27 11:19:03 -07:00
"staff" : staff ,
} , reportsBuffer , "text/html" )
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "reports" ) . Send ( )
2022-07-27 11:19:03 -07:00
return "" , err
2022-07-26 12:13:27 -07:00
}
output = reportsBuffer . String ( )
return
} } ,
2022-01-01 16:03:39 -08:00
{
2022-01-07 14:44:42 -08:00
ID : "staff" ,
Title : "Staff" ,
Permissions : AdminPerms ,
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-07 14:44:42 -08:00
var outputStr string
do := request . FormValue ( "do" )
allStaff , err := gcsql . GetAllStaffNopass ( true )
if wantsJSON {
return allStaff , err
}
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "staff" ) .
Msg ( "Error getting staff list" )
err = errors . New ( "Error getting staff list: " + err . Error ( ) )
2021-12-22 21:13:04 -08:00
return "" , err
2021-11-29 21:53:47 -08:00
}
2022-01-07 14:44:42 -08:00
for _ , staff := range allStaff {
username := request . FormValue ( "username" )
password := request . FormValue ( "password" )
rank := request . FormValue ( "rank" )
rankI , _ := strconv . Atoi ( rank )
if do == "add" {
if err = gcsql . NewStaff ( username , password , rankI ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "staff" ) .
Str ( "newStaff" , username ) .
Str ( "newPass" , password ) .
Int ( "newRank" , rankI ) .
Msg ( "Error creating new staff account" )
return "" , fmt . Errorf ( "Error creating new staff account %q by %q: %s" ,
username , staff . Username , err . Error ( ) )
2022-01-07 14:44:42 -08:00
}
} else if do == "del" && username != "" {
if err = gcsql . DeleteStaff ( username ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "staff" ) .
Str ( "delStaff" , username ) .
Msg ( "Error deleting staff account" )
return "" , fmt . Errorf ( "Error deleting staff account %q by %q: %s" ,
username , staff . Username , err . Error ( ) )
2022-01-07 14:44:42 -08:00
}
}
2022-09-03 16:19:31 -07:00
allStaff , err = gcsql . GetAllStaffNopass ( true )
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "staff" ) .
Msg ( "Error getting updated staff list" )
err = errors . New ( "Error getting updated staff list: " + err . Error ( ) )
2022-09-03 16:19:31 -07:00
return "" , err
}
2022-01-07 14:44:42 -08:00
switch {
case staff . Rank == 3 :
rank = "admin"
case staff . Rank == 2 :
rank = "mod"
case staff . Rank == 1 :
rank = "janitor"
}
}
staffBuffer := bytes . NewBufferString ( "" )
2022-09-04 14:27:14 -07:00
if err = serverutil . MinifyTemplate ( gctemplates . ManageStaff , map [ string ] interface { } {
"allstaff" : allStaff ,
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
"currentUsername" : staff . Username ,
} , staffBuffer , "text/html" ) ; err != nil {
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "staff" ) .
Str ( "template" , "manage_staff.html" ) . Send ( )
return "" , errors . New ( "Error executing staff management page template: " + err . Error ( ) )
2022-01-07 14:44:42 -08:00
}
outputStr += staffBuffer . String ( )
return outputStr , nil
2021-11-29 21:53:47 -08:00
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "login" ,
2020-04-29 17:44:29 -07:00
Title : "Login" ,
2020-10-10 16:17:36 -07:00
Permissions : NoPerms ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2021-07-11 11:51:29 -07:00
systemCritical := config . GetSystemCriticalConfig ( )
2022-09-04 14:27:14 -07:00
if staff . Rank > 0 {
2021-07-11 11:51:29 -07:00
http . Redirect ( writer , request , path . Join ( systemCritical . WebRoot , "manage" ) , http . StatusFound )
2020-04-29 17:44:29 -07:00
}
username := request . FormValue ( "username" )
password := request . FormValue ( "password" )
redirectAction := request . FormValue ( "action" )
2022-01-04 17:48:46 -08:00
if redirectAction == "" || redirectAction == "logout" {
2022-01-07 14:44:42 -08:00
redirectAction = "dashboard"
2020-04-29 17:44:29 -07:00
}
2022-01-04 17:48:46 -08:00
2020-04-29 17:44:29 -07:00
if username == "" || password == "" {
//assume that they haven't logged in
2022-01-04 17:48:46 -08:00
manageLoginBuffer := bytes . NewBufferString ( "" )
2022-09-04 14:27:14 -07:00
if err = serverutil . MinifyTemplate ( gctemplates . ManageLogin , map [ string ] interface { } {
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
"site_config" : config . GetSiteConfig ( ) ,
"sections" : gcsql . AllSections ,
"boards" : gcsql . AllBoards ,
"board_config" : config . GetBoardConfig ( "" ) ,
"redirect" : redirectAction ,
} , manageLoginBuffer , "text/html" ) ; err != nil {
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "login" ) .
Str ( "template" , "manage_login.html" ) . Send ( )
return "" , errors . New ( "Error executing staff login page template: " + err . Error ( ) )
2022-01-04 17:48:46 -08:00
}
output = manageLoginBuffer . String ( )
2020-04-29 17:44:29 -07:00
} else {
2021-07-11 11:51:29 -07:00
key := gcutil . Md5Sum ( request . RemoteAddr + username + password + systemCritical . RandomSeed + gcutil . RandomString ( 3 ) ) [ 0 : 10 ]
2020-04-29 17:44:29 -07:00
createSession ( key , username , password , request , writer )
2021-07-11 11:51:29 -07:00
http . Redirect ( writer , request , path . Join ( systemCritical . WebRoot , "manage?action=" + request . FormValue ( "redirect" ) ) , http . StatusFound )
2020-04-29 17:44:29 -07:00
}
return
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "announcements" ,
2020-04-29 17:44:29 -07:00
Title : "Announcements" ,
2020-10-10 16:17:36 -07:00
Permissions : JanitorPerms ,
2022-01-07 14:44:42 -08:00
JSONoutput : AlwaysJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-07 14:44:42 -08:00
// return an array of announcements and any errors
return gcsql . GetAllAccouncements ( )
2020-04-29 17:44:29 -07:00
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "staffinfo" ,
2020-10-10 16:17:36 -07:00
Permissions : NoPerms ,
2021-12-23 14:41:49 -08:00
JSONoutput : AlwaysJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
return staff , nil
2020-04-29 17:44:29 -07:00
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "boards" ,
2020-04-29 17:44:29 -07:00
Title : "Boards" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2022-01-16 13:30:33 -08:00
JSONoutput : NoJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-15 21:20:43 -08:00
pageBuffer := bytes . NewBufferString ( "" )
2022-01-16 13:30:33 -08:00
var board gcsql . Board
requestType , boardID , err := boardsRequestType ( request )
if err != nil {
return "" , err
}
if requestType == "cancel" || requestType == "" {
board . SetDefaults ( "" , "" , "" )
}
switch requestType {
case "create" :
// create button clicked, create the board with the request fields
2022-01-16 14:38:57 -08:00
board . ChangeFromRequest ( request , false )
2022-01-16 13:30:33 -08:00
err = board . Create ( )
case "delete" :
// delete button clicked, delete the board
if board , err = gcsql . GetBoardFromID ( boardID ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "boards" ) .
Int ( "deleteBoardID" , boardID ) . Send ( )
2022-01-16 13:30:33 -08:00
return "" , err
}
err = board . Delete ( )
2022-09-03 14:13:49 -07:00
if err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "boards" ) .
Str ( "deleteBoard" , board . Dir ) . Send ( )
2022-09-03 14:13:49 -07:00
return "" , err
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "boards" ) .
Str ( "deleteBoard" , board . Dir ) . Send ( )
err = os . RemoveAll ( board . AbsolutePath ( ) )
2022-01-16 13:30:33 -08:00
case "edit" :
// edit button clicked, fill the input fields with board data to be edited
board , err = gcsql . GetBoardFromID ( boardID )
case "modify" :
// save changes button clicked, apply changes to the board based on the request fields
board , err = gcsql . GetBoardFromID ( boardID )
if err != nil {
return "" , err
}
2022-09-04 14:27:14 -07:00
err = board . ChangeFromRequest ( request , true )
2022-01-16 13:30:33 -08:00
case "cancel" :
// cancel button was clicked
fallthrough
case "" :
fallthrough
default :
board . SetDefaults ( "" , "" , "" )
}
if err != nil {
return "" , err
}
2022-01-16 14:11:55 -08:00
if requestType == "create" || requestType == "modify" && err != nil {
if err = building . BuildBoardListJSON ( ) ; err != nil {
return "" , err
}
if err = building . BuildBoards ( false , board . ID ) ; err != nil {
return "" , err
}
if err = building . BuildBoardPages ( & board ) ; err != nil {
return "" , err
}
}
2022-01-15 21:20:43 -08:00
if err = serverutil . MinifyTemplate ( gctemplates . ManageBoards ,
map [ string ] interface { } {
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
"site_config" : config . GetSiteConfig ( ) ,
"sections" : gcsql . AllSections ,
"boards" : gcsql . AllBoards ,
"board_config" : config . GetBoardConfig ( "" ) ,
2022-01-16 13:30:33 -08:00
"editing" : requestType == "edit" ,
"board" : board ,
2022-01-15 21:20:43 -08:00
} , pageBuffer , "text/html" ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "boards" ) .
Str ( "template" , "manage_boards.html" ) . Send ( )
2022-01-15 21:20:43 -08:00
return "" , err
}
return pageBuffer . String ( ) , nil
2020-04-29 17:44:29 -07:00
} } ,
2022-08-07 22:02:06 -07:00
{
ID : "boardsections" ,
Title : "Board sections" ,
Permissions : AdminPerms ,
JSONoutput : NoJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-08-08 15:43:05 -07:00
section := & gcsql . BoardSection { }
editID := request . Form . Get ( "edit" )
updateID := request . Form . Get ( "updatesection" )
deleteID := request . Form . Get ( "delete" )
if editID != "" {
if section , err = gcsql . GetSectionFromID ( gcutil . HackyStringToInt ( editID ) ) ; err != nil {
return "" , & ErrStaffAction {
ErrorField : "db" ,
Action : "boardsections" ,
Message : err . Error ( ) ,
}
}
} else if updateID != "" {
if section , err = gcsql . GetSectionFromID ( gcutil . HackyStringToInt ( updateID ) ) ; err != nil {
return "" , & ErrStaffAction {
ErrorField : "db" ,
Action : "boardsections" ,
Message : err . Error ( ) ,
}
}
} else if deleteID != "" {
if err = gcsql . DeleteSection ( gcutil . HackyStringToInt ( deleteID ) ) ; err != nil {
return "" , & ErrStaffAction {
ErrorField : "db" ,
Action : "boardsections" ,
Message : err . Error ( ) ,
}
}
}
if request . PostForm . Get ( "save_section" ) != "" {
2022-08-07 22:32:37 -07:00
// user is creating a new board section
2022-08-08 15:43:05 -07:00
if section == nil {
section = & gcsql . BoardSection { }
}
section . Name = request . PostForm . Get ( "sectionname" )
section . Abbreviation = request . PostForm . Get ( "sectionabbr" )
section . Hidden = request . PostForm . Get ( "sectionhidden" ) == "on"
section . ListOrder , err = strconv . Atoi ( request . PostForm . Get ( "sectionpos" ) )
if section . Name == "" || section . Abbreviation == "" || request . PostForm . Get ( "sectionpos" ) == "" {
return "" , & ErrStaffAction {
ErrorField : "formerror" ,
Action : "boardsections" ,
Message : "Missing section title, abbreviation, or hidden status data" ,
}
} else if err != nil {
2022-08-07 22:32:37 -07:00
return "" , & ErrStaffAction {
ErrorField : "formerror" ,
Action : "boardsections" ,
2022-08-08 15:43:05 -07:00
Message : err . Error ( ) ,
2022-08-07 22:32:37 -07:00
}
}
2022-08-08 15:43:05 -07:00
if updateID != "" {
// submitting changes to the section
err = section . UpdateValues ( )
} else {
// creating a new section
err = gcsql . CreateSection ( section )
}
if err != nil {
2022-08-07 22:32:37 -07:00
return "" , & ErrStaffAction {
ErrorField : "db" ,
Action : "boardsections" ,
Message : err . Error ( ) ,
}
}
gcsql . ResetBoardSectionArrays ( )
2022-08-07 22:02:06 -07:00
}
pageBuffer := bytes . NewBufferString ( "" )
2022-08-08 15:43:05 -07:00
pageMap := map [ string ] interface { } {
2022-08-07 22:02:06 -07:00
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
"site_config" : config . GetSiteConfig ( ) ,
2022-08-07 22:32:37 -07:00
"sections" : gcsql . AllSections ,
2022-08-08 15:43:05 -07:00
}
if section . ID > 0 {
pageMap [ "edit_section" ] = section
}
if err = serverutil . MinifyTemplate ( gctemplates . ManageSections , pageMap , pageBuffer , "text/html" ) ; err != nil {
2022-08-07 22:02:06 -07:00
return "" , err
}
output = pageBuffer . String ( )
return
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "rebuildfront" ,
2020-04-29 17:44:29 -07:00
Title : "Rebuild front page" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2022-01-29 20:46:00 -08:00
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2020-05-28 12:49:41 -07:00
if err = gctemplates . InitTemplates ( ) ; err != nil {
return "" , err
}
2022-01-29 20:46:00 -08:00
err = building . BuildFrontPage ( )
if wantsJSON {
return map [ string ] string {
"front" : "Built front page successfully" ,
} , err
}
2022-01-29 23:47:13 -08:00
return "Built front page successfully" , err
2020-04-29 17:44:29 -07:00
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "rebuildall" ,
2020-04-29 17:44:29 -07:00
Title : "Rebuild everything" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2021-12-23 14:41:49 -08:00
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2020-04-29 17:44:29 -07:00
gctemplates . InitTemplates ( )
gcsql . ResetBoardSectionArrays ( )
2021-12-22 21:13:04 -08:00
buildErr := & ErrStaffAction {
ErrorField : "builderror" ,
Action : "rebuildall" ,
}
buildMap := map [ string ] string { }
2020-05-28 12:49:41 -07:00
if err = building . BuildFrontPage ( ) ; err != nil {
2022-09-04 14:27:14 -07:00
buildErr . Message = "Error building front page: " + err . Error ( )
2021-12-22 21:13:04 -08:00
if wantsJSON {
return buildErr , buildErr
}
return buildErr . Message , buildErr
2020-05-28 12:49:41 -07:00
}
2021-12-22 21:13:04 -08:00
buildMap [ "front" ] = "Built front page successfully"
2020-05-28 12:49:41 -07:00
if err = building . BuildBoardListJSON ( ) ; err != nil {
2022-09-04 14:27:14 -07:00
buildErr . Message = "Error building board list: " + err . Error ( )
2021-12-22 21:13:04 -08:00
if wantsJSON {
return buildErr , buildErr
}
return buildErr . Message , buildErr
2020-05-28 12:49:41 -07:00
}
2021-12-22 21:13:04 -08:00
buildMap [ "boardlist" ] = "Built board list successfully"
2020-05-28 12:49:41 -07:00
2020-06-03 12:54:12 -07:00
if err = building . BuildBoards ( false ) ; err != nil {
2022-09-04 14:27:14 -07:00
buildErr . Message = "Error building boards: " + err . Error ( )
2021-12-22 21:13:04 -08:00
if wantsJSON {
return buildErr , buildErr
}
return buildErr . Message , buildErr
2020-05-28 12:49:41 -07:00
}
2021-12-22 21:13:04 -08:00
buildMap [ "boards" ] = "Built boards successfully"
2020-05-28 12:49:41 -07:00
if err = building . BuildJS ( ) ; err != nil {
2022-09-04 14:27:14 -07:00
buildErr . Message = "Error building consts.js: " + err . Error ( )
2021-12-22 21:13:04 -08:00
if wantsJSON {
return buildErr , buildErr
}
return buildErr . Message , buildErr
}
if wantsJSON {
return buildMap , nil
2020-05-28 12:49:41 -07:00
}
2022-01-29 23:47:13 -08:00
buildStr := ""
2021-12-22 21:13:04 -08:00
for _ , msg := range buildMap {
buildStr += fmt . Sprintln ( msg , "<hr />" )
}
return buildStr , nil
} } ,
2022-01-29 23:47:13 -08:00
// {
// ID: "rebuildboard",
// Title: "Rebuild board",
// Permissions: AdminPerms,
// Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
// if err = gctemplates.InitTemplates(); err != nil {
// return "", err
// }
// for b, board := range request.Form {
// if b == "board" {
// return board[0], nil
// }
// }
// return "", &ErrStaffAction{
// ErrorField: "staffaction",
// Action: "rebuildboard",
// Message: fmt.Sprintf("/%s/ is not a board"),
// }
// }},
2022-01-01 16:03:39 -08:00
{
ID : "rebuildboards" ,
2020-04-29 17:44:29 -07:00
Title : "Rebuild boards" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2021-12-23 14:41:49 -08:00
JSONoutput : OptionalJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2020-05-28 12:49:41 -07:00
if err = gctemplates . InitTemplates ( ) ; err != nil {
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "rebuildboards" ) . Send ( )
2020-05-28 12:49:41 -07:00
return "" , err
}
2021-12-22 21:13:04 -08:00
if wantsJSON {
return map [ string ] interface { } {
"success" : true ,
"message" : "Boards built successfully" ,
} , building . BuildBoards ( false )
}
2022-01-29 23:47:13 -08:00
return "Boards built successfully" , building . BuildBoards ( false )
2020-04-29 17:44:29 -07:00
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "reparsehtml" ,
2020-04-29 17:44:29 -07:00
Title : "Reparse HTML" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2021-12-22 21:13:04 -08:00
var outputStr string
2020-04-29 17:44:29 -07:00
messages , err := gcsql . GetAllNondeletedMessageRaw ( )
if err != nil {
2020-05-28 12:49:41 -07:00
return "" , err
2020-04-29 17:44:29 -07:00
}
2020-07-08 20:50:04 +02:00
for i := range messages {
2022-07-25 09:29:00 -07:00
messages [ i ] . Message = posting . FormatMessage ( messages [ i ] . MessageRaw , messages [ i ] . Board )
2020-04-29 17:44:29 -07:00
}
2020-05-28 12:49:41 -07:00
if err = gcsql . SetFormattedInDatabase ( messages ) ; err != nil {
return "" , err
}
2021-12-22 21:13:04 -08:00
outputStr += "Done reparsing HTML<hr />"
2020-04-29 17:44:29 -07:00
2020-05-28 12:49:41 -07:00
if err = building . BuildFrontPage ( ) ; err != nil {
return "" , err
}
2021-12-22 21:13:04 -08:00
outputStr += "Done building front page<hr />"
2020-05-28 12:49:41 -07:00
if err = building . BuildBoardListJSON ( ) ; err != nil {
return "" , err
2020-04-29 17:44:29 -07:00
}
2021-12-22 21:13:04 -08:00
outputStr += "Done building board list JSON<hr />"
2020-05-28 12:49:41 -07:00
2020-06-03 12:54:12 -07:00
if err = building . BuildBoards ( false ) ; err != nil {
2020-05-28 12:49:41 -07:00
return "" , err
}
2021-12-22 21:13:04 -08:00
outputStr += "Done building boards<hr />"
return outputStr , nil
2020-04-29 17:44:29 -07:00
} } ,
2022-01-01 16:03:39 -08:00
{
ID : "postinfo" ,
2020-04-29 17:44:29 -07:00
Title : "Post info" ,
2020-10-10 16:17:36 -07:00
Permissions : ModPerms ,
2022-01-16 21:13:56 -08:00
JSONoutput : AlwaysJSON ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-08-28 11:55:08 -07:00
postIDstr := request . FormValue ( "postid" )
if postIDstr == "" {
return "" , errors . New ( "invalid request (missing postid)" )
}
var postID int
if postID , err = strconv . Atoi ( postIDstr ) ; err != nil {
return "" , err
}
post , err := gcsql . GetPostFromID ( postID , true )
if err != nil {
return "" , err
}
postInfo := map [ string ] interface { } {
"post" : post ,
"ip" : post . IP ,
}
names , err := net . LookupAddr ( post . IP )
if err == nil {
postInfo [ "ipFQDN" ] = names
} else {
postInfo [ "ipFQDN" ] = [ ] string { err . Error ( ) }
}
return postInfo , nil
2020-04-29 17:44:29 -07:00
} } ,
2022-01-31 09:47:19 -08:00
// {
2022-01-31 22:35:47 -08:00
// may end up deleting this
2022-01-31 09:47:19 -08:00
// ID: "tempposts",
// Title: "Temporary posts lists",
// Permissions: AdminPerms,
// Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
// outputStr := ""
// if len(gcsql.TempPosts) == 0 {
2022-01-31 22:35:47 -08:00
// outputStr += "No temporary posts"
2022-01-31 09:47:19 -08:00
// return
// }
// for p, post := range gcsql.TempPosts {
// outputStr += fmt.Sprintf("Post[%d]: %#v<br />", p, post)
// }
// return outputStr, nil
// }},
2022-01-01 16:03:39 -08:00
{
2022-01-31 09:47:19 -08:00
ID : "wordfilters" ,
Title : "Wordfilters" ,
2020-10-10 16:17:36 -07:00
Permissions : AdminPerms ,
2022-09-04 14:27:14 -07:00
Callback : func ( writer http . ResponseWriter , request * http . Request , staff * gcsql . Staff , wantsJSON bool ) ( output interface { } , err error ) {
2022-01-31 09:47:19 -08:00
managePageBuffer := bytes . NewBufferString ( "" )
editIDstr := request . FormValue ( "edit" )
2022-07-22 14:56:14 -07:00
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 )
2022-09-04 14:27:14 -07:00
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "wordfilters" ) . Send ( )
2022-07-22 14:56:14 -07:00
return err , err
}
2022-09-04 14:27:14 -07:00
gcutil . LogInfo ( ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "wordfilters" ) .
Str ( "deletedWordfilterID" , deleteIDstr )
2022-07-22 14:56:14 -07:00
}
2022-07-21 15:50:38 -07:00
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" ) ,
2022-07-21 16:11:23 -07:00
editIDstr )
2022-07-21 15:50:38 -07:00
case "Create new wordfilter" :
2022-07-21 16:11:23 -07:00
_ , err = gcsql . CreateWordFilter (
request . FormValue ( "find" ) ,
request . FormValue ( "replace" ) ,
request . FormValue ( "isregex" ) == "on" ,
strings . Split ( request . FormValue ( "boarddirs" ) , "," ) ,
staff . ID ,
request . FormValue ( "staffnote" ) )
2022-07-21 15:50:38 -07:00
}
if err != nil {
return err , err
}
2022-01-31 09:47:19 -08:00
wordfilters , err := gcsql . GetWordFilters ( )
if err != nil {
return wordfilters , nil
}
var editFilter * gcsql . WordFilter
if editIDstr != "" {
editID := gcutil . HackyStringToInt ( editIDstr )
for _ , filter := range wordfilters {
if filter . ID == editID {
editFilter = & filter
break
}
}
2020-04-29 17:44:29 -07:00
}
2022-01-31 09:47:19 -08:00
filterMap := map [ string ] interface { } {
2022-09-15 21:37:56 -07:00
"webroot" : config . GetSystemCriticalConfig ( ) . WebRoot ,
2022-01-31 09:47:19 -08:00
"wordfilters" : wordfilters ,
"edit" : editFilter ,
2020-04-29 17:44:29 -07:00
}
2022-01-31 09:47:19 -08:00
err = serverutil . MinifyTemplate ( gctemplates . ManageWordfilters ,
filterMap , managePageBuffer , "text/html" )
2022-09-04 14:27:14 -07:00
if err != nil {
gcutil . LogError ( err ) .
Str ( "staff" , staff . Username ) .
Str ( "action" , "wordfilters" ) .
Str ( "template" , "manage_wordfilters.html" ) . Send ( )
2022-01-31 09:47:19 -08:00
2022-09-04 14:27:14 -07:00
}
2022-01-31 09:47:19 -08:00
return managePageBuffer . String ( ) , err
} ,
} ,
2020-04-29 17:44:29 -07:00
}