From b32bc780d631f2efcdb468b47e4201fe48906ac1 Mon Sep 17 00:00:00 2001 From: optclblast Date: Sat, 11 May 2024 00:18:56 +0300 Subject: [PATCH] tmp --- backend/README.md | 33 ---------- backend/internal/interface/rest/server.go | 75 ++++++++++++++++++----- backend/internal/pkg/ctxmeta/context.go | 40 ++++++++++++ 3 files changed, 101 insertions(+), 47 deletions(-) create mode 100644 backend/internal/pkg/ctxmeta/context.go diff --git a/backend/README.md b/backend/README.md index 0c1b305..c0cf5e1 100644 --- a/backend/README.md +++ b/backend/README.md @@ -109,39 +109,6 @@ Response: } ``` - -## POST **/join** -### Request body: -name (string, optional) -credentals (object, optional) - credentals.email (string, optional) - credentals.phone (string, optional) - credentals.telegram (string, optional) -mnemonic (string, **required**) - -### Example -Request: -``` bash -curl --location 'http://localhost:8081/login' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "name": "Bladee The Grand Drainer", - "credentals": { - "email": "bladeee@gmail.com", - "phone": "+79999999999", - "telegram": "@thebladee" - }, - "mnemonic":"airport donate language disagree dumb access insect tribe ozone humor foot jealous much digital confirm" -}' -``` - -Response: -``` json -{ - "token": "token-here" -} -``` - ## POST **/organization** ### Request body: name (string, **required**) diff --git a/backend/internal/interface/rest/server.go b/backend/internal/interface/rest/server.go index 0041b2c..03254e8 100644 --- a/backend/internal/interface/rest/server.go +++ b/backend/internal/interface/rest/server.go @@ -6,13 +6,16 @@ import ( "fmt" "log/slog" "net/http" + "strings" "sync" "time" "github.com/emochka2007/block-accounting/internal/interface/rest/controllers" "github.com/emochka2007/block-accounting/internal/pkg/config" + "github.com/emochka2007/block-accounting/internal/pkg/ctxmeta" "github.com/emochka2007/block-accounting/internal/pkg/logger" "github.com/emochka2007/block-accounting/internal/pkg/metrics" + "github.com/emochka2007/block-accounting/internal/usecase/interactors/jwt" "github.com/go-chi/chi/v5" mw "github.com/go-chi/chi/v5/middleware" "github.com/go-chi/render" @@ -29,6 +32,8 @@ type Server struct { tls bool controllers *controllers.RootController + jwt jwt.JWTInteractor + closeMu sync.RWMutex closed bool } @@ -89,23 +94,27 @@ func (s *Server) buildRouter() { router.Post("/join", s.handle(s.controllers.Auth.Join, "join")) router.Post("/login", s.handle(s.controllers.Auth.Login, "login")) - router.Post("/organization", s.handle(s.controllers.Auth.Invite, "organization")) + router.Route("/organization", func(r chi.Router) { + r.With(s.withAuthorization) - router.Route("/organization/{organization_id}", func(r chi.Router) { - router.Route("/transactions", func(r chi.Router) { - r.Get("/", nil) // list - r.Post("/", nil) // add - r.Put("/{tx_id}", nil) // update / approve (or maybe body?) - r.Delete("/{tx_id}", nil) // remove - }) + r.Get("/", s.handle(s.controllers.Auth.Invite, "organization")) - r.Post("/invite/{hash}", s.handle(s.controllers.Auth.Invite, "invite")) // create a new invite link + r.Route("/{organization_id}", func(r chi.Router) { + r.Route("/transactions", func(r chi.Router) { + r.Get("/", nil) // list + r.Post("/", nil) // add + r.Put("/{tx_id}", nil) // update / approve (or maybe body?) + r.Delete("/{tx_id}", nil) // remove + }) - r.Route("/employees", func(r chi.Router) { - r.Get("/", nil) // list - r.Post("/", nil) // add - r.Put("/{employee_id}", nil) // update (or maybe body?) - r.Delete("/{employee_id}", nil) // remove + r.Post("/invite/{hash}", s.handle(s.controllers.Auth.Invite, "invite")) // create a new invite link + + r.Route("/employees", func(r chi.Router) { + r.Get("/", nil) // list + r.Post("/", nil) // add + r.Put("/{employee_id}", nil) // update (or maybe body?) + r.Delete("/{employee_id}", nil) // remove + }) }) }) @@ -173,3 +182,41 @@ func (s *Server) handleMw(next http.Handler) http.Handler { return http.HandlerFunc(fn) } + +func (s *Server) withAuthorization(next http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + tokenStringRaw := r.Header.Get("Authorization") + if tokenStringRaw == "" { + s.log.Warn( + "unauthorized request", + slog.String("remote_addr", r.RemoteAddr), + slog.String("endpoint", r.RequestURI), + ) + + w.WriteHeader(401) + + return + } + + tokenString := strings.Split(tokenStringRaw, " ")[1] + + user, err := s.jwt.User(tokenString) + if err != nil { + s.log.Warn( + "unauthorized request", + slog.String("remote_addr", r.RemoteAddr), + slog.String("endpoint", r.RequestURI), + logger.Err(err), + ) + + s.responseError(w, err) + return + } + + next.ServeHTTP(w, r.WithContext( + ctxmeta.UserContext(r.Context(), user), + )) + } + + return http.HandlerFunc(fn) +} diff --git a/backend/internal/pkg/ctxmeta/context.go b/backend/internal/pkg/ctxmeta/context.go new file mode 100644 index 0000000..8c843a0 --- /dev/null +++ b/backend/internal/pkg/ctxmeta/context.go @@ -0,0 +1,40 @@ +package ctxmeta + +import ( + "context" + "fmt" + + "github.com/emochka2007/block-accounting/internal/pkg/models" + "github.com/google/uuid" +) + +type ContextKey string + +var ( + UserContextKey = ContextKey("user") + OrganizationIdContextKey = ContextKey("org-id") +) + +func UserContext(parent context.Context, user *models.User) context.Context { + return context.WithValue(parent, UserContextKey, user) +} + +func User(ctx context.Context) (*models.User, error) { + if user, ok := ctx.Value(UserContextKey).(*models.User); ok { + return user, nil + } + + return nil, fmt.Errorf("error user not passed in context") +} + +func OrganizationIdContext(parent context.Context, id uuid.UUID) context.Context { + return context.WithValue(parent, OrganizationIdContextKey, id) +} + +func OrganizationId(ctx context.Context) (uuid.UUID, error) { + if id, ok := ctx.Value(OrganizationIdContextKey).(uuid.UUID); ok { + return id, nil + } + + return uuid.Nil, fmt.Errorf("error organization id not passed in context") +}