add deps struct
This commit is contained in:
parent
79eb5da3e3
commit
b4ce07515c
@ -9,6 +9,8 @@ import (
|
||||
"codeword/internal/services"
|
||||
"codeword/internal/utils/encrypt"
|
||||
"context"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
@ -29,8 +31,16 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
|
||||
})
|
||||
|
||||
userRepo := repository.NewUserRepository(mdb)
|
||||
|
||||
recoveryEmailSender := &client.RecoveryEmailSender{}
|
||||
recoveryService := services.NewRecoveryService(logger, userRepo, recoveryEmailSender, encryptService)
|
||||
|
||||
recoveryService := services.NewRecoveryService(services.Deps{
|
||||
Logger: logger,
|
||||
Repository: userRepo,
|
||||
Email: recoveryEmailSender,
|
||||
EncryptService: encryptService,
|
||||
})
|
||||
|
||||
recoveryController := controller.NewRecoveryController(logger, recoveryService)
|
||||
|
||||
server := httpserver.NewServer(httpserver.ServerConfig{
|
||||
@ -47,19 +57,46 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
if err := shutdownApp(server, logger); err != nil {
|
||||
fmt.Println("<-ctx.Done()")
|
||||
|
||||
if err := shutdownApp(server, mdb, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("Приложение остановлено")
|
||||
return nil
|
||||
}
|
||||
|
||||
func shutdownApp(server *httpserver.Server, logger *zap.Logger) error {
|
||||
// TODO возможно стоит вынести в отдельные файлы или отказаться от разделения на отдельные методы
|
||||
|
||||
func shutdownApp(server *httpserver.Server, mdb *mongo.Database, logger *zap.Logger) error {
|
||||
if err := shutdownHTTPServer(server, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := shutdownMongoDB(mdb, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func shutdownHTTPServer(server *httpserver.Server, logger *zap.Logger) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
logger.Error("Ошибка при остановке сервера Fiber", zap.Error(err))
|
||||
logger.Error("Ошибка при остановке HTTP-сервера", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func shutdownMongoDB(mdb *mongo.Database, logger *zap.Logger) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := mdb.Client().Disconnect(ctx); err != nil {
|
||||
logger.Error("Ошибка при закрытии соединения с MongoDB", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -9,14 +9,14 @@ import (
|
||||
)
|
||||
|
||||
type RecoveryController struct {
|
||||
Logger *zap.Logger
|
||||
Service *services.RecoveryService
|
||||
logger *zap.Logger
|
||||
service *services.RecoveryService
|
||||
}
|
||||
|
||||
func NewRecoveryController(logger *zap.Logger, service *services.RecoveryService) *RecoveryController {
|
||||
return &RecoveryController{
|
||||
Logger: logger,
|
||||
Service: service,
|
||||
logger: logger,
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,31 +24,31 @@ func NewRecoveryController(logger *zap.Logger, service *services.RecoveryService
|
||||
func (r *RecoveryController) HandleRecoveryRequest(c *fiber.Ctx) error {
|
||||
email := c.FormValue("email")
|
||||
|
||||
key, err := r.Service.GenerateKey()
|
||||
key, err := r.service.GenerateKey()
|
||||
if err != nil {
|
||||
r.Logger.Error("Failed to generate key", zap.Error(err))
|
||||
r.logger.Error("Failed to generate key", zap.Error(err))
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
|
||||
}
|
||||
fmt.Println(key)
|
||||
|
||||
user, err := r.Service.FindUserByEmail(email)
|
||||
user, err := r.service.FindUserByEmail(email)
|
||||
if err != nil {
|
||||
r.Logger.Error("Failed to find user by email", zap.Error(err))
|
||||
r.logger.Error("Failed to find user by email", zap.Error(err))
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
||||
}
|
||||
fmt.Println(user)
|
||||
// сохраняем в бд
|
||||
signature, err := r.Service.StoreRecoveryRecord("user")
|
||||
signature, err := r.service.StoreRecoveryRecord("user")
|
||||
if err != nil {
|
||||
r.Logger.Error("Failed to store recovery record", zap.Error(err))
|
||||
r.logger.Error("Failed to store recovery record", zap.Error(err))
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
|
||||
}
|
||||
// тут что-то на подобии канала или что-то подобное так как отправка выполнятеся в воркере,
|
||||
//это пока временное решение для написания структуры кода и проверки отправки, далее перепишу
|
||||
// под горутины
|
||||
err = r.Service.SendRecoveryEmail(email, signature)
|
||||
err = r.service.SendRecoveryEmail(email, signature)
|
||||
if err != nil {
|
||||
r.Logger.Error("Failed to send recovery email", zap.Error(err))
|
||||
r.logger.Error("Failed to send recovery email", zap.Error(err))
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
|
||||
}
|
||||
|
||||
@ -59,21 +59,21 @@ func (r *RecoveryController) HandleRecoveryRequest(c *fiber.Ctx) error {
|
||||
func (r *RecoveryController) HandleRecoveryLink(c *fiber.Ctx) error {
|
||||
signature := c.Params("sign")
|
||||
// тут получается
|
||||
record, err := r.Service.GetRecoveryRecord(signature)
|
||||
record, err := r.service.GetRecoveryRecord(signature)
|
||||
if err != nil {
|
||||
r.Logger.Error("Failed to get recovery record", zap.Error(err))
|
||||
r.logger.Error("Failed to get recovery record", zap.Error(err))
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
|
||||
}
|
||||
|
||||
// проверка на более чем 15 минут
|
||||
if time.Since(record.CreatedAt) > 15*time.Minute {
|
||||
r.Logger.Error("Recovery link expired", zap.String("signature", signature))
|
||||
r.logger.Error("Recovery link expired", zap.String("signature", signature))
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Recovery link expired"})
|
||||
}
|
||||
|
||||
tokens, err := r.Service.ExchangeForTokens(record.UserID)
|
||||
tokens, err := r.service.ExchangeForTokens(record.UserID)
|
||||
if err != nil {
|
||||
r.Logger.Error("Failed to exchange recovery link for tokens", zap.Error(err))
|
||||
r.logger.Error("Failed to exchange recovery link for tokens", zap.Error(err))
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,9 @@ type Config struct {
|
||||
MongoPassword string `env:"MONGO_PASSWORD" envDefault:"admin"`
|
||||
MongoDatabase string `env:"MONGO_DB" envDefault:"codeword_db"`
|
||||
MongoAuth string `env:"MONGO_AUTH" envDefault:"admin"`
|
||||
PublicCurveKey string `env:"PUBLIC_CURVE_KEY,required"`
|
||||
PrivateCurveKey string `env:"PRIVATE_CURVE_KEY,required"`
|
||||
SignSecret string `env:"SIGN_SECRET,required"`
|
||||
PublicCurveKey string `env:"PUBLIC_CURVE_KEY" envDefault:"test"`
|
||||
PrivateCurveKey string `env:"PRIVATE_CURVE_KEY" envDefault:"test"`
|
||||
SignSecret string `env:"SIGN_SECRET" envDefault:"test"`
|
||||
}
|
||||
|
||||
func LoadConfig() (*Config, error) {
|
||||
|
@ -12,6 +12,8 @@ type UserRepository struct {
|
||||
db *mongo.Database
|
||||
}
|
||||
|
||||
//todo реализовать
|
||||
|
||||
func NewUserRepository(db *mongo.Database) *UserRepository {
|
||||
return &UserRepository{db}
|
||||
}
|
||||
@ -28,8 +30,6 @@ func (r *UserRepository) StoreRecoveryRecord(userID, signature string, createdAt
|
||||
}
|
||||
|
||||
func (r *UserRepository) GetRecoveryRecord(signature string) (*models.RestoreRequest, error) {
|
||||
//todo
|
||||
|
||||
return &models.RestoreRequest{UserID: "123", Sign: signature, CreatedAt: time.Now()}, nil
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,14 @@ func NewServer(config ServerConfig) *Server {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) Start(addr string) error {
|
||||
return s.app.Listen(addr)
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown(ctx context.Context) error {
|
||||
return s.app.Shutdown()
|
||||
}
|
||||
|
||||
func (s *Server) registerRoutes() {
|
||||
s.app.Get("/liveness", s.handleLiveness)
|
||||
s.app.Get("/readiness", s.handleReadiness)
|
||||
@ -64,11 +72,3 @@ func (s *Server) handleReadiness(c *fiber.Ctx) error {
|
||||
|
||||
return c.Status(fiber.StatusOK).SendString(responseMessage)
|
||||
}
|
||||
|
||||
func (s *Server) Start(addr string) error {
|
||||
return s.app.Listen(addr)
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown(ctx context.Context) error {
|
||||
return s.app.Shutdown()
|
||||
}
|
||||
|
@ -17,21 +17,26 @@ type EmailSender interface {
|
||||
SendRecoveryEmail(email, signature string) error
|
||||
}
|
||||
|
||||
// todo deps
|
||||
|
||||
type RecoveryService struct {
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Repository UserRepository
|
||||
Email EmailSender
|
||||
EncryptService *encrypt.Encrypt
|
||||
}
|
||||
|
||||
func NewRecoveryService(logger *zap.Logger, repository UserRepository, email EmailSender, encryptService *encrypt.Encrypt) *RecoveryService {
|
||||
type RecoveryService struct {
|
||||
logger *zap.Logger
|
||||
repository UserRepository
|
||||
email EmailSender
|
||||
encryptService *encrypt.Encrypt
|
||||
}
|
||||
|
||||
func NewRecoveryService(deps Deps) *RecoveryService {
|
||||
return &RecoveryService{
|
||||
Logger: logger,
|
||||
Repository: repository,
|
||||
Email: email,
|
||||
EncryptService: encryptService,
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
email: deps.Email,
|
||||
encryptService: deps.EncryptService,
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,25 +48,25 @@ func (s *RecoveryService) GenerateKey() (string, error) {
|
||||
|
||||
// FindUserByEmail ищет пользователя по электронной почте
|
||||
func (s *RecoveryService) FindUserByEmail(email string) (*models.User, error) {
|
||||
return s.Repository.FindByEmail(email)
|
||||
return s.repository.FindByEmail(email)
|
||||
}
|
||||
|
||||
// StoreRecoveryRecord сохраняет запись восстановления в базе данных
|
||||
func (s *RecoveryService) StoreRecoveryRecord(userID string) (string, error) {
|
||||
signature := ""
|
||||
createdAt := time.Now()
|
||||
err := s.Repository.StoreRecoveryRecord(userID, signature, createdAt)
|
||||
err := s.repository.StoreRecoveryRecord(userID, signature, createdAt)
|
||||
return signature, err
|
||||
}
|
||||
|
||||
// GetRecoveryRecord получает запись восстановления из базы данных
|
||||
func (s *RecoveryService) GetRecoveryRecord(signature string) (*models.RestoreRequest, error) {
|
||||
return s.Repository.GetRecoveryRecord(signature)
|
||||
return s.repository.GetRecoveryRecord(signature)
|
||||
}
|
||||
|
||||
// SendRecoveryEmail посылает письмо для восстановления доступа пользователю
|
||||
func (s *RecoveryService) SendRecoveryEmail(email string, signature string) error {
|
||||
return s.Email.SendRecoveryEmail(email, signature)
|
||||
return s.email.SendRecoveryEmail(email, signature)
|
||||
}
|
||||
|
||||
// ExchangeForTokens обменивает ссылку восстановления на токены используя сервис аутентификации.
|
||||
|
Loading…
Reference in New Issue
Block a user