forked from mirrors/homebox
207 lines
5.5 KiB
Go
207 lines
5.5 KiB
Go
package v1
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/google/uuid"
|
|
"github.com/hay-kot/content/backend/internal/services"
|
|
"github.com/hay-kot/content/backend/internal/types"
|
|
"github.com/hay-kot/content/backend/pkgs/hasher"
|
|
"github.com/hay-kot/content/backend/pkgs/logger"
|
|
"github.com/hay-kot/content/backend/pkgs/server"
|
|
)
|
|
|
|
// HandleAdminUserGetAll godoc
|
|
// @Summary Gets all users from the database
|
|
// @Tags Admin: Users
|
|
// @Produce json
|
|
// @Success 200 {object} server.Result{item=[]types.UserOut}
|
|
// @Router /v1/admin/users [get]
|
|
// @Security Bearer
|
|
func (ctrl *V1Controller) HandleAdminUserGetAll() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
users, err := ctrl.svc.Admin.GetAll(r.Context())
|
|
|
|
if err != nil {
|
|
server.RespondError(w, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
server.Respond(w, http.StatusOK, server.Wrap(users))
|
|
}
|
|
}
|
|
|
|
// HandleAdminUserGet godoc
|
|
// @Summary Get a user from the database
|
|
// @Tags Admin: Users
|
|
// @Produce json
|
|
// @Param id path string true "User ID"
|
|
// @Success 200 {object} server.Result{item=types.UserOut}
|
|
// @Router /v1/admin/users/{id} [get]
|
|
// @Security Bearer
|
|
func (ctrl *V1Controller) HandleAdminUserGet() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
uid, err := uuid.Parse(chi.URLParam(r, "id"))
|
|
|
|
if err != nil {
|
|
ctrl.log.Debug(err.Error(), logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to convert id to valid UUID",
|
|
})
|
|
server.RespondError(w, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
user, err := ctrl.svc.Admin.GetByID(r.Context(), uid)
|
|
|
|
if err != nil {
|
|
ctrl.log.Error(err, nil)
|
|
server.RespondError(w, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
server.Respond(w, http.StatusOK, server.Wrap(user))
|
|
|
|
}
|
|
}
|
|
|
|
// HandleAdminUserCreate godoc
|
|
// @Summary Create a new user
|
|
// @Tags Admin: Users
|
|
// @Produce json
|
|
// @Param payload body types.UserCreate true "User Data"
|
|
// @Success 200 {object} server.Result{item=types.UserOut}
|
|
// @Router /v1/admin/users [POST]
|
|
// @Security Bearer
|
|
func (ctrl *V1Controller) HandleAdminUserCreate() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
createData := types.UserCreate{}
|
|
|
|
if err := server.Decode(r, &createData); err != nil {
|
|
ctrl.log.Error(err, logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to decode user create data",
|
|
})
|
|
server.RespondError(w, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
err := createData.Validate()
|
|
|
|
if err != nil {
|
|
server.RespondError(w, http.StatusUnprocessableEntity, err)
|
|
return
|
|
}
|
|
|
|
hashedPw, err := hasher.HashPassword(createData.Password)
|
|
|
|
if err != nil {
|
|
ctrl.log.Error(err, logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to hash password",
|
|
})
|
|
|
|
server.RespondError(w, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
createData.Password = hashedPw
|
|
userOut, err := ctrl.svc.Admin.Create(r.Context(), createData)
|
|
|
|
if err != nil {
|
|
ctrl.log.Error(err, logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to create user",
|
|
})
|
|
|
|
server.RespondError(w, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
server.Respond(w, http.StatusCreated, server.Wrap(userOut))
|
|
}
|
|
}
|
|
|
|
// HandleAdminUserUpdate godoc
|
|
// @Summary Update a User
|
|
// @Tags Admin: Users
|
|
// @Param id path string true "User ID"
|
|
// @Param payload body types.UserUpdate true "User Data"
|
|
// @Produce json
|
|
// @Success 200 {object} server.Result{item=types.UserOut}
|
|
// @Router /v1/admin/users/{id} [PUT]
|
|
// @Security Bearer
|
|
func (ctrl *V1Controller) HandleAdminUserUpdate() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
uid, err := uuid.Parse(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
ctrl.log.Debug(err.Error(), logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to convert id to valid UUID",
|
|
})
|
|
}
|
|
|
|
updateData := types.UserUpdate{}
|
|
|
|
if err := server.Decode(r, &updateData); err != nil {
|
|
ctrl.log.Error(err, logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to decode user update data",
|
|
})
|
|
server.RespondError(w, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
newData, err := ctrl.svc.Admin.UpdateProperties(r.Context(), uid, updateData)
|
|
|
|
if err != nil {
|
|
ctrl.log.Error(err, logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to update user",
|
|
})
|
|
server.RespondError(w, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
server.Respond(w, http.StatusOK, server.Wrap(newData))
|
|
}
|
|
}
|
|
|
|
// HandleAdminUserDelete godoc
|
|
// @Summary Delete a User
|
|
// @Tags Admin: Users
|
|
// @Param id path string true "User ID"
|
|
// @Produce json
|
|
// @Success 204
|
|
// @Router /v1/admin/users/{id} [DELETE]
|
|
// @Security Bearer
|
|
func (ctrl *V1Controller) HandleAdminUserDelete() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
uid, err := uuid.Parse(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
ctrl.log.Debug(err.Error(), logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to convert id to valid UUID",
|
|
})
|
|
}
|
|
|
|
actor := services.UseUserCtx(r.Context())
|
|
|
|
if actor.ID == uid {
|
|
server.RespondError(w, http.StatusBadRequest, errors.New("cannot delete yourself"))
|
|
return
|
|
}
|
|
|
|
err = ctrl.svc.Admin.Delete(r.Context(), uid)
|
|
|
|
if err != nil {
|
|
ctrl.log.Error(err, logger.Props{
|
|
"scope": "admin",
|
|
"details": "failed to delete user",
|
|
})
|
|
server.RespondError(w, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
}
|
|
}
|