fix(share): add ownership checks to Delete and Update (#5189)
* test(share): add failing tests for Delete ownership checks * fix(share): add ownership check to Delete * test(share): add failing tests for Update ownership checks * fix(share): add ownership check to Update * refactor(share): extract checkOwnership helper with lightweight query - Deduplicate ownership check from Delete and Update into a single helper - Use a minimal single-column SELECT instead of Get (avoids loadMedia overhead) - Use positive bypass form (IsAdmin || invalidUserId) matching codebase convention * fix(share): convert model.ErrNotFound to rest.ErrNotFound in checkOwnership Ensure consistent 404 responses when a nonexistent share ID is passed to Delete or Update, by handling the conversion in checkOwnership rather than relying on the subsequent write operation.
This commit is contained in:
@@ -30,7 +30,33 @@ func NewShareRepository(ctx context.Context, db dbx.Builder) model.ShareReposito
|
||||
return r
|
||||
}
|
||||
|
||||
// TODO: Ownership checks should be moved to the service layer (core/share.go)
|
||||
func (r *shareRepository) checkOwnership(id string) error {
|
||||
usr := loggedUser(r.ctx)
|
||||
if usr.IsAdmin || usr.ID == invalidUserId {
|
||||
return nil
|
||||
}
|
||||
sel := r.newSelect().Columns("user_id").Where(Eq{"id": id})
|
||||
var share struct {
|
||||
UserID string `db:"user_id"`
|
||||
}
|
||||
err := r.queryOne(sel, &share)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return rest.ErrNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
if share.UserID != usr.ID {
|
||||
return rest.ErrPermissionDenied
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *shareRepository) Delete(id string) error {
|
||||
if err := r.checkOwnership(id); err != nil {
|
||||
return err
|
||||
}
|
||||
err := r.delete(Eq{"id": id})
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return rest.ErrNotFound
|
||||
@@ -140,7 +166,9 @@ func sortByIdPosition(mfs model.MediaFiles, ids []string) model.MediaFiles {
|
||||
|
||||
func (r *shareRepository) Update(id string, entity any, cols ...string) error {
|
||||
s := entity.(*model.Share)
|
||||
// TODO Validate record
|
||||
if err := r.checkOwnership(id); err != nil {
|
||||
return err
|
||||
}
|
||||
s.ID = id
|
||||
s.UpdatedAt = time.Now()
|
||||
cols = append(cols, "updated_at")
|
||||
|
||||
Reference in New Issue
Block a user