~fkfd/sophon

e670aa430be554ba7cda4fffdb5273a321f95307 — Frederick Yin 3 years ago fa42aef
Absolute path at /var/sophon
3 files changed, 40 insertions(+), 24 deletions(-)

M main.go
M routes.go
M wiki.go
M main.go => main.go +19 -3
@@ 2,15 2,31 @@ package main

import (
	"crypto/tls"
	"io/ioutil"
	"log"
	"os"
	"strconv"

	toml "github.com/pelletier/go-toml"
)

const sophonVersion = "0.1"

var serverDir string

func main() {
	configFile, err := ioutil.ReadFile("/var/sophon/config.toml")
	if err != nil {
		return
	}
	configString := string(configFile)
	config, err := toml.Load(configString)
	if err != nil {
		return
	}
	serverDir = "/var/sophon/"
	// Open log files
	errorLogFile, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	errorLogFile, err := os.OpenFile(serverDir+"error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatal(err)
	}


@@ 18,7 34,7 @@ func main() {
	errorLog := log.New(errorLogFile, "", log.Ldate|log.Ltime)

	// Read TLS files, create TLS config
	cert, err := tls.LoadX509KeyPair("cert/cert.pem", "cert/key.pem")
	cert, err := tls.LoadX509KeyPair(serverDir+"cert/cert.pem", serverDir+"cert/key.pem")
	if err != nil {
		errorLog.Println("Error loading TLS keypair: " + err.Error())
		log.Fatal(err)


@@ 30,7 46,7 @@ func main() {
	}

	// Create TLS listener
	listener, err := tls.Listen("tcp", ":1965", tlscfg)
	listener, err := tls.Listen("tcp", ":"+strconv.Itoa(int(config.Get("port").(int64))), tlscfg)
	if err != nil {
		errorLog.Println("Error creating TLS listener: " + err.Error())
		log.Fatal(err)

M routes.go => routes.go +1 -1
@@ 77,7 77,7 @@ func routeWikiRequest(segs []string, query string, clientIP net.Addr) (string, s
		// /wiki/<page>/edit/<id>/
		id := segs[3]
		// check if a session called <id> exists
		sessionDirs, err := ioutil.ReadDir("sessions")
		sessionDirs, err := ioutil.ReadDir(serverDir + "sessions")
		if err != nil {
			return "40 " + err.Error(), ""
		}

M wiki.go => wiki.go +20 -20
@@ 14,7 14,7 @@ const filePerm = 0644 // readable to all, writable only by owner
const dirPerm = 0755  // 0644 plus search-in-directories (+x)

func listWikiPages() ([]string, error) {
	files, err := ioutil.ReadDir("wiki")
	files, err := ioutil.ReadDir(serverDir + "wiki")
	if err != nil {
		return []string{}, err
	}


@@ 41,7 41,7 @@ func genPageList() (string, error) {

func readWikiPage(pageName string) (string, error) {
	contents, err := ioutil.ReadFile(
		"wiki/" + pageName + ".gmi",
		serverDir + "wiki/" + pageName + ".gmi",
	)
	if err != nil {
		return "", errors.New("Page not found")


@@ 59,7 59,7 @@ type editSessionManifest struct {

func parseManifest(id string) (editSessionManifest, error) {
	var manifest editSessionManifest
	file, err := ioutil.ReadFile("sessions/" + id + "/MANIFEST")
	file, err := ioutil.ReadFile(serverDir + "sessions/" + id + "/MANIFEST")
	if err != nil {
		return manifest, err
	}


@@ 91,14 91,14 @@ func initEditSession(page, section, clientIP string) (string, error) {
	rand := sha256.Sum256([]byte(page + section + clientIP + now))
	id := hex.EncodeToString(rand[:])[:16]
	// mkdir sessions/<id>/
	err := os.Mkdir("sessions/"+id, dirPerm)
	err := os.Mkdir(serverDir+"sessions/"+id, dirPerm)
	if err != nil {
		return "", err
	}
	manifest := editSessionManifest{sophonVersion, page, section, clientIP, now}.String()
	// cp wiki/<page>.gmi sessions/
	pageFile := "sessions/" + id + "/" + page + ".gmi"
	copyFile("wiki/"+page+".gmi", pageFile)
	pageFile := serverDir + "sessions/" + id + "/" + page + ".gmi"
	copyFile(serverDir+"wiki/"+page+".gmi", pageFile)
	fileContents, err := ioutil.ReadFile(pageFile)
	if err != nil {
		return "", err


@@ 114,22 114,22 @@ func initEditSession(page, section, clientIP string) (string, error) {
		return "", err
	}

	ioutil.WriteFile("sessions/"+id+"/MANIFEST", []byte(manifest), filePerm)
	ioutil.WriteFile("sessions/"+id+"/DIFF", []byte(""), filePerm)
	ioutil.WriteFile("sessions/"+id+"/STAGE", []byte(stageContents), filePerm)
	ioutil.WriteFile(serverDir+"sessions/"+id+"/MANIFEST", []byte(manifest), filePerm)
	ioutil.WriteFile(serverDir+"sessions/"+id+"/DIFF", []byte(""), filePerm)
	ioutil.WriteFile(serverDir+"sessions/"+id+"/STAGE", []byte(stageContents), filePerm)
	return id, nil
}

func touchManifest(id string) error {
	// update the Last Accessed line in MANIFEST
	manifest, err := ioutil.ReadFile("sessions/" + id + "/MANIFEST")
	manifest, err := ioutil.ReadFile(serverDir + "sessions/" + id + "/MANIFEST")
	if err != nil {
		return err
	}
	manifestLines := strings.Split(string(manifest), "\n")
	manifestLines[len(manifestLines)-1] = time.Now().Format(time.RFC3339)
	manifest = []byte(strings.Join(manifestLines, "\n"))
	err = ioutil.WriteFile("sessions/"+id+"/MANIFEST", manifest, filePerm)
	err = ioutil.WriteFile(serverDir+"sessions/"+id+"/MANIFEST", manifest, filePerm)
	if err != nil {
		return err
	}


@@ 146,7 146,7 @@ func receiveDiff(id, diff string) error {
		return err
	}
	// log diff
	diffFile, err := os.OpenFile("sessions/"+id+"/DIFF", os.O_APPEND|os.O_WRONLY|os.O_CREATE, filePerm)
	diffFile, err := os.OpenFile(serverDir+"sessions/"+id+"/DIFF", os.O_APPEND|os.O_WRONLY|os.O_CREATE, filePerm)
	if err != nil {
		return err
	}


@@ 154,7 154,7 @@ func receiveDiff(id, diff string) error {
	diffFile.Close()

	// update stage
	err = ioutil.WriteFile("sessions/"+id+"/STAGE", []byte(stage), 0644)
	err = ioutil.WriteFile(serverDir+"sessions/"+id+"/STAGE", []byte(stage), 0644)
	if err != nil {
		return err
	}


@@ 162,7 162,7 @@ func receiveDiff(id, diff string) error {
}

func previewStage(id string) (string, error) {
	stageContents, err := ioutil.ReadFile("sessions/" + id + "/STAGE")
	stageContents, err := ioutil.ReadFile(serverDir + "sessions/" + id + "/STAGE")
	if err != nil {
		return "", err
	}


@@ 183,7 183,7 @@ func previewPage(id string) (string, error) {
	manifest, err := parseManifest(id)
	title := manifest.PageTitle
	section := manifest.Section
	file, err := ioutil.ReadFile("sessions/" + id + "/" + title + ".gmi")
	file, err := ioutil.ReadFile(serverDir + "sessions/" + id + "/" + title + ".gmi")
	if err != nil {
		return "", err
	}


@@ 213,7 213,7 @@ func previewPage(id string) (string, error) {
}

func abortSession(id string) error {
	return os.RemoveAll("sessions/" + id)
	return os.RemoveAll(serverDir + "sessions/" + id)
}

func commitSession(id, msg string) error {


@@ 227,12 227,12 @@ func commitSession(id, msg string) error {
	if section != "meta" {
		section = "section " + section
	}
	diff, err := ioutil.ReadFile("sessions/" + id + "/" + "DIFF")
	diff, err := ioutil.ReadFile(serverDir + "sessions/" + id + "/" + "DIFF")
	if err != nil {
		return err
	}

	sessionPageFilePath := "sessions/" + id + "/" + title + ".gmi"
	sessionPageFilePath := serverDir + "sessions/" + id + "/" + title + ".gmi"

	// generate page preview
	preview, err := previewPage(id)


@@ 245,14 245,14 @@ func commitSession(id, msg string) error {
	}

	// merge page back upstream
	err = copyFile(sessionPageFilePath, "wiki/"+title+".gmi")
	err = copyFile(sessionPageFilePath, serverDir+"wiki/"+title+".gmi")
	if err != nil {
		return err
	}

	// keep history log
	entry := historyEntry{"EDITED", section, time.Now(), manifest.ClientIP, msg, string(diff)}
	histFile, err := os.OpenFile("history/"+title+".hist", os.O_APPEND|os.O_WRONLY|os.O_CREATE, filePerm)
	histFile, err := os.OpenFile(serverDir+"history/"+title+".hist", os.O_APPEND|os.O_WRONLY|os.O_CREATE, filePerm)
	defer histFile.Close()
	_, err = histFile.WriteString(entry.Marshal())
	if err != nil {