diff --git a/internal/admin/routes.go b/internal/admin/routes.go index 106b853..a39e177 100644 --- a/internal/admin/routes.go +++ b/internal/admin/routes.go @@ -33,6 +33,7 @@ func (h *AdminHandler) RegisterRoutes(router chi.Router) { r.Patch("/api-services/toggle/{id}", h.ToggleApiService) r.Get("/users", h.GetUsers) + r.Post("/users", h.CreateUser) r.Get("/users/{id}", h.GetUser) }) } diff --git a/internal/admin/users.go b/internal/admin/users.go index 4bfe297..234ca36 100644 --- a/internal/admin/users.go +++ b/internal/admin/users.go @@ -7,6 +7,7 @@ import ( "gitea.local/admin/hspguard/internal/repository" "gitea.local/admin/hspguard/internal/types" + "gitea.local/admin/hspguard/internal/util" "gitea.local/admin/hspguard/internal/web" "github.com/go-chi/chi/v5" "github.com/google/uuid" @@ -79,3 +80,75 @@ func (h *AdminHandler) GetUser(w http.ResponseWriter, r *http.Request) { web.Error(w, "failed to encode user dto", http.StatusInternalServerError) } } + +type CreateUserRequest struct { + Email string `json:"email"` + FullName string `json:"full_name"` + Password string `json:"password"` + IsAdmin bool `json:"is_admin"` +} + +func (h *AdminHandler) CreateUser(w http.ResponseWriter, r *http.Request) { + var req CreateUserRequest + + decoder := json.NewDecoder(r.Body) + if err := decoder.Decode(&req); err != nil { + web.Error(w, "invalid request body", http.StatusBadRequest) + return + } + + if req.Email == "" { + web.Error(w, "email is required", http.StatusBadRequest) + return + } + + if req.FullName == "" { + web.Error(w, "full name is required", http.StatusBadRequest) + return + } + + if req.Password == "" { + web.Error(w, "password is required", http.StatusBadRequest) + return + } + + _, err := h.repo.FindUserEmail(r.Context(), req.Email) + if err == nil { + web.Error(w, "user with provided email already exists", http.StatusBadRequest) + return + } + + hash, err := util.HashPassword(req.Password) + if err != nil { + log.Println("ERR: Failed to hash password for new user:", err) + web.Error(w, "failed to create user account", http.StatusInternalServerError) + return + } + + params := repository.InsertUserParams{ + Email: req.Email, + FullName: req.FullName, + PasswordHash: hash, + IsAdmin: false, + } + + log.Println("INFO: params for user creation:", params) + + userId, err := h.repo.InsertUser(r.Context(), params) + if err != nil { + log.Println("ERR: Failed to insert user into database:", err) + web.Error(w, "failed to create user", http.StatusInternalServerError) + return + } + + type Response struct { + ID string `json:"id"` + } + + encoder := json.NewEncoder(w) + if err := encoder.Encode(Response{ + ID: userId.String(), + }); err != nil { + web.Error(w, "failed to encode response", http.StatusInternalServerError) + } +}