123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package webserver
- import (
- "encoding/hex"
- "errors"
- "fmt"
- "html/template"
- "io"
- "log"
- "math/rand"
- "strings"
- gamelangpb "git.alfi.li/gamelang/protobuf/gamelang"
- "github.com/gorilla/sessions"
- "github.com/labstack/echo-contrib/session"
- "github.com/labstack/echo/v4"
- echolog "github.com/labstack/gommon/log"
- )
- // Template wraps go's html template
- type Template struct {
- templates *template.Template
- }
- // Render renders a Template
- func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
- return t.templates.ExecuteTemplate(w, name, data)
- }
- func initTemplates(e *echo.Echo) {
- t := &Template{
- templates: template.Must(template.ParseGlob("public/*.html")),
- }
- e.Renderer = t
- }
- type Config struct {
- Http struct {
- ListenIP string
- ListenPort string
- }
- }
- type Endpoint struct {
- Method string
- Path string
- Callback echo.HandlerFunc
- }
- type Webserver struct {
- config Config
- echo *echo.Echo
- sessions map[string]gamelangpb.User
- }
- func NewWebserver(config Config) *Webserver {
- // init echo
- e := echo.New()
- e.Logger.SetLevel(echolog.DEBUG)
- e.Logger.Debug("Debug Log enabled")
- e.Use(session.Middleware(sessions.NewCookieStore([]byte("secret"))))
- initTemplates(e)
- log.Print("echo initialized")
- ws := Webserver{config: config, echo: e, sessions: map[string]gamelangpb.User{}}
- return &ws
- }
- func (ws *Webserver) NewSession(inputuser gamelangpb.User, ctx echo.Context) string {
- newSessionID, _ := randomHex(32)
- sess, _ := session.Get("GameLang", ctx)
- sess.Values["SessionID"] = newSessionID
- sess.Save(ctx.Request(), ctx.Response())
- user := gamelangpb.User{}
- user.Id = inputuser.Id
- user.Name = inputuser.Name
- ws.sessions[newSessionID] = user
- return newSessionID
- }
- func (ws *Webserver) CheckSess(ctx echo.Context) (bool, gamelangpb.User) {
- sess, err := session.Get("GameLang", ctx)
- if err != nil {
- log.Print("checkSess: user not logged in")
- return false, gamelangpb.User{}
- }
- sessionID, ok := sess.Values["SessionID"]
- if !ok {
- log.Print("checkSess: no SessionID value")
- return false, gamelangpb.User{}
- }
- user, ok := ws.sessions[sessionID.(string)]
- if !ok {
- log.Println("checkSess: no Session found for ID", sessionID.(string))
- return false, gamelangpb.User{}
- }
- return true, user
- }
- func (ws *Webserver) ListSess() map[string]gamelangpb.User {
- return ws.sessions
- }
- func (ws *Webserver) InitEndpoints(endpoints []Endpoint) error {
- for _, endpoint := range endpoints {
- switch strings.ToUpper(endpoint.Method) {
- case "GET":
- ws.echo.GET(endpoint.Path, endpoint.Callback)
- case "POST":
- ws.echo.POST(endpoint.Path, endpoint.Callback)
- default:
- return errors.New("method not implemented")
- }
- }
- return nil
- }
- func (ws *Webserver) Run() {
- ws.echo.Logger.Fatal(ws.echo.Start(fmt.Sprintf("%v:%v", ws.config.Http.ListenIP, ws.config.Http.ListenPort)))
- }
- func randomHex(n int) (string, error) {
- bytes := make([]byte, n)
- if _, err := rand.Read(bytes); err != nil {
- return "", err
- }
- return hex.EncodeToString(bytes), nil
- }
|