package api import ( "log" "strings" "time" "io/fs" "os" "path/filepath" "github.com/gofiber/fiber/v2" _ "github.com/mattn/go-sqlite3" sq "github.com/Masterminds/squirrel" "github.com/gofiber/fiber/v2/middleware/session" "github.com/gofiber/template/html/v2" "zedshaw.games/webapp/data" ) var STORE *session.Store func GetApiLogout(c *fiber.Ctx) error { err := LogoutUser(c) if err != nil { return IfErrNil(err, c) } return c.Redirect("/") } func GetApiStream(c *fiber.Ctx) error { authed, _, err := CheckAuthed(c) if NotAuthed(err, authed) { return IfErrNil(err, c) } sql, args, err := sq.Select("*").From("stream").ToSql() err = data.SelectJson[data.Stream](c, err, sql, args...) return IfErrNil(err, c) } func GetApiStreamId(c *fiber.Ctx) error { sql, args, err := sq.Select("*"). From("stream").Where("id=?", c.Params("id")).ToSql() err = data.GetJson[data.Stream](c, err, sql, args...) return IfErrNil(err, c) } func GetApiStreamIdLinks(c *fiber.Ctx) error { sql, args, err := sq.Select("*"). From("stream_link"). Where("stream_id=?", c.Params("id")).ToSql() err = data.SelectJson[data.Link](c, err, sql, args...) return IfErrNil(err, c) } func PostApiRegister(c *fiber.Ctx) error { user, err := ReceivePost[data.User](c) if err != nil { return IfErrNil(err, c) } err = SetUserPassword(user) if err != nil { return IfErrNil(err, c) } sql, args, err := sq.Insert("user"). Columns("username", "email", "password"). Values(user.Username, user.Email, user.Password).ToSql() err = data.Exec(err, sql, args...) if err != nil { return IfErrNil(err, c) } return c.Redirect("/login/") } func PostApiLogin(c *fiber.Ctx) error { var user data.User login, err := ReceivePost[data.Login](c) if(err != nil) { return IfErrNil(err, c) } pass_good, err := LoginUser(&user, login) if err != nil { return IfErrNil(err, c) } if pass_good { sess, err := STORE.Get(c) if err != nil { return IfErrNil(err, c) } sess.Set("authenticated", true) err = sess.Save() if err != nil { return IfErrNil(err, c) } return c.Redirect("/") } else { return c.Redirect("/login/") } } func PostApiLink(c *fiber.Ctx) error { var sql string var args []interface{} link, err := ReceivePost[data.Link](c) if err != nil { goto fail } sql, args, err = sq.Insert("stream_blah"). Columns("stream_id", "url", "description"). Values(link.StreamId, link.Url, link.Description).ToSql() err = data.Exec(err, sql, args...) if(err != nil) { goto fail } return c.Redirect("/live/") fail: return IfErrNil(err, c) } func RenderPages(pages_path string, target string) { engine := html.New(pages_path, ".html") engine.Load() err := filepath.WalkDir(pages_path, func(path string, d fs.DirEntry, err error) error { if !d.IsDir() { if err != nil { log.Printf("ERROR: %v", err) } dir := filepath.Dir(path) err = os.MkdirAll(dir, 0750) if err != nil { log.Fatalf("ERROR making dir %s, %v", dir, err) } split_path := strings.Split(path, string(os.PathSeparator))[1:] source_name := filepath.Join(split_path...) ext := filepath.Ext(source_name) name, found := strings.CutSuffix(source_name, ext) if found { log.Printf("name=%s, ext=%s, dir=%s, found=%v", name, ext, dir, found) prefixed_path := append([]string{target}, split_path...) target_path := filepath.Join(prefixed_path...) log.Printf("target_path: %s", target_path) out, err := os.OpenFile(target_path, os.O_RDWR|os.O_CREATE, 0644) if err != nil { log.Fatalf("ERROR writing file %s", target_path) } err = engine.Render(out, "game/1/turings-tarpit/index", fiber.Map{"Title": "Hello"}) if err != nil { log.Fatalf("failed to render %s, error=%v", path, err) } out.Close() } } return nil }) if err != nil { log.Fatalf("can't walk content") } } func Setup(app *fiber.App) { STORE = session.New() RenderPages("./pages", "./public") app.Static("/", "./public", fiber.Static{ Compress: false, CacheDuration: 1 * time.Nanosecond, }) app.Get("/api/stream", GetApiStream) app.Get("/api/logout", GetApiLogout) app.Get("/api/stream/:id", GetApiStreamId) app.Get("/api/stream/:id/links", GetApiStreamIdLinks) app.Post("/api/login", PostApiLogin) app.Post("/api/link", PostApiLink) app.Post("/api/register", PostApiRegister) } func Shutdown() { log.Println("Shutting down controllers...") }