Files
tp/main_dc/yalarba/api_yal/internal/domain/auth/handler.go
T
valitovgaziz d45c5841dc modified: main_dc/yalarba/api_yal/go.mod
modified:   main_dc/yalarba/api_yal/go.sum
	modified:   main_dc/yalarba/api_yal/internal/domain/auth/dto.go
	modified:   main_dc/yalarba/api_yal/internal/domain/auth/handler.go
	modified:   main_dc/yalarba/api_yal/internal/domain/auth/router.go
	modified:   main_dc/yalarba/api_yal/internal/domain/auth/servcie.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/auth.go
	deleted:    main_dc/yalarba/api_yal/internal/middleware/authMiddleware.go
	modified:   main_dc/yalarba/api_yal/internal/router/router.go
set auth domain, not tested
2026-03-10 00:35:25 +05:00

251 lines
7.1 KiB
Go

package auth
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"api_yal/internal/logger"
"api_yal/internal/middleware"
"github.com/go-playground/validator/v10"
"go.uber.org/zap"
)
// AuthHandler обработчик для аутентификации
type AuthHandler struct {
authService AuthService
validator *validator.Validate
}
// NewAuthHandler создает новый экземпляр AuthHandler
func NewAuthHandler(authService *AuthService) *AuthHandler {
return &AuthHandler{
authService: *authService,
validator: validator.New(),
}
}
// Register регистрация аккаунта пользователя
func (h *AuthHandler) Register(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Регистрация нового пользователя AuthHandler")
var req RegisterRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if err := h.validator.Struct(req); err != nil {
var invalidValidationError *validator.InvalidValidationError
if errors.As(err, &invalidValidationError) {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
var errs []string
for _, err := range err.(validator.ValidationErrors) {
errs = append(errs, fmt.Sprintf("field %s is invalid: %s", err.Field(), err.Tag()))
}
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{
"error": "Validation failed",
"fields": errs,
})
return
}
response, err := h.authService.Register(req)
if err != nil {
l.Error("Ошибка регистрации: %v", zap.Error(err))
status := http.StatusInternalServerError
message := "Registration failed"
if errors.Is(err, ErrUserAlreadyExists) {
status = http.StatusConflict
message = "User with this email already exists"
}
http.Error(w, message, status)
return
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(response)
}
// Login вход пользователя
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Вход пользователя AuthHandler")
var req LoginRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if err := h.validator.Struct(req); err != nil {
var invalidValidationError *validator.InvalidValidationError
if errors.As(err, &invalidValidationError) {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
var errs []string
for _, err := range err.(validator.ValidationErrors) {
errs = append(errs, fmt.Sprintf("field %s is invalid: %s", err.Field(), err.Tag()))
}
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{
"error": "Validation failed",
"fields": errs,
})
return
}
response, err := h.authService.Login(req)
if err != nil {
l.Error("Ошибка входа: %v", zap.Error(err))
status := http.StatusUnauthorized
message := "Login failed"
if errors.Is(err, ErrUserNotFound) {
message = "User not found"
} else if errors.Is(err, ErrInvalidPassword) {
message = "Invalid password"
}
http.Error(w, message, status)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// RefreshToken обновление токена
func (h *AuthHandler) RefreshToken(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Обновление токена AuthHandler")
// Получаем токен из заголовка Authorization
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
http.Error(w, "Authorization header required", http.StatusUnauthorized)
return
}
// Ожидаем формат "Bearer <token>"
parts := strings.Split(authHeader, " ")
if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
http.Error(w, "Invalid authorization header format", http.StatusUnauthorized)
return
}
response, err := h.authService.RefreshToken(parts[1])
if err != nil {
l.Error("Ошибка обновления токена: %v", zap.Error(err))
http.Error(w, "Token refresh failed", http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// Logout выход пользователя
func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Выход пользователя AuthHandler")
// Получаем ID пользователя из контекста (устанавливается middleware)
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
if err := h.authService.Logout(userID); err != nil {
l.Error("Ошибка выхода: %v", zap.Error(err))
http.Error(w, "Logout failed", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"message": "Successfully logged out",
})
}
// GetProfile получение профиля пользователя
func (h *AuthHandler) GetProfile(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Получение профиля пользователя")
// Получаем ID пользователя из контекста
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// TODO: Реализовать получение профиля через сервис
// response, err := h.authService.GetProfile(userID)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"user_id": userID,
"message": "Profile endpoint - to be implemented",
})
}
// UpdateProfile обновление профиля пользователя
func (h *AuthHandler) UpdateProfile(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Обновление профиля пользователя")
// Получаем ID пользователя из контекста
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// TODO: Реализовать обновление профиля
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"user_id": userID,
"message": "Update profile endpoint - to be implemented",
})
}
// ChangePassword смена пароля
func (h *AuthHandler) ChangePassword(w http.ResponseWriter, r *http.Request) {
l := logger.Get()
l.Debug("Смена пароля пользователя")
// Получаем ID пользователя из контекста
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// TODO: Реализовать смену пароля
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"user_id": userID,
"message": "Change password endpoint - to be implemented",
})
}