1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-17 10:56:24 -07:00

Make config.Username useful (applies given username ownership to files)

This commit is contained in:
Eggbertx 2022-12-31 01:51:14 -08:00
parent d0e59b4580
commit 76a4f92e18
6 changed files with 157 additions and 38 deletions

View file

@ -160,12 +160,18 @@ func BuildBoardPages(board *gcsql.Board) error {
boardPageFile, err = os.OpenFile(path.Join(criticalCfg.DocumentRoot, board.Dir, "1.html"),
os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
if err != nil {
errEv.Err(err).
errEv.Err(err).Caller().
Str("page", "board.html").
Caller().Msg("Failed getting board page")
Msg("Failed getting board page")
return fmt.Errorf("failed opening /%s/board.html: %s", board.Dir, err.Error())
}
defer boardPageFile.Close()
if err = config.TakeOwnershipOfFile(boardPageFile); err != nil {
errEv.Err(err).Caller().
Msg("Unable to take ownership of board.html")
return fmt.Errorf("unable to take ownership of /%s/board.html: %s", board.Dir, err.Error())
}
// Render board page template to the file,
// packaging the board/section list, threads, and board info
captchaCfg := config.GetSiteConfig().Captcha
@ -199,13 +205,17 @@ func BuildBoardPages(board *gcsql.Board) error {
// catalog JSON file is built with the pages because pages are recorded in the JSON file
catalogJSONFile, err := os.OpenFile(path.Join(criticalCfg.DocumentRoot, board.Dir, "catalog.json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
if err != nil {
errEv.Err(err).
Str("subject", "catalog.json").
Caller().Msg("Failed opening catalog.json")
errEv.Err(err).Caller().
Msg("Failed opening catalog.json")
return fmt.Errorf("failed opening /%s/catalog.json: %s", board.Dir, err.Error())
}
defer catalogJSONFile.Close()
if err = config.TakeOwnershipOfFile(catalogJSONFile); err != nil {
errEv.Err(err).Caller().
Msg("Unable to take ownership of catalog.json")
return fmt.Errorf("unable to take ownership of /%s/catalog.json: %s", board.Dir, err.Error())
}
for _, page := range catalog.pages {
catalog.currentPage++
var currentPageFilepath string
@ -213,13 +223,20 @@ func BuildBoardPages(board *gcsql.Board) error {
currentPageFilepath = path.Join(criticalCfg.DocumentRoot, board.Dir, pageFilename)
currentPageFile, err = os.OpenFile(currentPageFilepath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
if err != nil {
errEv.Err(err).
errEv.Err(err).Caller().
Str("page", pageFilename).
Caller().Msg("Failed getting board page")
Msg("Failed getting board page")
continue
}
defer currentPageFile.Close()
if err = config.TakeOwnershipOfFile(currentPageFile); err != nil {
errEv.Err(err).Caller().
Str("page", pageFilename).
Msg("Unable to update file ownership")
return errors.New("unable to set board page file ownership")
}
// Render the boardpage template
captchaCfg := config.GetSiteConfig().Captcha
if err = serverutil.MinifyTemplate(gctemplates.BoardPage, map[string]interface{}{
@ -329,9 +346,19 @@ func buildBoard(board *gcsql.Board, force bool) error {
return fmt.Errorf(pathExistsStr, dirPath)
}
if !dirInfo.IsDir() {
errEv.Err(os.ErrExist).
Str("dirPath", dirPath).
Caller().Send()
return fmt.Errorf(dirIsAFileStr, dirPath)
}
} else if err = os.Mkdir(dirPath, 0666); err != nil {
errEv.Err(os.ErrExist).
Str("dirPath", dirPath).
Caller().Send()
return fmt.Errorf(genericErrStr, dirPath, err.Error())
}
if err = config.TakeOwnership(dirPath); err != nil {
return fmt.Errorf(genericErrStr, dirPath, err.Error())
}
@ -356,7 +383,11 @@ func buildBoard(board *gcsql.Board, force bool) error {
errEv.Err(err).
Str("resPath", resPath).
Caller().Send()
return fmt.Errorf(genericErrStr, resPath, err.Error())
}
if err = config.TakeOwnership(resPath); err != nil {
errEv.Err(err).Caller().
Str("resPath", resPath).Send()
return fmt.Errorf(genericErrStr, resPath, err.Error())
}
@ -382,6 +413,11 @@ func buildBoard(board *gcsql.Board, force bool) error {
Caller().Send()
return err
}
if config.TakeOwnership(srcPath); err != nil {
errEv.Err(err).Caller().
Str("srcPath", srcPath).Send()
return fmt.Errorf(genericErrStr, srcPath, err.Error())
}
if thumbInfo != nil {
if !force {
@ -391,6 +427,13 @@ func buildBoard(board *gcsql.Board, force bool) error {
return fmt.Errorf(dirIsAFileStr, thumbPath)
}
} else if err = os.Mkdir(thumbPath, 0666); err != nil {
errEv.Err(err).Caller().
Str("thumbPath", thumbPath).Send()
return fmt.Errorf(genericErrStr, thumbPath, err.Error())
}
if config.TakeOwnership(thumbPath); err != nil {
errEv.Err(err).Caller().
Str("thumbPath", thumbPath).Send()
return fmt.Errorf(genericErrStr, thumbPath, err.Error())
}
@ -424,13 +467,19 @@ func buildBoard(board *gcsql.Board, force bool) error {
func BuildBoardListJSON() error {
boardsJsonPath := path.Join(config.GetSystemCriticalConfig().DocumentRoot, "boards.json")
boardListFile, err := os.OpenFile(boardsJsonPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
errEv := gcutil.LogError(nil).Str("building", "boards.json")
defer errEv.Discard()
if err != nil {
gcutil.LogError(err).
Str("building", "boardsList").Send()
return errors.New("Failed opening boards.json for writing: " + err.Error())
errEv.Err(err).Caller().Send()
return errors.New("unable to open boards.json for writing: " + err.Error())
}
defer boardListFile.Close()
if err = config.TakeOwnershipOfFile(boardListFile); err != nil {
errEv.Err(err).Caller().Send()
return errors.New("unable to update boards.json ownership: " + err.Error())
}
boardsMap := map[string][]boardJSON{
"boards": {},
}
@ -452,12 +501,12 @@ func BuildBoardListJSON() error {
// TODO: properly check if the board is in a hidden section
boardJSON, err := json.Marshal(boardsMap)
if err != nil {
gcutil.LogError(err).Str("building", "boards.json").Send()
errEv.Err(err).Caller().Send()
return errors.New("Failed to create boards.json: " + err.Error())
}
if _, err = serverutil.MinifyWriter(boardListFile, boardJSON, "application/json"); err != nil {
gcutil.LogError(err).Str("building", "boards.json").Send()
errEv.Err(err).Caller().Send()
return errors.New("Failed writing boards.json file: " + err.Error())
}
return nil

View file

@ -112,6 +112,11 @@ func BuildFrontPage() error {
}
defer frontFile.Close()
if err = config.TakeOwnershipOfFile(frontFile); err != nil {
errEv.Err(err).Caller().Send()
return errors.New("Failed setting file ownership for front page: " + err.Error())
}
var recentPostsArr []recentPost
siteCfg := config.GetSiteConfig()
recentPostsArr, err = getRecentPosts()
@ -164,8 +169,10 @@ func BuildPageFooter(writer io.Writer) (err error) {
func BuildJS() error {
// build consts.js from template
err := gctemplates.InitTemplates("js")
errEv := gcutil.LogError(nil).Str("building", "consts.js")
defer errEv.Discard()
if err != nil {
gcutil.LogError(err).Str("template", "consts.js").Send()
errEv.Err(err).Caller().Send()
return errors.New("Error loading consts.js template:" + err.Error())
}
@ -174,13 +181,16 @@ func BuildJS() error {
constsJSPath := path.Join(criticalCfg.DocumentRoot, "js", "consts.js")
constsJSFile, err := os.OpenFile(constsJSPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
gcutil.LogError(err).
Str("building", "consts.js").
Str("filePath", constsJSPath).Send()
return fmt.Errorf("error opening %q for writing: %s", constsJSPath, err.Error())
errEv.Err(err).Caller().Send()
return fmt.Errorf("error opening consts.js for writing: %s", err.Error())
}
defer constsJSFile.Close()
if err = config.TakeOwnershipOfFile(constsJSFile); err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("unable to update file ownership for consts.js: %s", err.Error())
}
if err = serverutil.MinifyTemplate(gctemplates.JsConsts,
map[string]interface{}{
"webroot": criticalCfg.WebRoot,
@ -189,10 +199,8 @@ func BuildJS() error {
"timezone": criticalCfg.TimeZone,
},
constsJSFile, "text/javascript"); err != nil {
gcutil.LogError(err).
Str("building", "consts.js").
Str("filePath", constsJSPath).Send()
return fmt.Errorf("error building %q: %s", constsJSPath, err.Error())
errEv.Err(err).Caller().Send()
return fmt.Errorf("error building consts.js: %s", err.Error())
}
return nil
}

View file

@ -86,6 +86,12 @@ func BuildCatalog(boardID int) error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed opening /%s/catalog.html: %s", board.Dir, err.Error())
}
defer catalogFile.Close()
if err = config.TakeOwnershipOfFile(catalogFile); err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed taking ownership of /%s/catalog.html: %s", board.Dir, err.Error())
}
threadOPs, err := getBoardTopPosts(boardID)
if err != nil {

View file

@ -85,10 +85,15 @@ func BuildThreadPages(op *gcsql.Post) error {
threadPageFilepath := path.Join(criticalCfg.DocumentRoot, board.Dir, "res", strconv.Itoa(op.ID)+".html")
threadPageFile, err = os.OpenFile(threadPageFilepath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
if err != nil {
errEv.Err(err).
Caller().Send()
return fmt.Errorf("unable to open opening /%s/res/%d.html: %s", board.Dir, op.ID, err.Error())
errEv.Err(err).Caller().Send()
return fmt.Errorf("unable to open /%s/res/%d.html: %s", board.Dir, op.ID, err.Error())
}
defer threadPageFile.Close()
if err = config.TakeOwnershipOfFile(threadPageFile); err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("unable to set file permissions for /%s/res/%d.html: %s", board.Dir, op.ID, err.Error())
}
errEv.Int("op", posts[0].ID)
// render thread page
captchaCfg := config.GetSiteConfig().Captcha
@ -103,8 +108,7 @@ func BuildThreadPages(op *gcsql.Post) error {
"useCaptcha": captchaCfg.UseCaptcha() && !captchaCfg.OnlyNeededForThreads,
"captcha": captchaCfg,
}, threadPageFile, "text/html"); err != nil {
errEv.Err(err).
Caller().Send()
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed building /%s/res/%d threadpage: %s", board.Dir, posts[0].ID, err.Error())
}
@ -113,13 +117,16 @@ func BuildThreadPages(op *gcsql.Post) error {
path.Join(criticalCfg.DocumentRoot, board.Dir, "res", strconv.Itoa(posts[0].ID)+".json"),
os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
if err != nil {
errEv.Err(err).
Int("op", posts[0].ID).
Caller().Send()
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed opening /%s/res/%d.json: %s", board.Dir, posts[0].ID, err.Error())
}
defer threadJSONFile.Close()
if err = config.TakeOwnershipOfFile(threadJSONFile); err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed setting file permissions for /%s/res/%d.json: %s", board.Dir, posts[0].ID, err.Error())
}
threadMap := make(map[string][]Post)
threadMap["posts"] = posts
@ -130,7 +137,6 @@ func BuildThreadPages(op *gcsql.Post) error {
}
if _, err = threadJSONFile.Write(threadJSON); err != nil {
errEv.Err(err).
Int("op", posts[0].ID).
Caller().Send()
return fmt.Errorf("failed writing /%s/res/%d.json: %s", board.Dir, posts[0].ID, err.Error())
}

View file

@ -5,8 +5,11 @@ import (
"flag"
"fmt"
"os"
"os/user"
"path"
"reflect"
"runtime"
"strconv"
"time"
"github.com/gochan-org/gochan/pkg/gcutil"
@ -17,6 +20,8 @@ var (
"ListenIP", "Port", "Username", "UseFastCGI", "DocumentRoot", "TemplateDir", "LogDir",
"DBtype", "DBhost", "DBname", "DBusername", "DBpassword", "SiteDomain", "Styles",
}
uid int
gid int
)
// MissingField represents a field missing from the configuration file
@ -74,6 +79,22 @@ func GetDefaultString(key string) string {
return str
}
func TakeOwnership(fp string) error {
if runtime.GOOS == "windows" || fp == "" {
// Chown returns an error in Windows
return nil
}
return os.Chown(fp, uid, gid)
}
func TakeOwnershipOfFile(f *os.File) error {
if runtime.GOOS == "windows" || f == nil {
// Chown returns an error in Windows
return nil
}
return f.Chown(uid, gid)
}
// ParseJSON loads and parses JSON data, returning a GochanConfig pointer, any critical missing
// fields that don't have defaults, and any error from parsing the file. This doesn't mean that the
// values are valid, just that they exist
@ -148,7 +169,7 @@ func InitConfig(versionStr string) {
Version: ParseVersion(versionStr),
},
SiteConfig: SiteConfig{
Username: "gochan",
Username: "",
FirstPage: []string{"index.html", "firstrun.html", "1.html"},
Lockdown: false,
LockdownMessage: "This imageboard has temporarily disabled posting. We apologize for the inconvenience",
@ -255,6 +276,21 @@ func InitConfig(versionStr string) {
os.Exit(1)
}
if runtime.GOOS != "windows" {
var gcUser *user.User
if cfg.Username != "" {
gcUser, err = user.Lookup(cfg.Username)
} else {
gcUser, err = user.Current()
}
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
uid, _ = strconv.Atoi(gcUser.Uid)
gid, _ = strconv.Atoi(gcUser.Gid)
}
if _, err = os.Stat(cfg.DocumentRoot); err != nil {
fmt.Println(err.Error())
os.Exit(1)

View file

@ -268,15 +268,18 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
return
}
documentRoot := config.GetSystemCriticalConfig().DocumentRoot
var filePath, thumbPath, catalogThumbPath string
if upload != nil {
filePath = path.Join(documentRoot, postBoard.Dir, "src", upload.Filename)
thumbPath = path.Join(documentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("thumb"))
catalogThumbPath = path.Join(documentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("catalog"))
}
if err = post.Insert(emailCommand != "sage", postBoard.ID, false, false, false, false); err != nil {
errEv.Err(err).Caller().
Str("sql", "postInsertion").
Msg("Unable to insert post")
if upload != nil {
filePath := path.Join(documentRoot, postBoard.Dir, "src", upload.Filename)
thumbPath := path.Join(documentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("thumb"))
catalogThumbPath := path.Join(documentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("catalog"))
os.Remove(filePath)
os.Remove(thumbPath)
os.Remove(catalogThumbPath)
@ -289,15 +292,26 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
errEv.Err(err).Caller().
Str("sql", "postInsertion").
Msg("Unable to attach upload to post")
filePath := path.Join(documentRoot, postBoard.Dir, "src", upload.Filename)
thumbPath := path.Join(documentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("thumb"))
catalogThumbPath := path.Join(documentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("catalog"))
os.Remove(filePath)
os.Remove(thumbPath)
os.Remove(catalogThumbPath)
serverutil.ServeErrorPage(writer, "Unable to attach upload: "+err.Error())
return
}
if upload != nil {
if err = config.TakeOwnership(filePath); err != nil {
errEv.Err(err).Caller().
Str("file", filePath).Send()
}
if err = config.TakeOwnership(thumbPath); err != nil {
errEv.Err(err).Caller().
Str("thumbnail", thumbPath).Send()
}
if err = config.TakeOwnership(catalogThumbPath); err != nil && !os.IsNotExist(err) {
errEv.Err(err).Caller().
Str("catalogThumbnail", catalogThumbPath).Send()
}
}
// rebuild the board page
if err = building.BuildBoards(false, postBoard.ID); err != nil {