1c74d12df6
modified: main_dc/yalarba/api_es/go.sum new file: main_dc/yalarba/api_es/internal/dto/user.go new file: main_dc/yalarba/api_es/internal/handler/all_handlers.go new file: main_dc/yalarba/api_es/internal/handler/auth_handler.go new file: main_dc/yalarba/api_es/internal/handler/user_handler.go deleted: main_dc/yalarba/api_es/internal/handlers/all_handlers.go deleted: main_dc/yalarba/api_es/internal/handlers/auth_handler.go deleted: main_dc/yalarba/api_es/internal/handlers/user_handler.go new file: main_dc/yalarba/api_es/internal/middleware/auth.go deleted: main_dc/yalarba/api_es/internal/repositories/user_repository.go new file: main_dc/yalarba/api_es/internal/repository/user_repository.go new file: main_dc/yalarba/api_es/internal/service/user_service.go new file: main_dc/yalarba/api_es/internal/utils/jwt.go add service, handler, repository for user model
195 lines
5.0 KiB
Go
195 lines
5.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"api_es/internal/dto"
|
|
"api_es/internal/models"
|
|
"api_es/internal/repository"
|
|
"api_es/internal/utils"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
var (
|
|
ErrUserNotFound = errors.New("user not found")
|
|
ErrInvalidCredentials = errors.New("invalid credentials")
|
|
ErrUserAlreadyExists = errors.New("user already exists")
|
|
ErrInvalidPassword = errors.New("invalid password")
|
|
)
|
|
|
|
type UserService interface {
|
|
Register(ctx context.Context, req dto.RegisterRequest) (*dto.AuthResponse, error)
|
|
Login(ctx context.Context, req dto.LoginRequest) (*dto.AuthResponse, error)
|
|
GetUser(ctx context.Context, id uint) (*dto.UserResponse, error)
|
|
UpdateUser(ctx context.Context, id uint, req dto.UpdateUserRequest) (*dto.UserResponse, error)
|
|
DeleteUser(ctx context.Context, id uint) error
|
|
ListUsers(ctx context.Context, limit, offset int) ([]*dto.UserResponse, error)
|
|
GetUserProfile(ctx context.Context, id uint) (*dto.UserResponse, error)
|
|
}
|
|
|
|
type userService struct {
|
|
userRepo repository.UserRepository
|
|
jwtUtil *utils.JWTUtil
|
|
}
|
|
|
|
func NewUserService(userRepo repository.UserRepository, jwtUtil *utils.JWTUtil) UserService {
|
|
return &userService{
|
|
userRepo: userRepo,
|
|
jwtUtil: jwtUtil,
|
|
}
|
|
}
|
|
|
|
func (s *userService) Register(ctx context.Context, req dto.RegisterRequest) (*dto.AuthResponse, error) {
|
|
// Проверяем существование пользователя
|
|
existingUser, _ := s.userRepo.GetByEmail(ctx, req.Email)
|
|
if existingUser != nil {
|
|
return nil, ErrUserAlreadyExists
|
|
}
|
|
|
|
// Хешируем пароль
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Создаем пользователя
|
|
user := &models.User{
|
|
Email: req.Email,
|
|
PasswordHash: string(hashedPassword),
|
|
FullName: req.FullName,
|
|
FirstName: req.FirstName,
|
|
LastName: req.LastName,
|
|
Phone: req.Phone,
|
|
City: req.City,
|
|
IsActive: true,
|
|
IsVerified: false,
|
|
Role: "user",
|
|
}
|
|
|
|
if err := s.userRepo.Create(ctx, user); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Генерируем токен
|
|
token, err := s.jwtUtil.GenerateToken(user.ID, user.Email, user.Role)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
userResponse := dto.ToUserResponse(user)
|
|
return &dto.AuthResponse{
|
|
Token: token,
|
|
User: userResponse,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) Login(ctx context.Context, req dto.LoginRequest) (*dto.AuthResponse, error) {
|
|
// Находим пользователя по email
|
|
user, err := s.userRepo.GetByEmail(ctx, req.Email)
|
|
if err != nil {
|
|
return nil, ErrInvalidCredentials
|
|
}
|
|
|
|
// Проверяем пароль
|
|
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password)); err != nil {
|
|
return nil, ErrInvalidCredentials
|
|
}
|
|
|
|
// Проверяем активность пользователя
|
|
if !user.IsActive {
|
|
return nil, errors.New("account is deactivated")
|
|
}
|
|
|
|
// Генерируем токен
|
|
token, err := s.jwtUtil.GenerateToken(user.ID, user.Email, user.Role)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
userResponse := dto.ToUserResponse(user)
|
|
return &dto.AuthResponse{
|
|
Token: token,
|
|
User: userResponse,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) GetUser(ctx context.Context, id uint) (*dto.UserResponse, error) {
|
|
user, err := s.userRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
response := dto.ToUserResponse(user)
|
|
return &response, nil
|
|
}
|
|
|
|
func (s *userService) UpdateUser(ctx context.Context, id uint, req dto.UpdateUserRequest) (*dto.UserResponse, error) {
|
|
user, err := s.userRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
// Обновляем поля
|
|
if req.FullName != "" {
|
|
user.FullName = req.FullName
|
|
}
|
|
if req.FirstName != "" {
|
|
user.FirstName = req.FirstName
|
|
}
|
|
if req.LastName != "" {
|
|
user.LastName = req.LastName
|
|
}
|
|
if req.Phone != "" {
|
|
user.Phone = req.Phone
|
|
}
|
|
if req.City != "" {
|
|
user.City = req.City
|
|
}
|
|
if req.OrganizationForm != "" {
|
|
user.OrganizationForm = req.OrganizationForm
|
|
}
|
|
if req.OrganizationName != "" {
|
|
user.OrganizationName = req.OrganizationName
|
|
}
|
|
if req.OrganizationShort != "" {
|
|
user.OrganizationShort = req.OrganizationShort
|
|
}
|
|
if req.INN != "" {
|
|
user.INN = req.INN
|
|
}
|
|
if req.PersonalINN != "" {
|
|
user.PersonalINN = req.PersonalINN
|
|
}
|
|
|
|
if err := s.userRepo.Update(ctx, user); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response := dto.ToUserResponse(user)
|
|
return &response, nil
|
|
}
|
|
|
|
func (s *userService) DeleteUser(ctx context.Context, id uint) error {
|
|
return s.userRepo.Delete(ctx, id)
|
|
}
|
|
|
|
func (s *userService) ListUsers(ctx context.Context, limit, offset int) ([]*dto.UserResponse, error) {
|
|
users, err := s.userRepo.List(ctx, limit, offset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
responses := make([]*dto.UserResponse, len(users))
|
|
for i, user := range users {
|
|
response := dto.ToUserResponse(user)
|
|
responses[i] = &response
|
|
}
|
|
|
|
return responses, nil
|
|
}
|
|
|
|
func (s *userService) GetUserProfile(ctx context.Context, id uint) (*dto.UserResponse, error) {
|
|
return s.GetUser(ctx, id)
|
|
}
|