user_change_password.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package admin
  2. import (
  3. "context"
  4. "errors"
  5. "git.dmitriygnatenko.ru/dima/go-common/logger"
  6. validation "github.com/go-ozzo/ozzo-validation/v4"
  7. "github.com/gofiber/fiber/v2"
  8. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/dto"
  9. customErrors "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/helper/errors"
  10. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/mapper"
  11. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/model"
  12. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/service/auth"
  13. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/service/i18n"
  14. )
  15. type changePasswordPage struct {
  16. authService AuthService
  17. userRepository UserRepository
  18. }
  19. func NewChangePasswordPageHandler(
  20. authService AuthService,
  21. userRepository UserRepository,
  22. ) fiber.Handler {
  23. h := changePasswordPage{
  24. authService: authService,
  25. userRepository: userRepository,
  26. }
  27. return h.handler()
  28. }
  29. func (h changePasswordPage) handler() fiber.Handler {
  30. return func(fctx *fiber.Ctx) error {
  31. ctx := fctx.Context()
  32. lang := i18n.LanguageFromContext(fctx)
  33. validationErrors := make(map[string]string)
  34. var form dto.ChangePasswordForm
  35. if fctx.Method() == fiber.MethodPost {
  36. if err := fctx.BodyParser(&form); err != nil {
  37. logger.Info(ctx, customErrors.Wrap(err, "change user password page: can't parse body").Error())
  38. return err
  39. }
  40. claims := h.authService.GetClaims(fctx)
  41. user, err := h.userRepository.Get(ctx, claims[auth.ClaimNameKey].(string))
  42. if err != nil {
  43. logger.Error(ctx, customErrors.Wrap(err, "change user password page: can't get user").Error())
  44. return err
  45. }
  46. if err := h.validateChangePasswordForm(ctx, form, *user); err != nil {
  47. logger.Info(ctx, customErrors.Wrap(err, "change user password page: validation").Error())
  48. validationErrors = mapper.ToErrorsMap(err)
  49. }
  50. if len(validationErrors) == 0 {
  51. newPassword, err := h.authService.GeneratePasswordHash(form.NewPassword)
  52. if err != nil {
  53. logger.Error(
  54. ctx,
  55. customErrors.Wrap(err, "change user password page: can't generate new password").Error(),
  56. )
  57. return err
  58. }
  59. if err = h.userRepository.UpdatePassword(ctx, user.ID, newPassword); err != nil {
  60. logger.Error(
  61. ctx,
  62. customErrors.Wrap(err, "change user password page: can't update user").Error(),
  63. )
  64. return err
  65. }
  66. return fctx.Redirect("/admin")
  67. }
  68. }
  69. return fctx.Render("admin/user_change_password", fiber.Map{
  70. "lang": lang,
  71. "section": "change_password",
  72. "form": form,
  73. "errors": validationErrors,
  74. }, "admin/_layout")
  75. }
  76. }
  77. func (h changePasswordPage) validateChangePasswordForm(
  78. ctx context.Context,
  79. req dto.ChangePasswordForm,
  80. user model.User,
  81. ) error {
  82. lang := i18n.DefaultLanguage()
  83. requiredMsg := i18n.T(lang, "admin_err_required")
  84. lengthMsg := i18n.T(lang, "admin_err_length_255")
  85. return validation.ValidateStructWithContext(
  86. ctx,
  87. &req,
  88. validation.Field(
  89. &req.OldPassword,
  90. validation.Required.Error(requiredMsg),
  91. validation.Length(1, 255).Error(lengthMsg),
  92. validation.By(h.validateOldPassword(user)),
  93. ),
  94. validation.Field(
  95. &req.NewPassword,
  96. validation.Required.Error(requiredMsg),
  97. validation.Length(1, 255).Error(lengthMsg),
  98. ),
  99. )
  100. }
  101. func (h changePasswordPage) validateOldPassword(user model.User) func(value interface{}) error {
  102. return func(value interface{}) error {
  103. oldPassword, _ := value.(string)
  104. if !h.authService.IsCorrectPassword(oldPassword, user.Password) {
  105. lang := i18n.DefaultLanguage()
  106. return errors.New(i18n.T(lang, "admin_err_incorrect_password"))
  107. }
  108. return nil
  109. }
  110. }