You've already forked pocketbase
mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-11-24 07:04:51 +02:00
[#6201] expanded the hidden fields check and allow targetting hidden fields in the List API rule
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -48,6 +49,26 @@ type RecordFieldResolver struct {
|
||||
allowHiddenFields bool
|
||||
}
|
||||
|
||||
// AllowedFields returns a copy of the resolver's allowed fields.
|
||||
func (r *RecordFieldResolver) AllowedFields() []string {
|
||||
return slices.Clone(r.allowedFields)
|
||||
}
|
||||
|
||||
// SetAllowedFields replaces the resolver's allowed fields with the new ones.
|
||||
func (r *RecordFieldResolver) SetAllowedFields(newAllowedFields []string) {
|
||||
r.allowedFields = slices.Clone(newAllowedFields)
|
||||
}
|
||||
|
||||
// AllowHiddenFields returns whether the current resolver allows filtering hidden fields.
|
||||
func (r *RecordFieldResolver) AllowHiddenFields() bool {
|
||||
return r.allowHiddenFields
|
||||
}
|
||||
|
||||
// SetAllowHiddenFields enables or disables hidden fields filtering.
|
||||
func (r *RecordFieldResolver) SetAllowHiddenFields(allowHiddenFields bool) {
|
||||
r.allowHiddenFields = allowHiddenFields
|
||||
}
|
||||
|
||||
// NewRecordFieldResolver creates and initializes a new `RecordFieldResolver`.
|
||||
func NewRecordFieldResolver(
|
||||
app App,
|
||||
|
||||
@@ -415,6 +415,10 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
|
||||
|
||||
field := collection.Fields.GetByName(prop)
|
||||
|
||||
if field != nil && field.GetHidden() && !r.allowHiddenFields {
|
||||
return nil, fmt.Errorf("non-filterable field %q", prop)
|
||||
}
|
||||
|
||||
// json field -> treat the rest of the props as json path
|
||||
if field != nil && field.Type() == FieldTypeJSON {
|
||||
var jsonPath strings.Builder
|
||||
@@ -479,6 +483,10 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
|
||||
return nil, fmt.Errorf("invalid back relation field %q", parts[2])
|
||||
}
|
||||
|
||||
if backField.GetHidden() && !r.allowHiddenFields {
|
||||
return nil, fmt.Errorf("non-filterable back relation field %q", backField.GetName())
|
||||
}
|
||||
|
||||
backRelField, ok := backField.(*RelationField)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to initialize back relation field %q", backField.GetName())
|
||||
|
||||
@@ -3,6 +3,7 @@ package core_test
|
||||
import (
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -12,7 +13,75 @@ import (
|
||||
"github.com/pocketbase/pocketbase/tools/search"
|
||||
)
|
||||
|
||||
func TestRecordFieldResolverAllowedFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("demo1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r := core.NewRecordFieldResolver(app, collection, nil, false)
|
||||
|
||||
fields := r.AllowedFields()
|
||||
if len(fields) != 8 {
|
||||
t.Fatalf("Expected %d original allowed fields, got %d", 8, len(fields))
|
||||
}
|
||||
|
||||
// change the allowed fields
|
||||
newFields := []string{"a", "b", "c"}
|
||||
expected := slices.Clone(newFields)
|
||||
r.SetAllowedFields(newFields)
|
||||
|
||||
// change the new fields to ensure that the slice was cloned
|
||||
newFields[2] = "d"
|
||||
|
||||
fields = r.AllowedFields()
|
||||
if len(fields) != len(expected) {
|
||||
t.Fatalf("Expected %d changed allowed fields, got %d", len(expected), len(fields))
|
||||
}
|
||||
|
||||
for i, v := range expected {
|
||||
if fields[i] != v {
|
||||
t.Errorf("[%d] Expected field %q", i, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordFieldResolverAllowHiddenFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("demo1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r := core.NewRecordFieldResolver(app, collection, nil, false)
|
||||
|
||||
allowHiddenFields := r.AllowHiddenFields()
|
||||
if allowHiddenFields {
|
||||
t.Fatalf("Expected original allowHiddenFields %v, got %v", allowHiddenFields, !allowHiddenFields)
|
||||
}
|
||||
|
||||
// change the flag
|
||||
expected := !allowHiddenFields
|
||||
r.SetAllowHiddenFields(expected)
|
||||
|
||||
allowHiddenFields = r.AllowHiddenFields()
|
||||
if allowHiddenFields != expected {
|
||||
t.Fatalf("Expected changed allowHiddenFields %v, got %v", expected, allowHiddenFields)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordFieldResolverUpdateQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user