add auth client

This commit is contained in:
Pavel 2024-01-04 17:57:30 +03:00
parent ebe7702d77
commit dc28f97562
8 changed files with 109 additions and 7 deletions

5
.env

@ -1,7 +1,7 @@
# General application settings
APP_NAME=codeword
HTTP_HOST="localhost"
HTTP_PORT="8000"
HTTP_PORT="8080"
# MongoDB settings
MONGO_HOST="127.0.0.1"
@ -33,4 +33,5 @@ SMTP_API_KEY="P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev"
SMTP_SENDER="noreply@mailing.pena.digital"
# URL settings
DEFAULT_REDIRECTION_URL = "def.url"
DEFAULT_REDIRECTION_URL = "def.url"
AUTH_REFRESH_URL = "http://localhost:8000/auth/refresh"

@ -0,0 +1,68 @@
package client
import (
"codeword/internal/models"
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)
type AuthClientDeps struct {
AuthUrl string
FiberClient *fiber.Client
Logger *zap.Logger
}
type AuthClient struct {
deps AuthClientDeps
}
func NewAuthClient(deps AuthClientDeps) *AuthClient {
if deps.FiberClient == nil {
deps.FiberClient = fiber.AcquireClient()
}
return &AuthClient{
deps: deps,
}
}
func (a *AuthClient) RefreshAuthToken(userID, signature string) (*models.RefreshResponse, error) {
body := models.AuthRequestBody{
UserID: userID,
Signature: signature,
}
bodyBytes, err := json.Marshal(body)
if err != nil {
a.deps.Logger.Error("Failed to encode request body", zap.Error(err))
return nil, err
}
agent := a.deps.FiberClient.Post(a.deps.AuthUrl)
agent.Set("Content-Type", "application/json").Body(bodyBytes)
//todo надо что-то придумать с авторизаиционными токенами
agent.Set("Authorization", "Bearer "+"123")
statusCode, resBody, errs := agent.Bytes()
if len(errs) > 0 {
for _, err := range errs {
a.deps.Logger.Error("Error in refresh auth token request", zap.Error(err))
}
return nil, fmt.Errorf("request failed: %v", errs)
}
if statusCode != fiber.StatusOK {
errorMessage := fmt.Sprintf("received an incorrect response from the authentication service: %d", statusCode)
a.deps.Logger.Error(errorMessage, zap.Int("status", statusCode))
return nil, fmt.Errorf(errorMessage)
}
var tokens models.RefreshResponse
if err := json.Unmarshal(resBody, &tokens); err != nil {
a.deps.Logger.Error("failed to unmarshal auth service response", zap.Error(err))
return nil, err
}
return &tokens, nil
}

@ -27,12 +27,14 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")})
userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")})
recoveryEmailSender := initialize.InitializeRecoveryEmailSender(cfg, logger)
authClient := initialize.InitializeAuthClient(cfg, logger)
recoveryService := services.NewRecoveryService(services.Deps{
Logger: logger,
CodewordRepository: codewordRepo,
UserRepository: userRepo,
Encrypt: encrypt,
AuthClient: authClient,
})
recoveryController := controller.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL)

@ -86,7 +86,7 @@ func (r *RecoveryController) HandleRecoveryLink(c *fiber.Ctx) error {
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, record.Sign)
if err != nil {
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"})

@ -21,3 +21,11 @@ func InitializeRecoveryEmailSender(cfg Config, logger *zap.Logger) *client.Recov
CodewordPort: cfg.HTTPPort,
})
}
func InitializeAuthClient(cfg Config, logger *zap.Logger) *client.AuthClient {
return client.NewAuthClient(client.AuthClientDeps{
AuthUrl: cfg.AuthURL,
Logger: logger,
FiberClient: &fiber.Client{},
})
}

@ -30,6 +30,7 @@ type Config struct {
SmtpApiKey string `env:"SMTP_API_KEY"`
SmtpSender string `env:"SMTP_SENDER"`
DefaultRedirectionURL string `env:"DEFAULT_REDIRECTION_URL"`
AuthURL string `env:"AUTH_REFRESH_URL"`
}
func LoadConfig() (*Config, error) {

11
internal/models/auth.go Normal file

@ -0,0 +1,11 @@
package models
type AuthRequestBody struct {
UserID string `json:"userId"`
Signature string `json:"signature"`
}
type RefreshResponse struct {
AccessToken string `json:"accessToken"`
RefreshToken string `json:"refreshToken"`
}

@ -1,6 +1,7 @@
package services
import (
"codeword/internal/adapters/client"
"codeword/internal/models"
"codeword/internal/utils/encrypt"
"context"
@ -24,6 +25,7 @@ type Deps struct {
CodewordRepository CodewordRepository
UserRepository UserRepository
Encrypt *encrypt.Encrypt
AuthClient *client.AuthClient
}
type RecoveryService struct {
@ -31,6 +33,7 @@ type RecoveryService struct {
repositoryCodeword CodewordRepository
repositoryUser UserRepository
encrypt *encrypt.Encrypt
authClient *client.AuthClient
}
func NewRecoveryService(deps Deps) *RecoveryService {
@ -39,6 +42,7 @@ func NewRecoveryService(deps Deps) *RecoveryService {
repositoryCodeword: deps.CodewordRepository,
repositoryUser: deps.UserRepository,
encrypt: deps.Encrypt,
authClient: deps.AuthClient,
}
}
@ -117,8 +121,15 @@ func (s *RecoveryService) GetRecoveryRecord(ctx context.Context, key string) (*m
return req, nil
}
// ExchangeForTokens обменивает ссылку восстановления на токены используя сервис аутентификации.
func (s *RecoveryService) ExchangeForTokens(userID string) (map[string]string, error) {
// TODO
return nil, nil
func (s *RecoveryService) ExchangeForTokens(userID string, signature string) (map[string]string, error) {
tokens, err := s.authClient.RefreshAuthToken(userID, signature)
if err != nil {
s.logger.Error("Failed to refresh auth token", zap.Error(err))
return nil, err
}
return map[string]string{
"accessToken": tokens.AccessToken,
"refreshToken": tokens.RefreshToken,
}, nil
}