Skip to content

Commit

Permalink
fix review part 3
Browse files Browse the repository at this point in the history
  • Loading branch information
Пешков Дмитрий committed Sep 17, 2024
1 parent f485732 commit 7186bc4
Show file tree
Hide file tree
Showing 16 changed files with 50 additions and 54 deletions.
4 changes: 3 additions & 1 deletion cmd/gophermart/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"github.com/spqrcor/gofermart/internal/authenticate"
"github.com/spqrcor/gofermart/internal/client"
"github.com/spqrcor/gofermart/internal/config"
"github.com/spqrcor/gofermart/internal/db"
Expand All @@ -28,6 +29,7 @@ func main() {
orderQueue := make(chan string)
defer close(orderQueue)

authService := authenticate.NewAuthenticateService(conf.SecretKey, conf.TokenExp)
userService := services.NewUserService(dbRes, conf.QueryTimeOut)
orderService := services.NewOrderService(orderQueue, dbRes, loggerRes, conf.QueryTimeOut)
withdrawalService := services.NewWithdrawalService(dbRes, loggerRes, conf.QueryTimeOut)
Expand All @@ -36,7 +38,7 @@ func main() {
orderWorker := workers.NewOrderWorker(mainCtx, orderService, orderQueue, loggerRes, conf.WorkerCount, orderClient)
orderWorker.Run()

appServer := server.NewServer(userService, orderService, withdrawalService, loggerRes, conf.RunAddr)
appServer := server.NewServer(userService, orderService, withdrawalService, loggerRes, conf.RunAddr, authService)
if err := appServer.Start(); err != nil {
loggerRes.Error(err.Error())
}
Expand Down
30 changes: 18 additions & 12 deletions internal/authenticate/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,43 @@ type ContextKey string

var ContextUserID ContextKey = "UserID"

const tokenExp = time.Hour * 3
const secretKey = "KLJ-fo3Fksd3fl!="
type Authenticate struct {
secretKey string
tokenExp time.Duration
}

func NewAuthenticateService(secretKey string, tokenExp time.Duration) *Authenticate {
return &Authenticate{secretKey: secretKey, tokenExp: tokenExp}
}

func CreateCookie(UserID uuid.UUID) (http.Cookie, error) {
token, err := createToken(UserID)
func (a *Authenticate) createCookie(UserID uuid.UUID) (http.Cookie, error) {
token, err := a.createToken(UserID)
if err != nil {
return http.Cookie{}, err
}
return http.Cookie{Name: "Authorization", Value: token, Expires: time.Now().Add(tokenExp), HttpOnly: true, Path: "/"}, nil
return http.Cookie{Name: "Authorization", Value: token, Expires: time.Now().Add(a.tokenExp), HttpOnly: true, Path: "/"}, nil
}

func createToken(UserID uuid.UUID) (string, error) {
func (a *Authenticate) createToken(UserID uuid.UUID) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, Claims{
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(tokenExp)),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(a.tokenExp)),
},
UserID: UserID,
})

tokenString, err := token.SignedString([]byte(secretKey))
tokenString, err := token.SignedString([]byte(a.secretKey))
if err != nil {
return "", err
}
return "Bearer " + tokenString, nil
}

func GetUserIDFromCookie(tokenString string) (uuid.UUID, error) {
func (a *Authenticate) GetUserIDFromCookie(tokenString string) (uuid.UUID, error) {
claims := &Claims{}
token, err := jwt.ParseWithClaims(strings.TrimPrefix(tokenString, "Bearer "), claims,
func(t *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
return []byte(a.secretKey), nil
})
if err != nil {
return uuid.Nil, err
Expand All @@ -59,8 +65,8 @@ func GetUserIDFromCookie(tokenString string) (uuid.UUID, error) {
return claims.UserID, nil
}

func SetCookie(rw http.ResponseWriter, UserID uuid.UUID) {
cookie, err := CreateCookie(UserID)
func (a *Authenticate) SetCookie(rw http.ResponseWriter, UserID uuid.UUID) {
cookie, err := a.createCookie(UserID)
if err == nil {
http.SetCookie(rw, &cookie)
}
Expand Down
4 changes: 4 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type Config struct {
DatabaseURI string `env:"DATABASE_URI"`
QueryTimeOut time.Duration `env:"QUERY_TIME_OUT"`
WorkerCount int `env:"WORKER_COUNT"`
SecretKey string `env:"SECRET_KEY"`
TokenExp time.Duration `env:"TOKEN_EXP"`
}

func NewConfig() Config {
Expand All @@ -25,6 +27,8 @@ func NewConfig() Config {
DatabaseURI: "",
QueryTimeOut: 3,
WorkerCount: 3,
SecretKey: "KLJ-fo3Fksd3fl!=",
TokenExp: time.Hour * 3,
}

flag.StringVar(&cfg.RunAddr, "a", cfg.RunAddr, "address and port to run server")
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/add_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func AddOrdersHandler(o services.OrderRepository) http.HandlerFunc {
func AddOrdersHandler(o *services.OrderService) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
orderNum, err := utils.FromPostPlain(req)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/add_withdrawals.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func AddWithdrawalHandler(w services.WithdrawalRepository) http.HandlerFunc {
func AddWithdrawalHandler(w *services.WithdrawalService) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
var input services.InputWithdrawal
if err := utils.FromPostJSON(req, &input); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/get_balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/http"
)

func GetBalanceHandler(w services.WithdrawalRepository) http.HandlerFunc {
func GetBalanceHandler(w *services.WithdrawalService) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
balance, err := w.GetBalance(req.Context())
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/get_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func GetOrdersHandler(o services.OrderRepository) http.HandlerFunc {
func GetOrdersHandler(o *services.OrderService) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
orders, err := o.GetAll(req.Context())
if errors.Is(err, services.ErrOrdersNotFound) {
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/get_withdrawals.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func GetWithdrawalsHandler(w services.WithdrawalRepository) http.HandlerFunc {
func GetWithdrawalsHandler(w *services.WithdrawalService) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
withdrawals, err := w.GetAll(req.Context())
if errors.Is(err, services.ErrWithdrawNotFound) {
Expand Down
4 changes: 2 additions & 2 deletions internal/handlers/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net/http"
)

func LoginHandler(u services.UserRepository) http.HandlerFunc {
func LoginHandler(u *services.UserService, a *authenticate.Authenticate) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
var input services.InputDataUser
if err := utils.FromPostJSON(req, &input); err != nil {
Expand All @@ -25,7 +25,7 @@ func LoginHandler(u services.UserRepository) http.HandlerFunc {
return
}

authenticate.SetCookie(res, UserID)
a.SetCookie(res, UserID)
res.WriteHeader(http.StatusOK)
}
}
4 changes: 2 additions & 2 deletions internal/handlers/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net/http"
)

func RegisterHandler(u services.UserRepository) http.HandlerFunc {
func RegisterHandler(u *services.UserService, a *authenticate.Authenticate) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
var input services.InputDataUser
if err := utils.FromPostJSON(req, &input); err != nil {
Expand All @@ -28,7 +28,7 @@ func RegisterHandler(u services.UserRepository) http.HandlerFunc {
return
}

authenticate.SetCookie(res, UserID)
a.SetCookie(res, UserID)
res.WriteHeader(http.StatusOK)
}
}
4 changes: 2 additions & 2 deletions internal/server/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (
"net/http"
)

func authenticateMiddleware(logger *zap.Logger) func(next http.Handler) http.Handler {
func authenticateMiddleware(logger *zap.Logger, auth *authenticate.Authenticate) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Authorization")
if err != nil {
http.Error(rw, err.Error(), http.StatusUnauthorized)
return
} else {
UserID, err := authenticate.GetUserIDFromCookie(cookie.Value)
UserID, err := auth.GetUserIDFromCookie(cookie.Value)
if err != nil {
logger.Error(err.Error())
http.Error(rw, err.Error(), http.StatusInternalServerError)
Expand Down
18 changes: 10 additions & 8 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@ package server
import (
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/spqrcor/gofermart/internal/authenticate"
"github.com/spqrcor/gofermart/internal/handlers"
"github.com/spqrcor/gofermart/internal/services"
"go.uber.org/zap"
"net/http"
)

type HTTPServer struct {
userService services.UserRepository
orderService services.OrderRepository
withdrawalService services.WithdrawalRepository
userService *services.UserService
orderService *services.OrderService
withdrawalService *services.WithdrawalService
logger *zap.Logger
runAddress string
authService *authenticate.Authenticate
}

func NewServer(userService services.UserRepository, orderService services.OrderRepository, withdrawalService services.WithdrawalRepository, logger *zap.Logger, runAddress string) *HTTPServer {
func NewServer(userService *services.UserService, orderService *services.OrderService, withdrawalService *services.WithdrawalService, logger *zap.Logger, runAddress string, authService *authenticate.Authenticate) *HTTPServer {
return &HTTPServer{
userService: userService, orderService: orderService, withdrawalService: withdrawalService, logger: logger, runAddress: runAddress,
userService: userService, orderService: orderService, withdrawalService: withdrawalService, logger: logger, runAddress: runAddress, authService: authService,
}
}

Expand All @@ -30,12 +32,12 @@ func (s *HTTPServer) Start() error {
r.Use(getBodyMiddleware(s.logger))

r.Group(func(r chi.Router) {
r.Post("/api/user/register", handlers.RegisterHandler(s.userService))
r.Post("/api/user/login", handlers.LoginHandler(s.userService))
r.Post("/api/user/register", handlers.RegisterHandler(s.userService, s.authService))
r.Post("/api/user/login", handlers.LoginHandler(s.userService, s.authService))
})

r.Group(func(r chi.Router) {
r.Use(authenticateMiddleware(s.logger))
r.Use(authenticateMiddleware(s.logger, s.authService))
r.Post("/api/user/orders", handlers.AddOrdersHandler(s.orderService))
r.Get("/api/user/orders", handlers.GetOrdersHandler(s.orderService))
r.Get("/api/user/balance", handlers.GetBalanceHandler(s.withdrawalService))
Expand Down
11 changes: 2 additions & 9 deletions internal/services/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ var ErrOrderUserExists = fmt.Errorf("order user exists")
var ErrOrderInvalidFormat = fmt.Errorf("order invalid format")
var ErrOrdersNotFound = fmt.Errorf("orders not found")

type OrderRepository interface {
Add(ctx context.Context, orderNum string) error
GetAll(ctx context.Context) ([]Order, error)
GetUnComplete(ctx context.Context) ([]string, error)
ChangeStatus(ctx context.Context, data OrderFromAccrual) error
}

type OrderService struct {
orderQueue chan string
db *sql.DB
Expand All @@ -56,8 +49,8 @@ func (o *OrderService) Add(ctx context.Context, orderNum string) error {

childCtx, cancel := context.WithTimeout(ctx, time.Second*o.queryTimeOut)
defer cancel()
err := o.db.QueryRowContext(childCtx, "INSERT INTO orders (id, user_id, number) VALUES ($1, $2, $3) "+
"ON CONFLICT(number) DO UPDATE SET number = EXCLUDED.number RETURNING id, user_id", orderID, ctx.Value(authenticate.ContextUserID), orderNum).Scan(&baseOrderID, &baseUserID)
err := o.db.QueryRowContext(childCtx, `INSERT INTO orders (id, user_id, number) VALUES ($1, $2, $3)
ON CONFLICT(number) DO UPDATE SET number = EXCLUDED.number RETURNING id, user_id`, orderID, ctx.Value(authenticate.ContextUserID), orderNum).Scan(&baseOrderID, &baseUserID)
if err != nil {
return err
} else if ctx.Value(authenticate.ContextUserID) != uuid.MustParse(baseUserID) {
Expand Down
5 changes: 0 additions & 5 deletions internal/services/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ type InputDataUser struct {
Password string `json:"password"`
}

type UserRepository interface {
Add(ctx context.Context, input InputDataUser) (uuid.UUID, error)
Login(ctx context.Context, input InputDataUser) (uuid.UUID, error)
}

type UserService struct {
db *sql.DB
queryTimeOut time.Duration
Expand Down
6 changes: 0 additions & 6 deletions internal/services/withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ type BalanceInfo struct {
var ErrBalance = fmt.Errorf("balance error")
var ErrWithdrawNotFound = fmt.Errorf("withdraw not found")

type WithdrawalRepository interface {
Add(ctx context.Context, input InputWithdrawal) error
GetAll(ctx context.Context) ([]Withdrawal, error)
GetBalance(ctx context.Context) (BalanceInfo, error)
}

type WithdrawalService struct {
db *sql.DB
logger *zap.Logger
Expand Down
4 changes: 2 additions & 2 deletions internal/workers/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (

type OrderWorker struct {
ctx context.Context
orderService services.OrderRepository
orderService *services.OrderService
orderQueue chan string
logger *zap.Logger
workerCount int
orderClient *client.OrderClient
}

func NewOrderWorker(ctx context.Context, orderService services.OrderRepository, orderQueue chan string, logger *zap.Logger, workerCount int, orderClient *client.OrderClient) *OrderWorker {
func NewOrderWorker(ctx context.Context, orderService *services.OrderService, orderQueue chan string, logger *zap.Logger, workerCount int, orderClient *client.OrderClient) *OrderWorker {
return &OrderWorker{ctx: ctx, orderService: orderService, orderQueue: orderQueue, logger: logger, workerCount: workerCount, orderClient: orderClient}
}

Expand Down

0 comments on commit 7186bc4

Please sign in to comment.