setup.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package handlers
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net/http"
  6. "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/repository"
  7. "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/services"
  8. "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/validator"
  9. )
  10. type SetupHandler struct {
  11. userRepo *repository.UserRepo
  12. authSvc *services.AuthService
  13. isProd bool
  14. }
  15. func NewSetupHandler(userRepo *repository.UserRepo, authSvc *services.AuthService, appEnv string) *SetupHandler {
  16. return &SetupHandler{
  17. userRepo: userRepo,
  18. authSvc: authSvc,
  19. isProd: appEnv == "production",
  20. }
  21. }
  22. func (h *SetupHandler) Status(w http.ResponseWriter, r *http.Request) {
  23. hasSuperadmin, err := h.userRepo.HasSuperadmin(r.Context())
  24. if err != nil {
  25. writeError(w, http.StatusInternalServerError, "failed to check setup status", err)
  26. return
  27. }
  28. writeJSON(w, http.StatusOK, map[string]bool{"has_superadmin": hasSuperadmin})
  29. }
  30. type setupRequest struct {
  31. Email string `json:"email" validate:"required,email,max=255"`
  32. Password string `json:"password" validate:"required,min=8,max=72"`
  33. Name string `json:"name" validate:"omitempty,max=255"`
  34. }
  35. func (h *SetupHandler) Setup(w http.ResponseWriter, r *http.Request) {
  36. hasSuperadmin, err := h.userRepo.HasSuperadmin(r.Context())
  37. if err != nil {
  38. writeError(w, http.StatusInternalServerError, "failed to check setup status", err)
  39. return
  40. }
  41. if hasSuperadmin {
  42. writeError(w, http.StatusConflict, "superadmin already exists", nil)
  43. return
  44. }
  45. r.Body = http.MaxBytesReader(w, r.Body, maxRequestBodySize)
  46. var req setupRequest
  47. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  48. writeError(w, http.StatusBadRequest, "invalid request body", err)
  49. return
  50. }
  51. if err := validator.Validate(req); err != nil {
  52. writeValidationError(w, err)
  53. return
  54. }
  55. result, refreshToken, err := h.authSvc.Register(r.Context(), services.RegisterInput{
  56. Email: req.Email,
  57. Password: req.Password,
  58. Role: "superadmin",
  59. Name: req.Name,
  60. })
  61. if err != nil {
  62. if errors.Is(err, services.ErrEmailExists) {
  63. writeError(w, http.StatusConflict, "email already exists", err)
  64. return
  65. }
  66. writeError(w, http.StatusInternalServerError, "setup failed", err)
  67. return
  68. }
  69. setRefreshTokenCookie(w, refreshToken, h.isProd)
  70. writeJSON(w, http.StatusCreated, result)
  71. }