package policy import ( "context" "testing" gwpb "github.com/moby/buildkit/frontend/gateway/pb" solverpb "github.com/moby/buildkit/solver/pb" moby_buildkit_v1_sourcepolicy "github.com/moby/buildkit/sourcepolicy/pb" "github.com/moby/buildkit/sourcepolicy/policysession" "github.com/stretchr/testify/require" ) func TestMultiPolicyCallbackNoCallbacks(t *testing.T) { cb := MultiPolicyCallback() decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, meta) require.NotNil(t, decision) require.Equal(t, moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW, decision.Action) } func TestMultiPolicyCallbackAllowOnly(t *testing.T) { cb := MultiPolicyCallback(func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW}, nil, nil }) decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, meta) require.NotNil(t, decision) require.Equal(t, moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW, decision.Action) } func TestMultiPolicyCallbackDenyWins(t *testing.T) { denyMsgA := &policysession.DenyMessage{Message: "nope-a"} denyMsgB := &policysession.DenyMessage{Message: "nope-b"} cb := MultiPolicyCallback( func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW}, nil, nil }, func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{ Action: moby_buildkit_v1_sourcepolicy.PolicyAction_DENY, DenyMessages: []*policysession.DenyMessage{denyMsgA, denyMsgB}, }, nil, nil }, ) decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, meta) require.NotNil(t, decision) require.Equal(t, moby_buildkit_v1_sourcepolicy.PolicyAction_DENY, decision.Action) require.Equal(t, []*policysession.DenyMessage{denyMsgA, denyMsgB}, decision.DenyMessages) } func TestMultiPolicyCallbackDenyShortCircuits(t *testing.T) { called := false cb := MultiPolicyCallback( func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_DENY}, nil, nil }, func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { called = true return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW}, nil, nil }, ) decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, meta) require.NotNil(t, decision) require.Equal(t, moby_buildkit_v1_sourcepolicy.PolicyAction_DENY, decision.Action) require.False(t, called) } func TestMultiPolicyCallbackUpdateReturned(t *testing.T) { update := &solverpb.SourceOp{} cb := MultiPolicyCallback( func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW}, nil, nil }, func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{ Action: moby_buildkit_v1_sourcepolicy.PolicyAction_CONVERT, Update: update, }, nil, nil }, ) decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, meta) require.NotNil(t, decision) require.Equal(t, moby_buildkit_v1_sourcepolicy.PolicyAction_CONVERT, decision.Action) require.Equal(t, update, decision.Update) } func TestMultiPolicyCallbackMetaRequest(t *testing.T) { metaReq := &gwpb.ResolveSourceMetaRequest{} cb := MultiPolicyCallback( func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return nil, metaReq, nil }, func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_DENY}, nil, nil }, ) decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, decision) require.Equal(t, metaReq, meta) } func TestMultiPolicyCallbackNilCallbackIgnored(t *testing.T) { cb := MultiPolicyCallback(nil, func(context.Context, *policysession.CheckPolicyRequest) (*policysession.DecisionResponse, *gwpb.ResolveSourceMetaRequest, error) { return &policysession.DecisionResponse{Action: moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW}, nil, nil }) decision, meta, err := cb(context.Background(), &policysession.CheckPolicyRequest{}) require.NoError(t, err) require.Nil(t, meta) require.NotNil(t, decision) require.Equal(t, moby_buildkit_v1_sourcepolicy.PolicyAction_ALLOW, decision.Action) }