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

Fix building errors for de-deprecation

This commit is contained in:
Eggbertx 2022-11-09 10:15:37 -08:00
parent f5337896b2
commit b16fdc81b8
9 changed files with 371 additions and 89 deletions

View file

@ -218,6 +218,12 @@ func getBoardIDFromURI(uri string) (int, error) {
return id, err
}
func (board *Board) Delete() error {
const query = `DELETE FROM DBPREFIXboards WHERE id = ?`
_, err := ExecSQL(query, board.ID)
return err
}
func (board *Board) GetThreads(onlyNotDeleted bool) ([]Thread, error) {
query := selectThreadsBaseSQL + " WHERE id = ?"
if onlyNotDeleted {

View file

@ -49,6 +49,35 @@ func GetPostFromID(id int, onlyNotDeleted bool) (*Post, error) {
return post, err
}
// GetPostsFromIP gets the posts from the database with a matching IP address, specifying
// optionally requiring them to not be deleted
func GetPostsFromIP(ip string, limit int, onlyNotDeleted bool) ([]Post, error) {
sql := selectPostsBaseSQL + ` WHERE DBPREFIXposts.ip = ?`
if onlyNotDeleted {
sql += " AND is_deleted = 0"
}
sql += " ORDER BY id DESC LIMIT ?"
rows, err := QuerySQL(sql, ip, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var posts []Post
for rows.Next() {
var post Post
if err = rows.Scan(
&post.ID, &post.ThreadID, &post.IsTopPost, &post.IP, &post.CreatedOn, &post.Name,
&post.Tripcode, &post.IsRoleSignature, &post.Email, &post.Subject, &post.Message,
&post.MessageRaw, &post.Password, &post.DeletedAt, &post.IsDeleted, &post.BannedMessage,
); err != nil {
return nil, err
}
posts = append(posts, post)
}
return posts, nil
}
func GetTopPostInThread(postID int) (int, error) {
const query = `SELECT id FROM DBPREFIXposts WHERE thread_id = (
SELECT thread_id FROM DBPREFIXposts WHERE id = ?

View file

@ -52,6 +52,24 @@ func getOrCreateDefaultSectionID() (sectionID int, err error) {
return id, nil
}
func GetSectionFromID(id int) (*Section, error) {
const query = `SELECT id, name, abbreviation, position, hidden FROM DBPREFIXsections WHERE id = ?`
var section Section
err := QueryRowSQL(query, interfaceSlice(id), interfaceSlice(
&section.ID, &section.Name, &section.Abbreviation, &section.Position, &section.Hidden,
))
if err != nil {
return nil, err
}
return &section, err
}
func DeleteSection(id int) error {
const query = `DELETE FROM DBPREFIXsections WHERE id = ?`
_, err := ExecSQL(query, id)
return err
}
// NewSection creates a new board section in the database and returns a *Section struct pointer.
// If position < 0, it will use the ID
func NewSection(name string, abbreviation string, hidden bool, position int) (*Section, error) {
@ -86,3 +104,9 @@ func GetAllNonHiddenSections() []Section {
}
return sections
}
func (s *Section) UpdateValues() error {
const query = `UPDATE DBPREFIXsections set name = ? abbreviation = ?, position = ?, hidden = ?`
_, err := ExecSQL(query, s.Name, s.Abbreviation, s.Position, s.Hidden)
return err
}

View file

@ -202,27 +202,7 @@ var funcMap = template.FuncMap{
return gcutil.GetThumbnailPath("thread", img)
},
"getUploadType": func(name string) string {
extension := gcutil.GetFileExtension(name)
var uploadType string
switch extension {
case "":
fallthrough
case "deleted":
uploadType = ""
case "webm":
fallthrough
case "mp4":
fallthrough
case "jpg":
fallthrough
case "jpeg":
fallthrough
case "gif":
uploadType = "jpg"
case "png":
uploadType = "png"
}
return uploadType
return gcutil.GetThumbnailExt(name)
},
"imageToThumbnailPath": func(thumbType string, img string) string {
filetype := strings.ToLower(img[strings.LastIndex(img, ".")+1:])

View file

@ -72,17 +72,17 @@ func LogAccess(request *http.Request) *zerolog.Event {
func LogError(err error) *zerolog.Event {
if err != nil {
return logger.Err(err).Caller(1)
return logger.Err(err)
}
return logger.Error().Caller(1)
return logger.Error()
}
func LogFatal() *zerolog.Event {
return logger.Fatal().Caller(1)
return logger.Fatal()
}
func LogDebug() *zerolog.Event {
return logger.Debug().Caller(1)
return logger.Debug()
}
func CloseLog() error {

View file

@ -167,32 +167,32 @@ var actions = []Action{
}
return outputStr, nil
}},
{
ID: "recentposts",
Title: "Recent posts",
Permissions: JanitorPerms,
JSONoutput: OptionalJSON,
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (output interface{}, err error) {
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
if wantsJSON || err != nil {
return recentposts, err
}
manageRecentsBuffer := bytes.NewBufferString("")
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())
}
return manageRecentsBuffer.String(), nil
}},
// {
// ID: "recentposts",
// Title: "Recent posts",
// Permissions: JanitorPerms,
// JSONoutput: OptionalJSON,
// Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (output interface{}, err error) {
// 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
// if wantsJSON || err != nil {
// return recentposts, err
// }
// manageRecentsBuffer := bytes.NewBufferString("")
// 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())
// }
// return manageRecentsBuffer.String(), nil
// }},
/* {
ID: "filebans",
Title: "File bans",
@ -502,6 +502,7 @@ var actions = []Action{
} else {
data["reverseAddrs"] = []string{err.Error()}
}
data["posts"], err = gcsql.GetPostsFromIP(ipQuery, limit, true)
if err != nil {
gcutil.LogError(err).
@ -583,7 +584,8 @@ var actions = []Action{
if err != nil {
return nil, err
}
post, err := gcsql.GetSpecificPost(post_id, true)
post, err := gcsql.GetPostFromID(post_id, true)
if err != nil {
return nil, err
}
@ -593,7 +595,7 @@ var actions = []Action{
"id": id,
"staff_id": int(staff_id_int),
"staff_user": string(staff_user),
"post_link": post.GetURL(false),
"post_link": post.WebPath(),
"ip": ip,
"reason": reason,
"is_cleared": is_cleared,
@ -625,12 +627,18 @@ var actions = []Action{
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (output interface{}, err error) {
var outputStr string
do := request.FormValue("do")
allStaff, err := gcsql.GetAllStaffNopass(true)
allStaff, err := getAllStaffNopass(true)
if wantsJSON {
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username).
Str("action", "staff").
Msg("Error getting staff list")
return allStaff, err
}
if err != nil {
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username).
Str("action", "staff").
Msg("Error getting staff list")
@ -644,7 +652,7 @@ var actions = []Action{
rank := request.FormValue("rank")
rankI, _ := strconv.Atoi(rank)
if do == "add" {
if err = gcsql.NewStaff(username, password, rankI); err != nil {
if _, err = gcsql.NewStaff(username, password, rankI); err != nil {
gcutil.LogError(err).
Str("staff", staff.Username).
Str("action", "staff").
@ -656,7 +664,7 @@ var actions = []Action{
username, staff.Username, err.Error())
}
} else if do == "del" && username != "" {
if err = gcsql.DeleteStaff(username); err != nil {
if err = gcsql.DeactivateStaff(username); err != nil {
gcutil.LogError(err).
Str("staff", staff.Username).
Str("action", "staff").
@ -666,7 +674,7 @@ var actions = []Action{
username, staff.Username, err.Error())
}
}
allStaff, err = gcsql.GetAllStaffNopass(true)
allStaff, err = getAllStaffNopass(true)
if err != nil {
gcutil.LogError(err).
Str("staff", staff.Username).
@ -764,22 +772,30 @@ var actions = []Action{
Permissions: AdminPerms,
JSONoutput: NoJSON,
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (output interface{}, err error) {
pageBuffer := bytes.NewBufferString("")
var board gcsql.Board
requestType, boardID, err := boardsRequestType(request)
if err != nil {
return "", err
}
if requestType == "cancel" || requestType == "" {
board.SetDefaults("", "", "")
}
errEv := gcutil.LogError(nil).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username)
defer errEv.Discard()
board := new(gcsql.Board)
requestType, _, _ := boardsRequestType(request)
switch requestType {
case "create":
// create button clicked, create the board with the request fields
board.ChangeFromRequest(request, false)
err = board.Create()
if err = getBoardDataFromForm(board, request); err != nil {
serveError(writer, err.Error(), "boards", err.Error(), wantsJSON)
return "", err
}
err = gcsql.CreateBoard(board, true)
case "delete":
// delete button clicked, delete the board
boardID, err := getIntField("boardid", staff.Username, request, 0)
if err != nil {
serveError(writer, "boardid", "boards", err.Error(), wantsJSON)
return "", err
}
if board, err = gcsql.GetBoardFromID(boardID); err != nil {
gcutil.LogError(err).
Str("staff", staff.Username).
@ -802,21 +818,17 @@ var actions = []Action{
err = os.RemoveAll(board.AbsolutePath())
case "edit":
// edit button clicked, fill the input fields with board data to be edited
board, err = gcsql.GetBoardFromID(boardID)
err = getBoardDataFromForm(board, request)
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
}
err = board.ChangeFromRequest(request, true)
err = getBoardDataFromForm(board, request)
case "cancel":
// cancel button was clicked
fallthrough
case "":
fallthrough
default:
board.SetDefaults("", "", "")
// board.SetDefaults("", "", "")
}
if err != nil {
return "", err
@ -828,10 +840,11 @@ var actions = []Action{
if err = building.BuildBoards(false, board.ID); err != nil {
return "", err
}
if err = building.BuildBoardPages(&board); err != nil {
if err = building.BuildBoardPages(board); err != nil {
return "", err
}
}
pageBuffer := bytes.NewBufferString("")
if err = serverutil.MinifyTemplate(gctemplates.ManageBoards,
map[string]interface{}{
"webroot": config.GetSystemCriticalConfig().WebRoot,
@ -857,7 +870,7 @@ var actions = []Action{
Permissions: AdminPerms,
JSONoutput: NoJSON,
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (output interface{}, err error) {
section := &gcsql.BoardSection{}
section := &gcsql.Section{}
editID := request.Form.Get("edit")
updateID := request.Form.Get("updatesection")
deleteID := request.Form.Get("delete")
@ -890,12 +903,12 @@ var actions = []Action{
if request.PostForm.Get("save_section") != "" {
// user is creating a new board section
if section == nil {
section = &gcsql.BoardSection{}
section = &gcsql.Section{}
}
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"))
section.Position, err = strconv.Atoi(request.PostForm.Get("sectionpos"))
if section.Name == "" || section.Abbreviation == "" || request.PostForm.Get("sectionpos") == "" {
return "", &ErrStaffAction{
ErrorField: "formerror",
@ -914,7 +927,7 @@ var actions = []Action{
err = section.UpdateValues()
} else {
// creating a new section
err = gcsql.CreateSection(section)
section, err = gcsql.NewSection(section.Name, section.Abbreviation, section.Hidden, section.Position)
}
if err != nil {
return "", &ErrStaffAction{
@ -1060,18 +1073,54 @@ var actions = []Action{
Permissions: AdminPerms,
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool) (output interface{}, err error) {
var outputStr string
messages, err := gcsql.GetAllNondeletedMessageRaw()
tx, err := gcsql.BeginTx()
if err != nil {
return "", err
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username).
Msg("Unable to begin transaction")
return "", errors.New("Unable to begin SQL transaction")
}
defer tx.Rollback()
const query = `SELECT
id, message_raw, thread_id as threadid,
(SELECT id FROM DBPREFIXposts WHERE is_top_post = TRUE AND thread_id = threadid LIMIT 1) AS op,
(SELECT board_id FROM DBPREFIXthreads WHERE id = threadid) AS boardid,
(SELECT dir FROM DBPREFIXboards WHERE id = boardid) AS dir
FROM DBPREFIXposts WHERE is_deleted = FALSE`
const updateQuery = `UPDATE DBPREFIXposts SET message = ? WHERE id = ?`
for i := range messages {
messages[i].Message = posting.FormatMessage(messages[i].MessageRaw, messages[i].Board)
}
if err = gcsql.SetFormattedInDatabase(messages); err != nil {
stmt, err := gcsql.PrepareSQL(query, tx)
if err != nil {
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username).
Msg("Unable to prepare SQL query")
return "", err
}
defer stmt.Close()
rows, err := stmt.Query()
if err != nil {
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username).
Msg("Unable to query the database")
return "", err
}
defer rows.Close()
for rows.Next() {
var postID, threadID, opID, boardID int
var messageRaw, boardDir string
if err = rows.Scan(&postID, &messageRaw, &threadID, &opID, &boardID, &boardDir); err != nil {
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff.Username).
Msg("Unable to scan SQL row")
return "", err
}
formatted := posting.FormatMessage(messageRaw, boardDir)
gcsql.ExecSQL(updateQuery, formatted, postID)
}
outputStr += "Done reparsing HTML<hr />"
if err = building.BuildFrontPage(); err != nil {

94
pkg/manage/formvals.go Normal file
View file

@ -0,0 +1,94 @@
package manage
import (
"fmt"
"net/http"
"strconv"
"github.com/gochan-org/gochan/pkg/gcutil"
)
func getStringField(field string, staff string, request *http.Request, logCallerOffset ...int) (string, error) {
action := request.FormValue("action")
callerOffset := 1
if len(logCallerOffset) > 0 {
callerOffset += logCallerOffset[0]
}
if len(request.Form[field]) == 0 {
gcutil.LogError(nil).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff).
Str("action", action).
Str("field", field).
Caller(callerOffset).Msg("Missing required field")
return "", &ErrStaffAction{
ErrorField: field,
Action: action,
Message: fmt.Sprintf("Missing required field %q", field),
}
}
return request.FormValue(field), nil
}
func getBooleanField(field string, staff string, request *http.Request, logCallerOffset ...int) (bool, error) {
action := request.FormValue("action")
callerOffset := 1
if len(logCallerOffset) > 0 {
callerOffset += logCallerOffset[0]
}
if len(request.Form[field]) == 0 {
gcutil.LogError(nil).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff).
Str("action", action).
Str("field", field).
Caller(callerOffset).Msg("Missing required field")
return false, &ErrStaffAction{
ErrorField: field,
Action: action,
Message: fmt.Sprintf("Missing required field %q", field),
}
}
return request.FormValue(field) == "on", nil
}
// getIntField gets the requested value from the form and tries to convert it to int. If it fails, it logs the error
// and wraps it in ErrStaffAction
func getIntField(field string, staff string, request *http.Request, logCallerOffset ...int) (int, error) {
action := request.FormValue("action")
callerOffset := 1
if len(logCallerOffset) > 0 {
callerOffset += logCallerOffset[0]
}
if len(request.Form[field]) == 0 {
gcutil.LogError(nil).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff).
Str("action", action).
Str("field", field).
Caller(callerOffset).Msg("Missing required field")
return 0, &ErrStaffAction{
ErrorField: field,
Action: action,
Message: fmt.Sprintf("Missing required field %q", field),
}
}
strVal := request.FormValue(field)
intVal, err := strconv.Atoi(strVal)
if err != nil {
gcutil.LogError(err).
Str("IP", gcutil.GetRealIP(request)).
Str("staff", staff).
Str("action", action).
Str("field", field).
Caller(callerOffset).Msg("Unable to convert field to int")
return 0, &ErrStaffAction{
ErrorField: field,
Action: action,
Message: fmt.Sprintf("Unable to convert form field %q to int"),
}
}
return intVal, nil
}

View file

@ -218,6 +218,107 @@ func boardsRequestType(request *http.Request) (string, int, error) {
return requestType, boardID, err
}
func getAllStaffNopass(activeOnly bool) ([]gcsql.Staff, error) {
query := `SELECT
id, username, global_rank, added_on, last_login, is_active
FROM DBPREFIXstaff`
if activeOnly {
query += " WHERE is_active"
}
rows, err := gcsql.QuerySQL(query)
if err != nil {
return nil, err
}
defer rows.Close()
var staff []gcsql.Staff
for rows.Next() {
var s gcsql.Staff
err = rows.Scan(&s.ID, &s.Username, &s.Rank, &s.AddedOn, &s.LastLogin, &s.IsActive)
if err != nil {
return nil, err
}
staff = append(staff, s)
}
return staff, nil
}
// getBoardDataFromForm parses the relevant form fields into the board and returns any errors for invalid string to int
// or missing required fields. It should only be used for editing and creating boards
func getBoardDataFromForm(board *gcsql.Board, request *http.Request) error {
staff, err := getCurrentStaff(request)
if err != nil {
return err
}
if len(request.Form["domodify"]) > 0 || len(request.Form["doedit"]) > 0 || len(request.Form["dodelete"]) > 0 {
if board.ID, err = getIntField("boardid", staff, request, 1); err != nil {
return err
}
}
if board.SectionID, err = getIntField("section", staff, request, 1); err != nil {
return err
}
if board.Dir, err = getStringField("dir", staff, request, 1); err != nil {
return err
}
if board.NavbarPosition, err = getIntField("navbarposition", staff, request, 1); err != nil {
return err
}
if board.Title, err = getStringField("title", staff, request, 1); err != nil {
return err
}
if board.Subtitle, err = getStringField("subtitle", staff, request, 1); err != nil {
return err
}
if board.Description, err = getStringField("description", staff, request, 1); err != nil {
return err
}
if board.MaxFilesize, err = getIntField("maxfilesize", staff, request, 1); err != nil {
return err
}
if board.MaxThreads, err = getIntField("maxthreads", staff, request, 1); err != nil {
return err
}
if board.DefaultStyle, err = getStringField("defaultstyle", staff, request, 1); err != nil {
return err
}
if board.Locked, err = getBooleanField("locked", staff, request, 1); err != nil {
return err
}
if board.AnonymousName, err = getStringField("anonymousname", staff, request, 1); err != nil {
return err
}
if board.ForceAnonymous, err = getBooleanField("forcedanonymous", staff, request, 1); err != nil {
return err
}
if board.AutosageAfter, err = getIntField("autosageafter", staff, request, 1); err != nil {
return err
}
if board.NoImagesAfter, err = getIntField("noimagesafter", staff, request, 1); err != nil {
return err
}
if board.MaxMessageLength, err = getIntField("maxmessagelength", staff, request, 1); err != nil {
return err
}
if board.MinMessageLength, err = getIntField("minmessagelength", staff, request, 1); err != nil {
return err
}
if board.AllowEmbeds, err = getBooleanField("allowembeds", staff, request, 1); err != nil {
return err
}
if board.RedirectToThread, err = getBooleanField("redirecttothread", staff, request, 1); err != nil {
return err
}
if board.RequireFile, err = getBooleanField("requirefile", staff, request, 1); err != nil {
return err
}
if board.EnableCatalog, err = getBooleanField("enablecatalog", staff, request, 1); err != nil {
return err
}
return nil
}
func invalidWordfilterID(id interface{}) error {
return fmt.Errorf("wordfilter with id %q does not exist", id)
}

View file

@ -124,8 +124,7 @@ func getThumbnailSize(uploadWidth, uploadHeight int, boardDir string, thumbType
}
func numImageFrames(imgPath string) (int, error) {
ext := strings.ToLower(gcutil.GetFileExtension(imgPath))
if ext != "gif" {
if path.Ext(imgPath) != ".gif" {
return 1, nil
}
fi, err := os.Open(imgPath)