refactor(handler): extract DoReadOne from ReadOneWeb

This commit is contained in:
kolaente 2026-04-20 10:48:56 +02:00
parent 19fa92febf
commit 12feb63e4c
2 changed files with 43 additions and 40 deletions

View File

@ -66,3 +66,43 @@ func DoCreate(_ context.Context, obj CObject, a web.Auth) error {
events.DispatchPending(s) events.DispatchPending(s)
return nil return nil
} }
// DoReadOne runs the permission check + model ReadOne + commit pipeline for a
// CObject. obj should have its identifying fields set before call. On success,
// obj is fully populated. maxPermission is exposed via the x-max-permission
// header in the Echo wrapper; Huma wrapper may ignore it.
func DoReadOne(_ context.Context, obj CObject, a web.Auth) (maxPermission int, err error) {
s := db.NewSession()
defer func() {
if cerr := s.Close(); cerr != nil {
log.Errorf("Could not close session: %s", cerr)
}
}()
canRead, maxPermission, err := obj.CanRead(s, a)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return 0, err
}
if !canRead {
_ = s.Rollback()
events.CleanupPending(s)
log.Warningf("Tried to read while not having the permissions for it (User: %v)", a)
return 0, echo.NewHTTPError(http.StatusForbidden, "You don't have the permission to see this")
}
if err := obj.ReadOne(s, a); err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return 0, err
}
if err := s.Commit(); err != nil {
events.CleanupPending(s)
return 0, err
}
events.DispatchPending(s)
return maxPermission, nil
}

View File

@ -22,8 +22,6 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/events"
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/auth" "code.vikunja.io/api/pkg/modules/auth"
@ -52,49 +50,14 @@ func (c *WebHandler) ReadOneWeb(ctx *echo.Context) error {
return echo.NewHTTPError(http.StatusInternalServerError, "Could not determine the current user.").Wrap(err) return echo.NewHTTPError(http.StatusInternalServerError, "Could not determine the current user.").Wrap(err)
} }
// Create the db session maxPermission, err := DoReadOne(ctx.Request().Context(), currentStruct, currentAuth)
s := db.NewSession()
defer func() {
err = s.Close()
if err != nil {
log.Errorf("Could not close session: %s", err)
}
}()
canRead, maxPermission, err := currentStruct.CanRead(s, currentAuth)
if err != nil { if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
if !canRead {
_ = s.Rollback()
events.CleanupPending(s)
log.Warningf("Tried to read while not having the permissions for it (User: %v)", currentAuth)
return echo.NewHTTPError(http.StatusForbidden, "You don't have the permission to see this")
}
// Get our object
err = currentStruct.ReadOne(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err return err
} }
// Set the headers // Set the headers
if canRead { ctx.Response().Header().Set("x-max-permission", strconv.FormatInt(int64(maxPermission), 10))
ctx.Response().Header().Set("x-max-permission", strconv.FormatInt(int64(maxPermission), 10)) ctx.Response().Header().Set("Access-Control-Expose-Headers", "x-max-permission")
ctx.Response().Header().Set("Access-Control-Expose-Headers", "x-max-permission")
}
err = s.Commit()
if err != nil {
events.CleanupPending(s)
return err
}
events.DispatchPending(s)
return ctx.JSON(http.StatusOK, currentStruct) return ctx.JSON(http.StatusOK, currentStruct)
} }