diff --git a/tests/integration/acp/README.md b/tests/integration/acp/README.md index 501f305e41..cc0ab86707 100644 --- a/tests/integration/acp/README.md +++ b/tests/integration/acp/README.md @@ -1,6 +1,17 @@ -## More Information on what each directory tests. +## More Information on ACP test directories. -1) `./add_policy` +1) `./defradb/tests/integration/acp/add_policy` - This directory tests ONLY the `Adding of a Policy` through DefraDB. + - Does NOT assert the schema. - Does NOT test DPI validation. + +2) `./defradb/tests/integration/acp/schema/add_dpi` + - This directory tests the loading/adding of a schema that has `@policy(id, resource)` + specified (i.e. permissioned schema). The tests ensure that only a schema linking to + a valid DPI policy is accepted. Naturally these tests will also be `Adding a Policy` + through DefraDB like in (1) before actually adding the schema. If a schema has a + policy specified that doesn't exist (or wasn't added yet), that schema WILL/MUST + be rejected in these tests. + - The tests assert the schema after to ensure rejection/acceptance. + - Tests DPI validation. diff --git a/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go b/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go new file mode 100644 index 0000000000..7e7d45e1d8 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go @@ -0,0 +1,214 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_BasicYAML_SchemaAccepted(t *testing.T) { + policyIDOfValidDPI := "dfe202ffb4f0fe9b46157c313213a3839e08a6f0a7c3aba55e4724cb49ffde8a" + + test := testUtils.TestCase{ + Description: "Test acp, specify basic policy that was added in YAML format, accept schema", + + Actions: []any{ + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a basic policy that satisfies minimum DPI requirements + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + write: + expr: owner + + relations: + owner: + types: + - actor + + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_BasicJSON_SchemaAccepted(t *testing.T) { + policyIDOfValidDPI := "dfe202ffb4f0fe9b46157c313213a3839e08a6f0a7c3aba55e4724cb49ffde8a" + + test := testUtils.TestCase{ + Description: "Test acp, specify basic policy that was added in JSON format, accept schema", + + Actions: []any{ + testUtils.AddPolicy{ + IsYAML: false, + + Creator: actor1Signature, + + Policy: ` + { + "description": "a basic policy that satisfies minimum DPI requirements", + "resources": { + "users": { + "permissions": { + "read": { + "expr": "owner" + }, + "write": { + "expr": "owner" + } + }, + "relations": { + "owner": { + "types": [ + "actor" + ] + } + } + } + }, + "actor": { + "name": "actor" + } + } + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go new file mode 100644 index 0000000000..9e21670a54 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go @@ -0,0 +1,316 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_WithExtraPermsHavingRequiredRelation_AcceptSchema(t *testing.T) { + policyIDOfValidDPI := "08a29e8086c21c6be73300fba023d7ec5f17a956d4e5bfe5aa46aa15a20cb836" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with extra permissions having required relation, schema accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner & reader + magic: + expr: owner - reader + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_WithExtraPermsHavingRequiredRelationInTheEnd_AcceptSchema(t *testing.T) { + policyIDOfValidDPI := "1b7f8e09dfea880cbdaaa33419ceceb3e23ce3292e1e1b8881888b8fec64ee91" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with extra permissions having required relation in the end, schema accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + magic: + expr: reader - owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_WithExtraPermsHavingNoRequiredRelation_AcceptSchema(t *testing.T) { + policyIDOfValidDPI := "7b6266a93bfb6920bf57884f55c3823a5a5147c4ce445a9fc703b7c1e59b2d12" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with extra permissions having no required relation, schema accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + magic: + expr: reader + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go new file mode 100644 index 0000000000..c9400e7223 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go @@ -0,0 +1,121 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_WithManagedRelation_AcceptSchemas(t *testing.T) { + policyIDOfValidDPI := "53980e762616fcffbe76307995895e862f87ef3f21d509325d1dc772a770b001" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, where one resource is specified on different schemas, schemas accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + admin: + manages: + - reader + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go new file mode 100644 index 0000000000..75289977ef --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go @@ -0,0 +1,131 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_PartialValidDPIButUseOnlyValidDPIResource_AcceptSchema(t *testing.T) { + policyIDOfPartiallyValidDPI := "d5d411825b2d8fa5a550f1e34153b88b375ed9c9af19ce6d2ba1769e237a45d0" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, has both valid & invalid resources, but use only valid resource, schema accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Partially Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + usersValid: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + + usersInvalid: + permissions: + read: + expr: reader - owner + write: + expr: reader + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfPartiallyValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "usersValid" + ) { + name: String + age: Int + } + `, + policyIDOfPartiallyValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go b/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go new file mode 100644 index 0000000000..b4b7046b98 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go @@ -0,0 +1,184 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_AddDuplicateDPIsByOtherCreatorsUseBoth_AcceptSchema(t *testing.T) { + const sameResourceNameOnBothDPI string = "users" + const validDPIUsedByBoth string = ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + ` + + const policyIDOfFirstCreatorsDPI string = "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + const policyIDOfSecondCreatorsDPI string = "d33aa07a28ea19ed07a5256eb7e7f5600b0e0af13254889a7fce60202c4f6c7e" + + test := testUtils.TestCase{ + Description: "Test acp, add duplicate DPIs by different actors, accept both schemas", + + Actions: []any{ + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: validDPIUsedByBoth, + + ExpectedPolicyID: policyIDOfFirstCreatorsDPI, + }, + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor2Signature, + + Policy: validDPIUsedByBoth, + + ExpectedPolicyID: policyIDOfSecondCreatorsDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type OldUsers @policy( + id: "%s", + resource: "%s" + ) { + name: String + age: Int + } + `, + policyIDOfFirstCreatorsDPI, + sameResourceNameOnBothDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "OldUsers") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "OldUsers", // NOTE: "OldUsers" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type NewUsers @policy( + id: "%s", + resource: "%s" + ) { + name: String + age: Int + } + `, + policyIDOfSecondCreatorsDPI, + sameResourceNameOnBothDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "NewUsers") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "NewUsers", // NOTE: "NewUsers" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go new file mode 100644 index 0000000000..6d2cd23d20 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go @@ -0,0 +1,281 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_WithMultipleResources_AcceptSchema(t *testing.T) { + policyIDOfValidDPI := "f3e521de628fa607ba11af0e9b53e2fb74ca0e6ea33622003d1f43dbae0ce41d" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with multiple resources, schema accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + + books: + permissions: + read: + expr: owner + write: + expr: owner + + relations: + owner: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_WithMultipleResourcesBothBeingUsed_AcceptSchema(t *testing.T) { + policyIDOfValidDPI := "f3e521de628fa607ba11af0e9b53e2fb74ca0e6ea33622003d1f43dbae0ce41d" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with multiple resources both being used, schemas accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + + books: + permissions: + read: + expr: owner + write: + expr: owner + + relations: + owner: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Users", // NOTE: "Users" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Books @policy( + id: "%s", + resource: "books" + ) { + name: String + } + `, + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Books") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "Books", // NOTE: "Books" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go b/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go new file mode 100644 index 0000000000..a2d0fb2f53 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go @@ -0,0 +1,172 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" +) + +func TestACP_AddDPISchema_UseSameResourceOnDifferentSchemas_AcceptSchemas(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + sharedSameResourceName := "users" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, where one resource is specified on different schemas, schemas accepted", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type OldUsers @policy( + id: "%s", + resource: "%s" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + sharedSameResourceName, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "OldUsers") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "OldUsers", // NOTE: "OldUsers" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type NewUsers @policy( + id: "%s", + resource: "%s" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + sharedSameResourceName, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "NewUsers") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": map[string]any{ + "name": "NewUsers", // NOTE: "NewUsers" MUST exist + "fields": schemaUtils.DefaultFields.Append( + schemaUtils.Field{ + "name": "name", + "type": map[string]any{ + "kind": "SCALAR", + "name": "String", + }, + }, + ).Append( + schemaUtils.Field{ + "name": "age", + "type": map[string]any{ + "kind": "SCALAR", + "name": "Int", + }, + }, + ).Tidy(), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/fixture.go b/tests/integration/acp/schema/add_dpi/fixture.go new file mode 100644 index 0000000000..0202cddeaa --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/fixture.go @@ -0,0 +1,18 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" +) + +var actor1Signature = acpUtils.Actor1Signature +var actor2Signature = acpUtils.Actor2Signature diff --git a/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go new file mode 100644 index 0000000000..9c95aef5fc --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go @@ -0,0 +1,165 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_NoArgWasSpecifiedOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but no arg was specified on schema, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy { + name: String + age: Int + } + `, + ExpectedError: "missing policy arguments, must have both id and resource", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_SpecifiedArgsAreEmptyOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, specified args on schema are empty, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy(resource: "", id: "") { + name: String + age: Int + } + `, + ExpectedError: "missing policy arguments, must have both id and resource", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go new file mode 100644 index 0000000000..d76cf26c0a --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go @@ -0,0 +1,169 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_InvalidPolicyIDArgTypeWasSpecifiedOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but invalid policyID arg type was specified on schema, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy(id: 123 , resource: "users") { + name: String + age: Int + } + `, + ExpectedError: "policy directive with invalid id property", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_InvalidResourceArgTypeWasSpecifiedOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but invalid resource arg type was specified on schema, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy(id: "%s" , resource: 123) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + + ExpectedError: "policy directive with invalid resource property", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go new file mode 100644 index 0000000000..ccf97437b9 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go @@ -0,0 +1,419 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_OwnerMissingRequiredReadPermissionOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "782ffee730033ff01a3bdb05a3aa130f08c0914887378b0dfee314be6c3a8dd0" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with owner missing required read permission, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + write: + expr: owner + read: + expr: r + + relations: + owner: + types: + - actor + r: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=read is missing required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_OwnerMissingRequiredReadPermissionLabelOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "62d2d65d0304cb9a16bb4f07d1f48c7142911f73bc1db6ee54cdd2c6c7949c73" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with owner missing required read permission label, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: fmt.Sprintf( + "resource=users is missing required permission=read on policy=%s", + policyIDOfInvalidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnReadPermissionExprOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "f9fe33e8b2ee18a65d16bdc8017fe829ec13b0797330422639cd9dafac7b00f8" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, owner specified incorrectly on read permission expression, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: reader + owner + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=read must start with required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnReadPermissionNoSpaceExprOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "08cc6bed6b9695dd47b6bf1e934ff91975db598631a55c26db9ead1393a77588" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, owner specified incorrectly on read permission expression (no space), reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: reader+owner + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=read must start with required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_MaliciousOwnerSpecifiedOnReadPermissionExprOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "fff5c6fc25fbc2a9e5a7251c19b1cb950889281d656e5aeb642ce7c16f181c9b" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, malicious owner specified on read permission expression, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: ownerBad + write: + expr: owner + + relations: + owner: + types: + - actor + ownerBad: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=read has invalid char after relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go new file mode 100644 index 0000000000..a354be298f --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go @@ -0,0 +1,419 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_OwnerMissingRequiredWritePermissionOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "4256d2b54767cafd0e0a2b39a6faebf44bc99a7fc74ff5b51894f7accf2ef638" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with owner missing required write permission, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + write: + expr: w + read: + expr: owner + + relations: + owner: + types: + - actor + w: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=write is missing required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_OwnerMissingRequiredWritePermissionLabelOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "e8be944571cd6b52faa1e8b75fa339a9f60065b65d78ed126d037722e2512593" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with owner missing required write permission label, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: fmt.Sprintf( + "resource=users is missing required permission=write on policy=%s", + policyIDOfInvalidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnWritePermissionExprOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "34ff30cb9e80993e2b11f86f85c6daa7cd9bf25724e4d5ff0704518d7970d074" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, owner specified incorrectly on write permission expression, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + write: + expr: writer + owner + + relations: + owner: + types: + - actor + writer: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=write must start with required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnWritePermissionNoSpaceExprOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "2e9fc5805b0442e856e9893fea0f4759d333e442856a230ed741b88670e6426c" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, owner specified incorrectly on write permission expression (no space), reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + write: + expr: writer+owner + + relations: + owner: + types: + - actor + writer: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=write must start with required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_MaliciousOwnerSpecifiedOnWritePermissionExprOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "3bcd650ac1e69d5efe6c930d05420231a0a69e6018d0f1015e0ecef9869d8dd5" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, malicious owner specified on write permission expression, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: a policy + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + write: + expr: ownerBad + + relations: + owner: + types: + - actor + ownerBad: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: "expr of required permission=write has invalid char after relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go new file mode 100644 index 0000000000..42f7515954 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go @@ -0,0 +1,154 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_WhereNoPolicyWasAdded_SchemaRejected(t *testing.T) { + nonExistingPolicyID := "dfe202ffb4f0fe9b46157c313213a3839e08a6f0a7c3aba55e4724cb49ffde8a" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but no policy was added, reject schema", + + Actions: []any{ + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + nonExistingPolicyID, + ), + + ExpectedError: fmt.Sprintf( + "policyID=%s specified does not exist on acp module", + nonExistingPolicyID, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_WhereAPolicyWasAddedButLinkedPolicyWasNotAdded_SchemaRejected(t *testing.T) { + policyAdded := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + incorrectPolicyID := "dfe202ffb4f0fe9b46157c313213a3839e08a6f0a7c3aba55e4724cb49ffde8a" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but specify incorrect policy ID, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyAdded, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + incorrectPolicyID, + ), + + ExpectedError: fmt.Sprintf( + "policyID=%s specified does not exist on acp module", + incorrectPolicyID, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go new file mode 100644 index 0000000000..6f0c86b67b --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go @@ -0,0 +1,165 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_NoPolicyIDWasSpecifiedOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but no policyID was specified on schema, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy(resource: "users") { + name: String + age: Int + } + `, + ExpectedError: "policyID must not be empty", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_SpecifiedPolicyIDArgIsEmptyOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, specified policyID arg on schema is empty, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy(resource: "users", id: "") { + name: String + age: Int + } + `, + ExpectedError: "policyID must not be empty", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go new file mode 100644 index 0000000000..e8b72629d6 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go @@ -0,0 +1,95 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_MissingRequiredReadPermissionOnDPI_SchemaRejected(t *testing.T) { + policyIDOfInvalidDPI := "7eb7448daa631cfe33da3a149f5eea716026f54bf23ce1315c594259382c5c57" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, with missing required read permission, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A policy + + actor: + name: actor + + resources: + users: + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfInvalidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "users" + ) { + name: String + age: Int + } + `, + policyIDOfInvalidDPI, + ), + + ExpectedError: fmt.Sprintf( + "resource=users is missing required permission=read on policy=%s", + policyIDOfInvalidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go new file mode 100644 index 0000000000..591099175b --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go @@ -0,0 +1,170 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_NoResourceWasSpecifiedOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but no resource was specified on schema, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy(id: "%s") { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + ExpectedError: "resource name must not be empty", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_AddDPISchema_SpecifiedResourceArgIsEmptyOnSchema_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, specified resource arg on schema is empty, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy(id: "%s", resource: "") { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + ExpectedError: "resource name must not be empty", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go new file mode 100644 index 0000000000..434e151133 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go @@ -0,0 +1,101 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_SpecifiedResourceDoesNotExistOnDPI_SchemaRejected(t *testing.T) { + policyIDOfValidDPI := "4f13c5084c3d0e1e5c5db702fceef84c3b6ab948949ca8e27fcaad3fb8bc39f4" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, but specified resource does not exist on DPI, reject schema", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "doesntExist" + ) { + name: String + age: Int + } + `, + policyIDOfValidDPI, + ), + + ExpectedError: fmt.Sprintf( + "resource=doesntExist does not exist on the specified policy=%s", + policyIDOfValidDPI, + ), + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go new file mode 100644 index 0000000000..0879fea8e2 --- /dev/null +++ b/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go @@ -0,0 +1,112 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp_schema_add_dpi + +import ( + "fmt" + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestACP_AddDPISchema_PartialValidDPIButUseInValidDPIResource_RejectSchema(t *testing.T) { + policyIDOfPartiallyValidDPI := "d5d411825b2d8fa5a550f1e34153b88b375ed9c9af19ce6d2ba1769e237a45d0" + + test := testUtils.TestCase{ + Description: "Test acp, add dpi schema, has both valid & invalid resources, but use invalid resource, schema rejected", + + Actions: []any{ + + testUtils.AddPolicy{ + IsYAML: true, + + Creator: actor1Signature, + + Policy: ` + description: A Partially Valid Defra Policy Interface (DPI) + + actor: + name: actor + + resources: + usersValid: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + + usersInvalid: + permissions: + read: + expr: reader - owner + write: + expr: reader + + relations: + owner: + types: + - actor + reader: + types: + - actor + `, + + ExpectedPolicyID: policyIDOfPartiallyValidDPI, + }, + + testUtils.SchemaUpdate{ + Schema: fmt.Sprintf(` + type Users @policy( + id: "%s", + resource: "usersInvalid" + ) { + name: String + age: Int + } + `, + policyIDOfPartiallyValidDPI, + ), + ExpectedError: "expr of required permission=read must start with required relation=owner", + }, + + testUtils.IntrospectionRequest{ + Request: ` + query { + __type (name: "Users") { + name + fields { + name + type { + name + kind + } + } + } + } + `, + ExpectedData: map[string]any{ + "__type": nil, // NOTE: No "Users" should exist. + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +}