tools/cmd/melon-tools/main.go
2022-09-08 14:48:36 +01:00

119 lines
2.6 KiB
Go

package main
import (
"code.mrmelon54.com/melon/tools/module/discord"
"code.mrmelon54.com/melon/tools/module/gitea"
"code.mrmelon54.com/melon/tools/utils"
_ "embed"
"encoding/gob"
"fmt"
"github.com/google/uuid"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"github.com/joho/godotenv"
"html/template"
"log"
"net/http"
"os"
"sync"
)
var (
modules = []utils.IModule{
gitea.New(),
discord.New(),
}
sessionStore = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
//go:embed pages/index.go.html
indexTemplate string
)
func main() {
err := godotenv.Load()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
stateManager := StateManager{&sync.RWMutex{}, make(map[uuid.UUID]*utils.State)}
router := mux.NewRouter()
router.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Content-Type", "text/html")
rw.WriteHeader(http.StatusOK)
modTmp := make([]template.HTML, 0)
for _, v := range modules {
modTmp = append(modTmp, template.HTML(fmt.Sprintf("<a href=\"%s\">%s</a>", v.GetEndpoint(), v.GetName())))
}
tmp, err := template.New("homepage").Parse(indexTemplate)
if err != nil {
fmt.Println("Template parse error:", err)
return
}
err = tmp.Execute(rw, struct {
Modules []template.HTML
}{
Modules: modTmp,
})
if err != nil {
fmt.Println("Template execute error:", err)
return
}
})
gob.Register(uuid.UUID{})
for _, v := range modules {
a := v.GetEndpoint()
router.HandleFunc(a, func(rw http.ResponseWriter, req *http.Request) {
http.Redirect(rw, req, a+"/", http.StatusTemporaryRedirect)
})
v.SetupModule(router.PathPrefix(v.GetEndpoint()).Subrouter(), stateManager.sessionWrapper)
}
s := &http.Server{
Addr: os.Getenv("LISTEN"),
Handler: router,
}
err = s.ListenAndServe()
if err != nil {
if err == http.ErrServerClosed {
log.Println("Server closed successfully")
} else {
log.Fatalln(err)
}
return
}
}
type StateManager struct {
MSync *sync.RWMutex
States map[uuid.UUID]*utils.State
}
func (m *StateManager) sessionWrapper(cb func(http.ResponseWriter, *http.Request, *utils.State)) func(rw http.ResponseWriter, req *http.Request) {
return func(rw http.ResponseWriter, req *http.Request) {
session, _ := sessionStore.Get(req, "melon-tools-session")
if a, ok := session.Values["session-key"]; ok {
if b, ok := a.(uuid.UUID); ok {
m.MSync.RLock()
c, ok := m.States[b]
m.MSync.RUnlock()
if ok {
cb(rw, req, c)
return
}
}
}
u := utils.NewState()
m.MSync.Lock()
m.States[u.Uuid] = u
m.MSync.Unlock()
session.Values["session-key"] = u.Uuid
_ = session.Save(req, rw)
cb(rw, req, u)
}
}