119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"code.mrmelon54.xyz/sean/melon-tools/module/discord"
|
|
"code.mrmelon54.xyz/sean/melon-tools/module/gitea"
|
|
"code.mrmelon54.xyz/sean/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)
|
|
}
|
|
}
|