From 11b739c555c3439cce380a3b9b0a2ad91f502846 Mon Sep 17 00:00:00 2001 From: Casey Waldren Date: Wed, 4 Dec 2024 12:27:22 -0800 Subject: [PATCH] make nested context kind inaccessible --- ldai/client.go | 11 +++++++---- ldai/client_test.go | 23 +++++++++++++++++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/ldai/client.go b/ldai/client.go index 194b0d19..b0f434c9 100644 --- a/ldai/client.go +++ b/ldai/client.go @@ -116,7 +116,7 @@ func (c *Client) Config( func getAllAttributes(context ldcontext.Context) map[string]interface{} { if !context.Multiple() { - return addSingleKindContextAttributes(context) + return addContextAttributes(context, false) } attributes := map[string]interface{}{ @@ -125,19 +125,22 @@ func getAllAttributes(context ldcontext.Context) map[string]interface{} { } for _, ctx := range context.GetAllIndividualContexts(nil) { - attributes[string(ctx.Kind())] = addSingleKindContextAttributes(ctx) + attributes[string(ctx.Kind())] = addContextAttributes(ctx, true) } return attributes } -func addSingleKindContextAttributes(context ldcontext.Context) map[string]interface{} { +func addContextAttributes(context ldcontext.Context, omitKind bool) map[string]interface{} { attributes := map[string]interface{}{ - "kind": context.Kind(), "key": context.Key(), "anonymous": context.Anonymous(), } + if !omitKind { + attributes["kind"] = context.Kind() + } + for _, attr := range context.GetOptionalAttributeNames(nil) { attributes[attr] = context.GetValue(attr).AsArbitraryValue() } diff --git a/ldai/client_test.go b/ldai/client_test.go index fc578b15..a254c521 100644 --- a/ldai/client_test.go +++ b/ldai/client_test.go @@ -375,8 +375,27 @@ func TestInterpolation(t *testing.T) { context := ldcontext.NewMulti(user, cat) - result, err := eval(t, "kind={{ ldctx.kind }}", context, nil) + result, err := eval(t, "kind=<{{ ldctx.kind }}>", context, nil) require.NoError(t, err) - assert.Equal(t, "kind=multi", result) + assert.Equal(t, "kind=", result) + }) + + t.Run("interpolation with multi kind context does not have child kinds", func(t *testing.T) { + + // The idea here is that in a multi-kind context, we can access ldctx.kind (== "multi"), but you can't + // access the kind field of the individual nested contexts since this doesn't match the actual data model. + // That is, you can't access ldctx.user.kind or ldctx.cat.kind, only ldctx.kind. + + user := ldcontext.NewBuilder("123"). + SetValue("cat_ownership", ldvalue.ObjectBuild().Set("count", ldvalue.Int(12)).Build()).Build() + + cat := ldcontext.NewBuilder("456").Kind("cat"). + SetValue("health", ldvalue.ObjectBuild().Set("hunger", ldvalue.String("off the charts")).Build()).Build() + + context := ldcontext.NewMulti(user, cat) + + result, err := eval(t, "user_kind=<{{ ldctx.user.kind}}>,cat_kind=<{{ ldctx.cat.kind }}>", context, nil) + require.NoError(t, err) + assert.Equal(t, "user_kind=<>,cat_kind=<>", result) }) }