Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diplom #7

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ vendor/
# IDEs directories
.idea
.vscode
.env
Binary file removed cmd/accrual/accrual_windows_amd64
Binary file not shown.
8 changes: 7 additions & 1 deletion cmd/gophermart/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
package main

func main() {}
import (
"github.com/botaevg/gophermart/internal/app"
)

func main() {
app.StartApp()
}
20 changes: 20 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module github.com/botaevg/gophermart

go 1.18

require (
github.com/caarlos0/env/v6 v6.9.3 // indirect
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
github.com/go-chi/chi/v5 v5.0.7 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.12.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.11.0 // indirect
github.com/jackc/pgx/v4 v4.16.1 // indirect
github.com/jackc/puddle v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/text v0.3.7 // indirect
)
176 changes: 176 additions & 0 deletions go.sum

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions internal/ExternalService/clientRequest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package externalservice

import (
"encoding/json"
"fmt"
"github.com/botaevg/gophermart/internal/models"
"github.com/botaevg/gophermart/internal/service"
"io"
"log"
"net/http"
)

type ExternalService struct {
gophermart service.Gophermart
asyncExecution chan string
accrualSystemAddress string
}

func NewES(accrualSystemAddress string, gophermart service.Gophermart, asyncExecution chan string) ExternalService {
return ExternalService{
accrualSystemAddress: accrualSystemAddress,
gophermart: gophermart,
asyncExecution: asyncExecution,
}
}

func (e ExternalService) AccrualPoints(orderID string) {
client := http.Client{}

URL := fmt.Sprintf("%s/api/orders/%s", e.accrualSystemAddress, orderID)
log.Print(URL)
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
log.Print(err)
return
}

resp, err := client.Do(req)
if err != nil {
log.Print(err)
return
}
log.Print(resp.Status)
if resp.Status == "200 OK" {
respBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Print(err)
return
}
defer resp.Body.Close()

var Order models.OrderES
err = json.Unmarshal(respBody, &Order)
if err != nil {
log.Print(err)
}
log.Print(Order)

e.gophermart.UpdateOrders(Order)

if Order.Status == "PROCESSED" {
e.gophermart.AccrualRequest(Order)
}

if Order.Status == "REGISTERED" || Order.Status == "PROCESSING" {
e.asyncExecution <- orderID
return
}

} else {
e.asyncExecution <- orderID
}
}
62 changes: 62 additions & 0 deletions internal/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package app

import (
"github.com/botaevg/gophermart/internal/ExternalService"
"github.com/botaevg/gophermart/internal/apperror"
"github.com/botaevg/gophermart/internal/config"
"github.com/botaevg/gophermart/internal/handlers"
"github.com/botaevg/gophermart/internal/repositories"
"github.com/botaevg/gophermart/internal/service"
"github.com/botaevg/gophermart/pkg/postgre"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"log"
"net/http"
)

func StartApp() {
cfg, err := config.GetConfig()
if err != nil {
log.Print("config error")
return
}
dbpool, err := postgre.NewClient(cfg.DataBaseDsn)
if err != nil {
log.Print("DB connect error")
return
}

storage := repositories.NewDB(dbpool)

auth := service.NewAuth(storage, cfg.SecretKey)
log.Print(cfg.SecretKey)
gophermart := service.NewGophermart(storage)
r := chi.NewRouter()

asyncChannel := make(chan string)
externalService := externalservice.NewES(cfg.AccrualSystemAddress, gophermart, asyncChannel)
h := handlers.NewHandler(cfg, auth, gophermart, asyncChannel)
go func() {
for job := range asyncChannel {
log.Print("async go")
externalService.AccrualPoints(job)
}
}()

authcookie := apperror.NewAuthMiddleware(cfg.SecretKey)
r.Use(authcookie.AuthCookie)

r.Use(middleware.Logger)

r.Post("/api/user/register", h.RegisterUser)
r.Post("/api/user/login", h.Login)

r.Post("/api/user/orders", h.LoadOrder)
r.Get("/api/user/orders", h.GetListOrders)

r.Get("/api/user/balance", h.BalanceUser)
r.Post("/api/user/balance/withdraw", h.WithdrawRequest)
r.Get("/api/user/withdrawals", h.ListWithdraw)

log.Fatal(http.ListenAndServe(cfg.RunAddress, r))
}
59 changes: 59 additions & 0 deletions internal/apperror/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package apperror

import (
"context"
"errors"
"github.com/botaevg/gophermart/internal/service"
"github.com/dgrijalva/jwt-go/v4"
"log"
"net/http"
)

type AuthMiddleware struct {
secretkey string
}

func NewAuthMiddleware(key string) *AuthMiddleware {
return &AuthMiddleware{
secretkey: key,
}
}

type UserID string

func (a AuthMiddleware) AuthCookie(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
openURL := []string{"/api/user/register", "/api/user/login"}
path := r.URL.Path
for _, v := range openURL {
if v == path {
next.ServeHTTP(w, r)
return
}
}
ctoken, err := r.Cookie("Bearer")
if err != nil {
http.Error(w, errors.New("unauthorized").Error(), http.StatusUnauthorized)
return
}

tokenClaims := &service.Claims{}
token, err := jwt.ParseWithClaims(ctoken.Value, tokenClaims, func(token *jwt.Token) (interface{}, error) {
return []byte(a.secretkey), nil
})
if err != nil {
http.Error(w, errors.New("token error").Error(), http.StatusUnauthorized)
return
}
if !token.Valid {
http.Error(w, errors.New("token disabled").Error(), http.StatusUnauthorized)
return
}
log.Print("userID middle")
log.Print(tokenClaims.UserID)
ctx := context.WithValue(r.Context(), UserID("username"), tokenClaims.UserID)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)

})
}
30 changes: 30 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package config

import (
"flag"
"github.com/caarlos0/env/v6"
)

type Config struct {
RunAddress string `env:"RUN_ADDRESS"`
DataBaseDsn string `env:"DATABASE_URI"`
AccrualSystemAddress string `env:"ACCRUAL_SYSTEM_ADDRESS"`
SecretKey string `env:"SECRETKEY"`
}

func GetConfig() (Config, error) {
cfg := Config{}

flag.StringVar(&cfg.RunAddress, "a", "", "port start listen")
flag.StringVar(&cfg.DataBaseDsn, "d", "", "database dsn")
flag.StringVar(&cfg.AccrualSystemAddress, "r", "", "AccrualSystemAddress")
flag.StringVar(&cfg.SecretKey, "s", "", "salt")
flag.Parse()
//postgresql://postgres:sqllife@localhost:5434/gophermart
//:8080 :8080
if err := env.Parse(&cfg); err != nil {
return Config{}, err
}

return cfg, nil
}
Loading