track/pkg/app/app.go

91 lines
2.2 KiB
Go
Raw Normal View History

2024-08-18 13:29:54 +03:00
package app
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/alexedwards/scs/boltstore"
"github.com/alexedwards/scs/v2"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
session "github.com/spazzymoto/echo-scs-session"
"gitrepo.ru/neonxp/track/pkg/config"
"gitrepo.ru/neonxp/track/pkg/handler"
"gitrepo.ru/neonxp/track/pkg/models"
"go.etcd.io/bbolt"
bolt "go.etcd.io/bbolt"
"golang.org/x/crypto/bcrypt"
)
func App(ctx context.Context) error {
cfg := config.New()
db, err := bolt.Open(cfg.DBPath, 0600, nil)
if err != nil {
return fmt.Errorf("failed open db: %w", err)
}
defer db.Close()
e := echo.New()
sessionManager := scs.New()
sessionManager.Store = boltstore.NewWithCleanupInterval(db, 5*time.Minute)
sessionManager.Lifetime = 30 * 24 * time.Hour
userHandler := handler.NewUser(db, sessionManager)
locationHandler := handler.NewLocation(db, sessionManager)
authFunc := func(s1, s2 string, c echo.Context) (bool, error) {
// TODO remove this shit
user := new(models.User)
s1 = strings.ReplaceAll(s1, "%40", "@")
err := db.View(func(tx *bbolt.Tx) error {
users := tx.Bucket([]byte("users"))
jb := users.Get([]byte(strings.ToLower(s1)))
if jb == nil {
return errors.New("invalid user or password")
}
if err := json.Unmarshal(jb, user); err != nil {
return err
}
if err := bcrypt.CompareHashAndPassword(user.Password, []byte(s2)); err != nil {
return errors.New("invalid user or password")
}
return nil
})
if err != nil {
return false, err
}
sessionManager.Put(c.Request().Context(), "user", user)
return true, nil
}
func(eg *echo.Group) {
eg.POST("/user/register", userHandler.Register)
eg.POST("/user/login", userHandler.Login)
eg.GET("/user", userHandler.User)
eg.GET("/point", locationHandler.AddPoint, middleware.BasicAuth(authFunc))
eg.GET("/points", locationHandler.GetPoints)
eg.GET("/points/last", locationHandler.GetLast)
}(e.Group("/api"))
e.Static("/", "./web")
e.Use(
middleware.Recover(),
middleware.Logger(),
session.LoadAndSave(sessionManager),
)
if err := e.Start(cfg.Listen); err != http.ErrServerClosed {
return err
}
return nil
}