diff options
author | Alexander Neonxp Kiryukhin <i@neonxp.ru> | 2024-08-18 13:29:54 +0300 |
---|---|---|
committer | Alexander Neonxp Kiryukhin <i@neonxp.ru> | 2024-08-18 13:29:54 +0300 |
commit | fd70f95224374d23157ee7c0357733102cd0df53 (patch) | |
tree | e490c12e021cedaf211b292d5d623baa32a673fc /pkg/app/app.go |
Diffstat (limited to 'pkg/app/app.go')
-rw-r--r-- | pkg/app/app.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go new file mode 100644 index 0000000..9a2df50 --- /dev/null +++ b/pkg/app/app.go @@ -0,0 +1,90 @@ +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 +} |