fix(09): WR-05 refuse relation link and unlink the panel does not declare

This commit is contained in:
Jakub Zych
2026-10-01 21:07:11 +02:00
parent b8084080cb
commit 9bca815b1b
3 changed files with 52 additions and 1 deletions

View File

@@ -8,6 +8,7 @@ import (
"io"
"net/http"
"reflect"
"slices"
"strconv"
"strings"
"time"
@@ -456,6 +457,20 @@ func (s *service) relationUnlink(w http.ResponseWriter, r *http.Request) {
func (s *service) relationMutation(w http.ResponseWriter, r *http.Request, link bool) {
s.protect(w, r, func(cc *CompiledController) {
// The panel's toolbarButtons are the capability: a relation declared
// without `link` (or `unlink`) refuses that route, whatever the
// controller permission. An unknown relation is the service's 404.
action := "unlink"
if link {
action = "link"
}
if cr, ok := cc.Relations[r.PathValue("name")]; ok && cr != nil && cr.Schema != nil && !slices.Contains(cr.Schema.View.ToolbarButtons, action) {
if principal, _ := bouncer.User(r.Context()); principal != nil {
s.logAuth(r, "denied", principal.ID)
}
WriteError(w, http.StatusForbidden, "forbidden", msgForbidden)
return
}
id, err := pathID(r)
if err != nil {
writeCRUDError(w, err)