diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 4b374d736e..ca12e9bd71 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -17,7 +17,7 @@ - + diff --git a/src/Service.Tests/Authorization/AuthorizationHelpers.cs b/src/Service.Tests/Authorization/AuthorizationHelpers.cs index d6166f4ace..efd4fca93c 100644 --- a/src/Service.Tests/Authorization/AuthorizationHelpers.cs +++ b/src/Service.Tests/Authorization/AuthorizationHelpers.cs @@ -60,7 +60,7 @@ public static RuntimeConfig InitRuntimeConfig( string entityName = TEST_ENTITY, object? entitySource = null, string roleName = "Reader", - Operation operation = Operation.Create, + Config.Operation operation = Config.Operation.Create, HashSet? includedCols = null, HashSet? excludedCols = null, string? databasePolicy = null, diff --git a/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs b/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs index 4120279d5b..8a2fd8806e 100644 --- a/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs +++ b/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs @@ -22,7 +22,7 @@ public class AuthorizationResolverUnitTests { private const string TEST_ENTITY = "SampleEntity"; private const string TEST_ROLE = "Writer"; - private const Operation TEST_OPERATION = Operation.Create; + private const Config.Operation TEST_OPERATION = Config.Operation.Create; private const string TEST_AUTHENTICATION_TYPE = "TestAuth"; private const string TEST_CLAIMTYPE_NAME = "TestName"; @@ -99,14 +99,14 @@ public void NoRoleHeader_RoleContextTest() /// Request operation does not match an operation defined for role (role has >=1 defined operation) -> INVALID /// [DataTestMethod] - [DataRow("Writer", Operation.Create, "Writer", Operation.Create, true)] - [DataRow("Reader", Operation.Create, "Reader", Operation.None, false)] - [DataRow("Writer", Operation.Create, "Writer", Operation.Update, false)] + [DataRow("Writer", Config.Operation.Create, "Writer", Config.Operation.Create, true)] + [DataRow("Reader", Config.Operation.Create, "Reader", Config.Operation.None, false)] + [DataRow("Writer", Config.Operation.Create, "Writer", Config.Operation.Update, false)] public void AreRoleAndOperationDefinedForEntityTest( string configRole, - Operation configOperation, + Config.Operation configOperation, string roleName, - Operation operation, + Config.Operation operation, bool expected) { RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( @@ -131,7 +131,7 @@ public void TestWildcardOperation() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.All); + operation: Config.Operation.All); // Override the permission operations to be a list of operations for wildcard // instead of a list of objects created by InitRuntimeConfig() @@ -143,10 +143,10 @@ public void TestWildcardOperation() Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.All)); + Config.Operation.All)); // The wildcard operation should be expanded to all the explicit operations. - foreach (Operation operation in PermissionOperation.ValidPermissionOperations) + foreach (Config.Operation operation in PermissionOperation.ValidPermissionOperations) { Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, @@ -165,8 +165,8 @@ public void TestWildcardOperation() } // Validate that the authorization check fails because the operations are invalid. - Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, TEST_ROLE, Operation.Insert)); - Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, TEST_ROLE, Operation.Upsert)); + Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, TEST_ROLE, Config.Operation.Insert)); + Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, TEST_ROLE, Config.Operation.Upsert)); } /// @@ -186,12 +186,12 @@ public void TestRoleAndOperationCombination() exclude: null); PermissionOperation readAction = new( - Name: Operation.Read, + Name: Config.Operation.Read, Fields: fieldsForRole, Policy: null); PermissionOperation updateAction = new( - Name: Operation.Update, + Name: Config.Operation.Update, Fields: fieldsForRole, Policy: null); @@ -228,37 +228,37 @@ public void TestRoleAndOperationCombination() Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_ONLY_ROLE, - Operation.Read)); + Config.Operation.Read)); Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_ONLY_ROLE, - Operation.Update)); + Config.Operation.Update)); Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_ONLY_ROLE, - Operation.Create)); + Config.Operation.Create)); Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_ONLY_ROLE, - Operation.Delete)); + Config.Operation.Delete)); // Verify that read only role has permission for read/update and nothing else. Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_AND_UPDATE_ROLE, - Operation.Read)); + Config.Operation.Read)); Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_AND_UPDATE_ROLE, - Operation.Update)); + Config.Operation.Update)); Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_AND_UPDATE_ROLE, - Operation.Create)); + Config.Operation.Create)); Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, READ_AND_UPDATE_ROLE, - Operation.Delete)); + Config.Operation.Delete)); List expectedRolesForRead = new() { READ_ONLY_ROLE, READ_AND_UPDATE_ROLE }; List expectedRolesForUpdate = new() { READ_AND_UPDATE_ROLE }; @@ -266,22 +266,22 @@ public void TestRoleAndOperationCombination() IEnumerable actualReadRolesForCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, "col1", - Operation.Read); + Config.Operation.Read); CollectionAssert.AreEquivalent(expectedRolesForRead, actualReadRolesForCol1.ToList()); IEnumerable actualUpdateRolesForCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, "col1", - Operation.Update); + Config.Operation.Update); CollectionAssert.AreEquivalent(expectedRolesForUpdate, actualUpdateRolesForCol1.ToList()); IEnumerable actualRolesForRead = IAuthorizationResolver.GetRolesForOperation( AuthorizationHelpers.TEST_ENTITY, - Operation.Read, + Config.Operation.Read, authZResolver.EntityPermissionsMap); CollectionAssert.AreEquivalent(expectedRolesForRead, actualRolesForRead.ToList()); IEnumerable actualRolesForUpdate = IAuthorizationResolver.GetRolesForOperation( AuthorizationHelpers.TEST_ENTITY, - Operation.Update, + Config.Operation.Update, authZResolver.EntityPermissionsMap); CollectionAssert.AreEquivalent(expectedRolesForUpdate, actualRolesForUpdate.ToList()); } @@ -296,13 +296,13 @@ public void TestAuthenticatedRoleWhenAnonymousRoleIsDefined() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationResolver.ROLE_ANONYMOUS, - operation: Operation.Create); + operation: Config.Operation.Create); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); - foreach (Operation operation in PermissionOperation.ValidPermissionOperations) + foreach (Config.Operation operation in PermissionOperation.ValidPermissionOperations) { - if (operation is Operation.Create) + if (operation is Config.Operation.Create) { // Create operation should be defined for anonymous role. Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity( @@ -335,13 +335,13 @@ public void TestAuthenticatedRoleWhenAnonymousRoleIsDefined() // Anonymous role's permissions are copied over for authenticated role only. // Assert by checking for an arbitrary role. Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, - AuthorizationHelpers.TEST_ROLE, Operation.Create)); + AuthorizationHelpers.TEST_ROLE, Config.Operation.Create)); // Assert that the create operation has both anonymous, authenticated roles. List expectedRolesForCreate = new() { AuthorizationResolver.ROLE_AUTHENTICATED, AuthorizationResolver.ROLE_ANONYMOUS }; IEnumerable actualRolesForCreate = IAuthorizationResolver.GetRolesForOperation( AuthorizationHelpers.TEST_ENTITY, - Operation.Create, + Config.Operation.Create, authZResolver.EntityPermissionsMap); CollectionAssert.AreEquivalent(expectedRolesForCreate, actualRolesForCreate.ToList()); @@ -351,14 +351,14 @@ public void TestAuthenticatedRoleWhenAnonymousRoleIsDefined() AuthorizationResolver.ROLE_AUTHENTICATED }; IEnumerable actualRolesForCreateCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, - "col1", Operation.Create); + "col1", Config.Operation.Create); CollectionAssert.AreEquivalent(expectedRolesForCreateCol1, actualRolesForCreateCol1.ToList()); // Assert that the col1 field with read operation has no role. List expectedRolesForReadCol1 = new(); IEnumerable actualRolesForReadCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, - "col1", Operation.Read); + "col1", Config.Operation.Read); CollectionAssert.AreEquivalent(expectedRolesForReadCol1, actualRolesForReadCol1.ToList()); } @@ -372,7 +372,7 @@ public void TestAuthenticatedRoleWhenAnonymousRoleIsNotDefined() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create); + operation: Config.Operation.Create); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); @@ -380,20 +380,20 @@ public void TestAuthenticatedRoleWhenAnonymousRoleIsNotDefined() Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create)); + Config.Operation.Create)); // Create operation should not be defined for authenticated role, // because neither authenticated nor anonymous role is defined. Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationResolver.ROLE_AUTHENTICATED, - Operation.Create)); + Config.Operation.Create)); // Assert that the Create operation has only test_role. List expectedRolesForCreate = new() { AuthorizationHelpers.TEST_ROLE }; IEnumerable actualRolesForCreate = IAuthorizationResolver.GetRolesForOperation( AuthorizationHelpers.TEST_ENTITY, - Operation.Create, + Config.Operation.Create, authZResolver.EntityPermissionsMap); CollectionAssert.AreEquivalent(expectedRolesForCreate, actualRolesForCreate.ToList()); @@ -402,7 +402,7 @@ public void TestAuthenticatedRoleWhenAnonymousRoleIsNotDefined() List expectedRolesForCreateCol1 = new() { AuthorizationHelpers.TEST_ROLE }; IEnumerable actualRolesForCreateCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, - "col1", Operation.Create); + "col1", Config.Operation.Create); CollectionAssert.AreEquivalent(expectedRolesForCreateCol1, actualRolesForCreateCol1.ToList()); } @@ -418,12 +418,12 @@ public void TestAuthenticatedRoleWhenBothAnonymousAndAuthenticatedAreDefined() exclude: null); PermissionOperation readAction = new( - Name: Operation.Read, + Name: Config.Operation.Read, Fields: fieldsForRole, Policy: null); PermissionOperation updateAction = new( - Name: Operation.Update, + Name: Config.Operation.Update, Fields: fieldsForRole, Policy: null); @@ -459,11 +459,11 @@ public void TestAuthenticatedRoleWhenBothAnonymousAndAuthenticatedAreDefined() // Assert that for the role authenticated, only the Read operation is allowed. // The Update operation is not allowed even though update is allowed for the role anonymous. Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, - AuthorizationResolver.ROLE_AUTHENTICATED, Operation.Read)); + AuthorizationResolver.ROLE_AUTHENTICATED, Config.Operation.Read)); Assert.IsTrue(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, - AuthorizationResolver.ROLE_ANONYMOUS, Operation.Update)); + AuthorizationResolver.ROLE_ANONYMOUS, Config.Operation.Update)); Assert.IsFalse(authZResolver.AreRoleAndOperationDefinedForEntity(AuthorizationHelpers.TEST_ENTITY, - AuthorizationResolver.ROLE_AUTHENTICATED, Operation.Delete)); + AuthorizationResolver.ROLE_AUTHENTICATED, Config.Operation.Delete)); // Assert that the read operation has both anonymous and authenticated role. List expectedRolesForRead = new() { @@ -471,7 +471,7 @@ public void TestAuthenticatedRoleWhenBothAnonymousAndAuthenticatedAreDefined() AuthorizationResolver.ROLE_AUTHENTICATED }; IEnumerable actualRolesForRead = IAuthorizationResolver.GetRolesForOperation( AuthorizationHelpers.TEST_ENTITY, - Operation.Read, + Config.Operation.Read, authZResolver.EntityPermissionsMap); CollectionAssert.AreEquivalent(expectedRolesForRead, actualRolesForRead.ToList()); @@ -479,7 +479,7 @@ public void TestAuthenticatedRoleWhenBothAnonymousAndAuthenticatedAreDefined() List expectedRolesForUpdate = new() { AuthorizationResolver.ROLE_ANONYMOUS }; IEnumerable actualRolesForUpdate = IAuthorizationResolver.GetRolesForOperation( AuthorizationHelpers.TEST_ENTITY, - Operation.Update, + Config.Operation.Update, authZResolver.EntityPermissionsMap); CollectionAssert.AreEquivalent(expectedRolesForUpdate, actualRolesForUpdate.ToList()); @@ -489,14 +489,14 @@ public void TestAuthenticatedRoleWhenBothAnonymousAndAuthenticatedAreDefined() AuthorizationResolver.ROLE_AUTHENTICATED }; IEnumerable actualRolesForReadCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, - "col1", Operation.Read); + "col1", Config.Operation.Read); CollectionAssert.AreEquivalent(expectedRolesForReadCol1, actualRolesForReadCol1.ToList()); // Assert that the col1 field with Update operation has only anonymous roles. List expectedRolesForUpdateCol1 = new() { AuthorizationResolver.ROLE_ANONYMOUS }; IEnumerable actualRolesForUpdateCol1 = authZResolver.GetRolesForField( AuthorizationHelpers.TEST_ENTITY, - "col1", Operation.Update); + "col1", Config.Operation.Update); CollectionAssert.AreEquivalent(expectedRolesForUpdateCol1, actualRolesForUpdateCol1.ToList()); } @@ -508,12 +508,12 @@ public void TestAuthenticatedRoleWhenBothAnonymousAndAuthenticatedAreDefined() /// The operation configured for the configRole. /// The roleName which is to be checked for the permission. [DataTestMethod] - [DataRow("Writer", Operation.Create, "wRiTeR", DisplayName = "role wRiTeR checked against Writer")] - [DataRow("Reader", Operation.Read, "READER", DisplayName = "role READER checked against Reader")] - [DataRow("Writer", Operation.Create, "WrIter", DisplayName = "role WrIter checked against Writer")] + [DataRow("Writer", Config.Operation.Create, "wRiTeR", DisplayName = "role wRiTeR checked against Writer")] + [DataRow("Reader", Config.Operation.Read, "READER", DisplayName = "role READER checked against Reader")] + [DataRow("Writer", Config.Operation.Create, "WrIter", DisplayName = "role WrIter checked against Writer")] public void AreRoleAndOperationDefinedForEntityTestForDifferentlyCasedRole( string configRole, - Operation operation, + Config.Operation operation, string roleNameToCheck ) { @@ -544,7 +544,7 @@ public void ExplicitIncludeColumn() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: includedColumns ); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); @@ -552,28 +552,28 @@ public void ExplicitIncludeColumn() Assert.IsTrue(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, includedColumns)); // Not allow column. Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, new List { "col4" })); // Mix of allow and not allow. Should result in not allow. Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, new List { "col3", "col4" })); // Column does not exist Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, new List { "col5", "col6" })); } @@ -591,7 +591,7 @@ public void ExplicitIncludeAndExcludeColumns() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: includeColumns, excludedCols: excludeColumns ); @@ -601,27 +601,27 @@ public void ExplicitIncludeAndExcludeColumns() Assert.IsTrue(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, includeColumns)); Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, excludeColumns)); // Not exist column in the inclusion or exclusion list Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, new List { "col4" })); // Mix of allow and not allow. Should result in not allow. Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, new List { "col1", "col3" })); } @@ -638,7 +638,7 @@ public void ColumnExclusionWithSameColumnInclusion() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: includedColumns, excludedCols: excludedColumns ); @@ -649,7 +649,7 @@ public void ColumnExclusionWithSameColumnInclusion() Assert.IsTrue(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, new List { "col2" })); // Col1 should NOT to included since it is in exclusion list. @@ -657,13 +657,13 @@ public void ColumnExclusionWithSameColumnInclusion() Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, new List { "col1" })); Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, excludedColumns)); } @@ -676,7 +676,7 @@ public void WildcardColumnInclusion() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: new HashSet { AuthorizationResolver.WILDCARD } ); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); @@ -686,7 +686,7 @@ public void WildcardColumnInclusion() Assert.IsTrue(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedColumns)); } @@ -703,7 +703,7 @@ public void WildcardColumnInclusionWithExplictExclusion() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: new HashSet { AuthorizationResolver.WILDCARD }, excludedCols: excludedColumns ); @@ -712,12 +712,12 @@ public void WildcardColumnInclusionWithExplictExclusion() Assert.IsTrue(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedColumns)); Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, excludedColumns)); } @@ -732,7 +732,7 @@ public void WildcardColumnExclusion() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, excludedCols: new HashSet { AuthorizationResolver.WILDCARD } ); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); @@ -740,7 +740,7 @@ public void WildcardColumnExclusion() Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, excludedColumns)); } @@ -757,7 +757,7 @@ public void WildcardColumnExclusionWithExplicitColumnInclusion() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: includedColumns, excludedCols: new HashSet { AuthorizationResolver.WILDCARD } ); @@ -766,12 +766,12 @@ public void WildcardColumnExclusionWithExplicitColumnInclusion() Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedColumns)); Assert.IsFalse(authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, excludedColumns)); } @@ -789,14 +789,14 @@ public void CheckIncludeAndExcludeColumnForWildcardOperation() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.All, + operation: Config.Operation.All, includedCols: includeColumns, excludedCols: excludeColumns ); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); - foreach (Operation operation in PermissionOperation.ValidPermissionOperations) + foreach (Config.Operation operation in PermissionOperation.ValidPermissionOperations) { // Validate that the authorization check passes for valid CRUD operations // because columns are accessbile or inaccessible. @@ -827,7 +827,7 @@ public void AreColumnsAllowedForOperationWithMissingFieldProperty(bool expected, RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create + operation: Config.Operation.Create ); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); @@ -837,7 +837,7 @@ public void AreColumnsAllowedForOperationWithMissingFieldProperty(bool expected, authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create, + Config.Operation.Create, new List(columnsToCheck))); } @@ -861,13 +861,13 @@ public void TestAuthenticatedRoleForColumnPermissionsWhenAnonymousRoleIsDefined( RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationResolver.ROLE_ANONYMOUS, - operation: Operation.All, + operation: Config.Operation.All, includedCols: new HashSet(includeCols), excludedCols: new HashSet(excludeCols)); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); - foreach (Operation operation in PermissionOperation.ValidPermissionOperations) + foreach (Config.Operation operation in PermissionOperation.ValidPermissionOperations) { Assert.AreEqual(expected, authZResolver.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, @@ -889,14 +889,14 @@ public void TestAuthenticatedRoleForColumnPermissionsWhenAnonymousRoleIsDefined( /// Columns to be checked for access. /// Expected booolean result for the relevant method call. [DataTestMethod] - [DataRow(Operation.All, "Writer", new string[] { "col1", "col2" }, new string[] { "col3" }, "WRITER", + [DataRow(Config.Operation.All, "Writer", new string[] { "col1", "col2" }, new string[] { "col3" }, "WRITER", new string[] { "col1", "col2" }, true, DisplayName = "Case insensitive role writer")] - [DataRow(Operation.Read, "Reader", new string[] { "col1", "col3", "col4" }, new string[] { "col3" }, "reADeR", + [DataRow(Config.Operation.Read, "Reader", new string[] { "col1", "col3", "col4" }, new string[] { "col3" }, "reADeR", new string[] { "col1", "col3" }, false, DisplayName = "Case insensitive role reader")] - [DataRow(Operation.Create, "Creator", new string[] { "col1", "col2" }, new string[] { "col3", "col4" }, "CREator", + [DataRow(Config.Operation.Create, "Creator", new string[] { "col1", "col2" }, new string[] { "col3", "col4" }, "CREator", new string[] { "col1", "col2" }, true, DisplayName = "Case insensitive role creator")] public void AreColumnsAllowedForOperationWithRoleWithDifferentCasing( - Operation operation, + Config.Operation operation, string configRole, string[] columnsToInclude, string[] columnsToExclude, @@ -913,9 +913,9 @@ public void AreColumnsAllowedForOperationWithRoleWithDifferentCasing( ); AuthorizationResolver authZResolver = AuthorizationHelpers.InitAuthorizationResolver(runtimeConfig); - List operations = AuthorizationResolver.GetAllOperations(operation).ToList(); + List operations = AuthorizationResolver.GetAllOperations(operation).ToList(); - foreach (Operation testOperation in operations) + foreach (Config.Operation testOperation in operations) { // Assert that the expected result and the returned result are equal. Assert.AreEqual(expected, @@ -1150,21 +1150,21 @@ public void ParsePolicyWithDuplicateUserClaims(bool exceptionExpected, params st // no predicates need to be added to the database query generated for the request. // When a value is returned as a result, the execution behaved as expected. [DataTestMethod] - [DataRow("anonymous", "anonymous", Operation.Read, Operation.Read, "id eq 1", true, + [DataRow("anonymous", "anonymous", Config.Operation.Read, Config.Operation.Read, "id eq 1", true, DisplayName = "Fetch Policy for existing system role - anonymous")] - [DataRow("authenticated", "authenticated", Operation.Update, Operation.Update, "id eq 1", true, + [DataRow("authenticated", "authenticated", Config.Operation.Update, Config.Operation.Update, "id eq 1", true, DisplayName = "Fetch Policy for existing system role - authenticated")] - [DataRow("anonymous", "anonymous", Operation.Read, Operation.Read, null, false, + [DataRow("anonymous", "anonymous", Config.Operation.Read, Config.Operation.Read, null, false, DisplayName = "Fetch Policy for existing role, no policy object defined in config.")] - [DataRow("anonymous", "authenticated", Operation.Read, Operation.Read, "id eq 1", false, + [DataRow("anonymous", "authenticated", Config.Operation.Read, Config.Operation.Read, "id eq 1", false, DisplayName = "Fetch Policy for non-configured role")] - [DataRow("anonymous", "anonymous", Operation.Read, Operation.Create, "id eq 1", false, + [DataRow("anonymous", "anonymous", Config.Operation.Read, Config.Operation.Create, "id eq 1", false, DisplayName = "Fetch Policy for non-configured operation")] public void GetDBPolicyTest( string clientRole, string configuredRole, - Operation requestOperation, - Operation configuredOperation, + Config.Operation requestOperation, + Config.Operation configuredOperation, string policy, bool expectPolicy) { @@ -1214,7 +1214,7 @@ public void GetDBPolicyTest( public static RuntimeConfig InitRuntimeConfig( string entityName = "SampleEntity", string roleName = "Reader", - Operation operation = Operation.Create, + Config.Operation operation = Config.Operation.Create, HashSet? includedCols = null, HashSet? excludedCols = null, string? requestPolicy = null, diff --git a/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationTests.cs b/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationTests.cs index a39b1860ef..7c49e9f961 100644 --- a/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationTests.cs +++ b/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationTests.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Azure.DataApiBuilder.Auth; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Authorization; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.GraphQLBuilder.Mutations; @@ -116,7 +115,7 @@ private static SqlMutationEngine SetupTestFixture(bool isAuthorized) _authorizationResolver.Setup(x => x.AreColumnsAllowedForOperation( It.IsAny(), It.IsAny(), - It.IsAny(), + It.IsAny(), It.IsAny>() )).Returns(isAuthorized); diff --git a/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationUnitTests.cs b/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationUnitTests.cs index 8c37572df9..6f92eed803 100644 --- a/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationUnitTests.cs +++ b/src/Service.Tests/Authorization/GraphQL/GraphQLMutationAuthorizationUnitTests.cs @@ -20,14 +20,14 @@ public class GraphQLMutationAuthorizationUnitTests /// /// /// - [DataRow(Operation.Create, new string[] { }, "", + [DataRow(Config.Operation.Create, new string[] { }, "", DisplayName = "No Roles -> Expects no objectTypeDefinition created")] - [DataRow(Operation.Create, new string[] { "role1" }, @"@authorize(roles: [""role1""])", + [DataRow(Config.Operation.Create, new string[] { "role1" }, @"@authorize(roles: [""role1""])", DisplayName = "One Role added to Authorize Directive")] - [DataRow(Operation.Create, new string[] { "role1", "role2" }, @"@authorize(roles: [""role1"",""role2""])", + [DataRow(Config.Operation.Create, new string[] { "role1", "role2" }, @"@authorize(roles: [""role1"",""role2""])", DisplayName = "Two Roles added to Authorize Directive")] [DataTestMethod] - public void AuthorizeDirectiveAddedForMutation(Operation operationType, string[] rolesDefinedInPermissions, string expectedAuthorizeDirective) + public void AuthorizeDirectiveAddedForMutation(Config.Operation operationType, string[] rolesDefinedInPermissions, string expectedAuthorizeDirective) { string gql = @" @@ -43,7 +43,7 @@ type Foo @model(name: ""Foo""){ entities: new Dictionary { { "Foo", GraphQLTestHelpers.GenerateEmptyEntity() } }, entityPermissionsMap: GraphQLTestHelpers.CreateStubEntityPermissionsMap( entityNames: new string[] { "Foo" }, - operations: new Operation[] { operationType }, + operations: new Config.Operation[] { operationType }, roles: rolesDefinedInPermissions) ); diff --git a/src/Service.Tests/Authorization/GraphQL/GraphQLQueryAuthorizationUnitTests.cs b/src/Service.Tests/Authorization/GraphQL/GraphQLQueryAuthorizationUnitTests.cs index 5ba4625012..cd24ee5d4e 100644 --- a/src/Service.Tests/Authorization/GraphQL/GraphQLQueryAuthorizationUnitTests.cs +++ b/src/Service.Tests/Authorization/GraphQL/GraphQLQueryAuthorizationUnitTests.cs @@ -40,7 +40,7 @@ type Foo @model(name: ""Foo""){ inputTypes: new(), GraphQLTestHelpers.CreateStubEntityPermissionsMap( entityNames: new string[] { "Foo" }, - operations: new Operation[] { Operation.Read }, + operations: new Config.Operation[] { Config.Operation.Read }, roles: rolesDefinedInPermissions) ); diff --git a/src/Service.Tests/Authorization/REST/RestAuthorizationHandlerUnitTests.cs b/src/Service.Tests/Authorization/REST/RestAuthorizationHandlerUnitTests.cs index 31d6d29a74..30ea8a474f 100644 --- a/src/Service.Tests/Authorization/REST/RestAuthorizationHandlerUnitTests.cs +++ b/src/Service.Tests/Authorization/REST/RestAuthorizationHandlerUnitTests.cs @@ -147,22 +147,22 @@ public async Task EntityRoleOperationPermissionsRequirementTest( authorizationResolver.Setup(x => x.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Create + Config.Operation.Create )).Returns(isValidCreateRoleOperation); authorizationResolver.Setup(x => x.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Read + Config.Operation.Read )).Returns(isValidReadRoleOperation); authorizationResolver.Setup(x => x.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Update + Config.Operation.Update )).Returns(isValidUpdateRoleOperation); authorizationResolver.Setup(x => x.AreRoleAndOperationDefinedForEntity( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Delete + Config.Operation.Delete )).Returns(isValidDeleteRoleOperation); HttpContext httpContext = CreateHttpContext(httpMethod); @@ -257,13 +257,13 @@ public async Task FindColumnPermissionsTests(string[] columnsRequestedInput, authorizationResolver.Setup(x => x.AreColumnsAllowedForOperation( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Read, + Config.Operation.Read, It.IsAny>() // Can be any IEnumerable, as find request result field list is depedent on AllowedColumns. )).Returns(areColumnsAllowed); authorizationResolver.Setup(x => x.GetAllowedExposedColumns( AuthorizationHelpers.TEST_ENTITY, AuthorizationHelpers.TEST_ROLE, - Operation.Read + Config.Operation.Read )).Returns(allowedColumns); string httpMethod = HttpConstants.GET; @@ -365,7 +365,7 @@ private static AuthorizationResolver SetupAuthResolverWithWildcardOperation() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: "admin", - operation: Operation.All); + operation: Config.Operation.All); // Override the operation to be a list of string for wildcard instead of a list of object created by InitRuntimeConfig() // diff --git a/src/Service.Tests/Configuration/ConfigurationTests.cs b/src/Service.Tests/Configuration/ConfigurationTests.cs index 7965fed602..5d1ecec4bf 100644 --- a/src/Service.Tests/Configuration/ConfigurationTests.cs +++ b/src/Service.Tests/Configuration/ConfigurationTests.cs @@ -166,7 +166,7 @@ public void TestCorrectSerializationOfSourceObject( entityName: "MyEntity", entitySource: entitySource, roleName: "Anonymous", - operation: Operation.All, + operation: Config.Operation.All, includedCols: null, excludedCols: null, databasePolicy: null @@ -272,7 +272,7 @@ public async Task TestSqlSettingPostStartupConfigurations() entityName: POST_STARTUP_CONFIG_ENTITY, entitySource: POST_STARTUP_CONFIG_ENTITY_SOURCE, roleName: POST_STARTUP_CONFIG_ROLE, - operation: Operation.Read, + operation: Config.Operation.Read, includedCols: new HashSet() { "*" }); ConfigurationPostParameters config = GetPostStartupConfigParams(MSSQL_ENVIRONMENT, configuration); @@ -534,9 +534,9 @@ private static void ConfigFileDeserializationValidationHelper(string jsonString) { foreach (object operation in permission.Operations) { - HashSet allowedActions = - new() { Operation.All, Operation.Create, Operation.Read, - Operation.Update, Operation.Delete }; + HashSet allowedActions = + new() { Config.Operation.All, Config.Operation.Create, Config.Operation.Read, + Config.Operation.Update, Config.Operation.Delete }; Assert.IsTrue(((JsonElement)operation).ValueKind == JsonValueKind.String || ((JsonElement)operation).ValueKind == JsonValueKind.Object); if (((JsonElement)operation).ValueKind == JsonValueKind.Object) @@ -551,7 +551,7 @@ private static void ConfigFileDeserializationValidationHelper(string jsonString) } else { - Operation name = AuthorizationResolver.WILDCARD.Equals(operation.ToString()) ? Operation.All : ((JsonElement)operation).Deserialize(RuntimeConfig.SerializerOptions); + Config.Operation name = AuthorizationResolver.WILDCARD.Equals(operation.ToString()) ? Config.Operation.All : ((JsonElement)operation).Deserialize(RuntimeConfig.SerializerOptions); Assert.IsTrue(allowedActions.Contains(name)); } } @@ -1098,7 +1098,7 @@ public static RuntimeConfig InitMinimalRuntimeConfig(Dictionary GetEntityPermissionsMap(string { return GraphQLTestHelpers.CreateStubEntityPermissionsMap( entityNames: entities, - operations: new Operation[] { Operation.Create, Operation.Read, Operation.Update, Operation.Delete }, + operations: new Config.Operation[] { Config.Operation.Create, Config.Operation.Read, Config.Operation.Update, Config.Operation.Delete }, roles: new string[] { "anonymous", "authenticated" } ); } diff --git a/src/Service.Tests/GraphQLBuilder/Helpers/GraphQLTestHelpers.cs b/src/Service.Tests/GraphQLBuilder/Helpers/GraphQLTestHelpers.cs index 35bfdfc951..df4a3c8e35 100644 --- a/src/Service.Tests/GraphQLBuilder/Helpers/GraphQLTestHelpers.cs +++ b/src/Service.Tests/GraphQLBuilder/Helpers/GraphQLTestHelpers.cs @@ -47,14 +47,14 @@ type People @model(name:""People"") { /// Actions performed on entity to resolve authorization permissions. /// Collection of role names allowed to perform action on entity. /// EntityPermissionsMap Key/Value collection. - public static Dictionary CreateStubEntityPermissionsMap(string[] entityNames, IEnumerable operations, IEnumerable roles) + public static Dictionary CreateStubEntityPermissionsMap(string[] entityNames, IEnumerable operations, IEnumerable roles) { EntityMetadata entityMetadata = new() { - OperationToRolesMap = new Dictionary>() + OperationToRolesMap = new Dictionary>() }; - foreach (Operation operation in operations) + foreach (Config.Operation operation in operations) { entityMetadata.OperationToRolesMap.Add(operation, roles.ToList()); } diff --git a/src/Service.Tests/GraphQLBuilder/MutationBuilderTests.cs b/src/Service.Tests/GraphQLBuilder/MutationBuilderTests.cs index c98c08260c..1a00198355 100644 --- a/src/Service.Tests/GraphQLBuilder/MutationBuilderTests.cs +++ b/src/Service.Tests/GraphQLBuilder/MutationBuilderTests.cs @@ -29,7 +29,7 @@ public void SetupEntityPermissionsMap() { _entityPermissions = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "Foo", "Baz", "Bar" }, - new Operation[] { Operation.Create, Operation.Update, Operation.Delete }, + new Config.Operation[] { Config.Operation.Create, Config.Operation.Update, Config.Operation.Delete }, new string[] { "anonymous", "authenticated" } ); } @@ -64,7 +64,7 @@ type Foo @model(name:""Foo"") { Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "Foo" }, - new Operation[] { Operation.Create }, + new Config.Operation[] { Config.Operation.Create }, roles); DocumentNode mutationRoot = MutationBuilder.Build(root, DatabaseType.cosmos, @@ -605,7 +605,7 @@ type Foo @model(name:""Foo"") { Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "Foo" }, - new Operation[] { Operation.Delete }, + new Config.Operation[] { Config.Operation.Delete }, roles); DocumentNode mutationRoot = MutationBuilder.Build(root, DatabaseType.cosmos, @@ -711,7 +711,7 @@ type Foo @model(name:""Foo"") { Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "Foo" }, - new Operation[] { Operation.Update }, + new Config.Operation[] { Config.Operation.Update }, roles); DocumentNode mutationRoot = MutationBuilder.Build( root, @@ -959,7 +959,7 @@ string expectedName DocumentNode root = Utf8GraphQLParser.Parse(gql); Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { entityName }, - new Operation[] { Operation.Create, Operation.Update, Operation.Delete }, + new Config.Operation[] { Config.Operation.Create, Config.Operation.Update, Config.Operation.Delete }, new string[] { "anonymous", "authenticated" }); Entity entity = (singularName is not null) diff --git a/src/Service.Tests/GraphQLBuilder/QueryBuilderTests.cs b/src/Service.Tests/GraphQLBuilder/QueryBuilderTests.cs index e7c2655ec7..42db25a884 100644 --- a/src/Service.Tests/GraphQLBuilder/QueryBuilderTests.cs +++ b/src/Service.Tests/GraphQLBuilder/QueryBuilderTests.cs @@ -28,7 +28,7 @@ public void SetupEntityPermissionsMap() { _entityPermissions = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "Foo" }, - new Operation[] { Operation.Read }, + new Config.Operation[] { Config.Operation.Read }, new string[] { "anonymous", "authenticated" } ); } @@ -57,7 +57,7 @@ type Foo @model(name:""Foo"") { Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "Foo" }, - new Operation[] { Operation.Read }, + new Config.Operation[] { Config.Operation.Read }, roles); DocumentNode queryRoot = QueryBuilder.Build( root, @@ -132,7 +132,7 @@ type foo @model(name:""foo"") { Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { "foo" }, - new Operation[] { Operation.Read }, + new Config.Operation[] { Config.Operation.Read }, roles); DocumentNode queryRoot = QueryBuilder.Build( root, @@ -334,7 +334,7 @@ string expectedNameInDescription Dictionary entityPermissionsMap = GraphQLTestHelpers.CreateStubEntityPermissionsMap( new string[] { entityName }, - new Operation[] { Operation.Read }, + new Config.Operation[] { Config.Operation.Read }, new string[] { "anonymous", "authenticated" }); Entity entity = (singularName is not null) diff --git a/src/Service.Tests/SqlTests/RestApiTests/Delete/DeleteApiTestBase.cs b/src/Service.Tests/SqlTests/RestApiTests/Delete/DeleteApiTestBase.cs index 49455026d8..63f0bbad88 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Delete/DeleteApiTestBase.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Delete/DeleteApiTestBase.cs @@ -1,6 +1,5 @@ using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Services; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -32,7 +31,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: null, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: null, expectedStatusCode: HttpStatusCode.NoContent ); @@ -55,7 +54,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationMappingEntity, sqlQuery: null, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: null, expectedStatusCode: HttpStatusCode.NoContent ); @@ -79,7 +78,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationUniqueCharactersEntity, sqlQuery: null, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: null, expectedStatusCode: HttpStatusCode.NoContent ); @@ -99,7 +98,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_all_books, sqlQuery: null, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: null, expectedStatusCode: HttpStatusCode.NoContent ); @@ -110,7 +109,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_subset_stocks, sqlQuery: null, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: null, expectedStatusCode: HttpStatusCode.NoContent ); @@ -134,7 +133,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: string.Empty, exceptionExpected: true, expectedErrorMessage: "Not Found", @@ -158,7 +157,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: string.Empty, exceptionExpected: true, expectedErrorMessage: "The request is invalid since the primary keys: title requested were not found in the entity definition.", @@ -181,7 +180,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: string.Empty, exceptionExpected: true, expectedErrorMessage: RequestValidator.PRIMARY_KEY_NOT_PROVIDED_ERR_MESSAGE, @@ -202,7 +201,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: string.Empty, exceptionExpected: true, expectedErrorMessage: "Parameter \"{}\" cannot be resolved as column \"id\" with type \"Int32\".", @@ -233,7 +232,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: string.Empty, exceptionExpected: true, expectedErrorMessage: message, @@ -256,7 +255,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _composite_subset_bookPub, sqlQuery: null, - operationType: Operation.Delete, + operationType: Config.Operation.Delete, requestBody: null, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/RestApiTests/Insert/InsertApiTestBase.cs b/src/Service.Tests/SqlTests/RestApiTests/Insert/InsertApiTestBase.cs index 1a49aa068d..b81348beda 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Insert/InsertApiTestBase.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Insert/InsertApiTestBase.cs @@ -1,6 +1,5 @@ using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Services; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -32,7 +31,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(nameof(InsertOneTest)), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -51,7 +50,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("InsertOneInCompositeNonAutoGenPKTest"), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -77,7 +76,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_all_books, sqlQuery: GetQuery("InsertOneInBooksViewAll"), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created ); @@ -97,7 +96,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_subset_stocks, sqlQuery: GetQuery("InsertOneInStocksViewSelected"), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created ); @@ -124,7 +123,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationUniqueCharactersEntity, sqlQuery: GetQuery(nameof(InsertOneUniqueCharactersTest)), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -151,7 +150,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationMappingEntity, sqlQuery: GetQuery(nameof(InsertOneWithMappingTest)), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -177,7 +176,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _entityWithCompositePrimaryKey, sqlQuery: GetQuery(nameof(InsertOneInCompositeKeyTableTest)), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -194,7 +193,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _entityWithCompositePrimaryKey, sqlQuery: GetQuery("InsertOneInDefaultTestTable"), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -219,7 +218,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("InsertOneWithNullFieldValue"), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -250,7 +249,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(query), - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -275,7 +274,7 @@ await SetupAndRunRestApiTest( queryString: "?/id/5001", entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: RequestValidator.QUERY_STRING_INVALID_USAGE_ERR_MESSAGE, @@ -300,7 +299,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: RequestValidator.BATCH_MUTATION_UNSUPPORTED_ERR_MESSAGE, @@ -326,7 +325,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Parameter \"[1234,4321]\" cannot be resolved as column \"publisher_id\" with type \"Int32\".", @@ -349,7 +348,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Missing field in body: title.", @@ -374,7 +373,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Field not allowed in body: id.", @@ -399,7 +398,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Missing field in body: id.", @@ -426,7 +425,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: null, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Parameter \"StringFailsToCastToInt\" cannot be resolved as column \"publisher_id\" with type \"Int32\".", @@ -452,7 +451,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Missing field in body: title.", @@ -471,7 +470,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Missing field in body: categoryName.", @@ -497,7 +496,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid value for field piecesRequired in request body.", @@ -518,7 +517,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid value for field categoryName in request body.", @@ -549,7 +548,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationBrokenMappingEntity, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, exceptionExpected: true, requestBody: requestBody, expectedErrorMessage: "Invalid request body. Contained unexpected fields in body: hazards", @@ -579,7 +578,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _composite_subset_bookPub, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, exceptionExpected: true, requestBody: requestBody, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/RestApiTests/Insert/MsSqlInsertApiTests.cs b/src/Service.Tests/SqlTests/RestApiTests/Insert/MsSqlInsertApiTests.cs index 28b06777db..6f8e90c263 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Insert/MsSqlInsertApiTests.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Insert/MsSqlInsertApiTests.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -170,7 +169,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/RestApiTests/Insert/MySqlInsertApiTests.cs b/src/Service.Tests/SqlTests/RestApiTests/Insert/MySqlInsertApiTests.cs index 638cdc9b22..caeaa23149 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Insert/MySqlInsertApiTests.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Insert/MySqlInsertApiTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -181,7 +180,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/RestApiTests/Insert/PostgreSqlInsertApiTests.cs b/src/Service.Tests/SqlTests/RestApiTests/Insert/PostgreSqlInsertApiTests.cs index 00d1a03c92..bdd2200239 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Insert/PostgreSqlInsertApiTests.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Insert/PostgreSqlInsertApiTests.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -206,7 +205,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Insert, + operationType: Config.Operation.Insert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs b/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs index 10bf6869bd..6b3847610f 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Services; using Microsoft.AspNetCore.Http; @@ -41,7 +40,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Insert_Nulled_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -59,7 +58,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Update_Nulled_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -89,7 +88,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationUniqueCharactersEntity, sqlQuery: GetQuery(nameof(PatchOne_Insert_UniqueCharacters_Test)), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -118,7 +117,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: GetQuery(nameof(PatchOne_Insert_NonAutoGenPK_Test)), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -137,7 +136,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Insert_CompositeNonAutoGenPK_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -156,7 +155,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Insert_Empty_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -173,7 +172,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Insert_Default_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -192,7 +191,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationMappingEntity, sqlQuery: GetQuery("PatchOne_Insert_Mapping_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -219,7 +218,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_subset_stocks, sqlQuery: GetQuery("PatchOneInsertInStocksViewSelected"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: string.Empty @@ -244,7 +243,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(nameof(PatchOne_Update_Test)), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -259,7 +258,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _entityWithCompositePrimaryKey, sqlQuery: GetQuery("PatchOne_Update_Default_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -274,7 +273,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Update_CompositeNonAutoGenPK_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -290,7 +289,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PatchOne_Update_Empty_Test"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -316,7 +315,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_subset_stocks, sqlQuery: GetQuery("PatchOneUpdateStocksViewSelected"), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -342,7 +341,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(nameof(PatchOne_Update_IfMatchHeaders_Test)), - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, headers: new HeaderDictionary(headerDictionary), requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK @@ -373,7 +372,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: null, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: $"Cannot perform INSERT and could not find {_integrationEntityName} with primary key to perform UPDATE on.", @@ -402,7 +401,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: null, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: $"Cannot perform INSERT and could not find {_integration_NonAutoGenPK_EntityName} with primary key to perform UPDATE on.", @@ -433,7 +432,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, headers: new HeaderDictionary(headerDictionary), requestBody: requestBody, exceptionExpected: true, @@ -465,7 +464,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationBrokenMappingEntity, sqlQuery: string.Empty, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, exceptionExpected: true, requestBody: requestBody, expectedErrorMessage: "Invalid request body. Either insufficient or extra fields supplied.", @@ -496,7 +495,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid value for field categoryName in request body.", @@ -516,7 +515,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid value for field categoryName in request body.", @@ -541,7 +540,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: null, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Parameter \"StringFailsToCastToInt\" cannot be resolved as column \"publisher_id\" with type \"Int32\".", @@ -568,7 +567,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: string.Empty, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: RequestValidator.PRIMARY_KEY_NOT_PROVIDED_ERR_MESSAGE, @@ -597,7 +596,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _composite_subset_bookPub, sqlQuery: string.Empty, - operationType: Operation.UpsertIncremental, + operationType: Config.Operation.UpsertIncremental, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs b/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs index 880619a5d3..3df0c07bba 100644 --- a/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs +++ b/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Services; using Microsoft.AspNetCore.Http; @@ -38,7 +37,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(nameof(PutOne_Update_Test)), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -54,7 +53,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _entityWithCompositePrimaryKey, sqlQuery: GetQuery("PutOne_Update_Default_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -72,7 +71,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Update_CompositeNonAutoGenPK_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -91,7 +90,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Update_NullOutMissingField_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -109,7 +108,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Update_Empty_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -136,7 +135,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(nameof(PutOne_Update_IfMatchHeaders_Test)), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, headers: new HeaderDictionary(headerDictionary), requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK @@ -164,7 +163,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: GetQuery(nameof(PutOne_Insert_Test)), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -185,7 +184,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: GetQuery("PutOne_Insert_Nullable_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -207,7 +206,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_AutoGenNonPK_EntityName, sqlQuery: GetQuery("PutOne_Insert_AutoGenNonPK_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -226,7 +225,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Insert_CompositeNonAutoGenPK_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -243,7 +242,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Insert_Default_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -262,7 +261,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Insert_Empty_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -290,7 +289,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_subset_stocks, sqlQuery: GetQuery("PutOneInsertInStocksViewSelected"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created ); @@ -319,7 +318,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Insert_Nulled_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.Created, expectedLocationHeader: expectedLocationHeader @@ -340,7 +339,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: GetQuery("PutOne_Update_Nulled_Test"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -365,7 +364,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _simple_subset_stocks, sqlQuery: GetQuery("PutOneUpdateStocksViewSelected"), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -392,7 +391,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationMappingEntity, sqlQuery: GetQuery(nameof(PutOne_Update_With_Mapping_Test)), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -421,7 +420,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integrationEntityName, sqlQuery: GetQuery(query), - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedStatusCode: HttpStatusCode.OK ); @@ -446,7 +445,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Missing field in body: categoryName.", @@ -471,7 +470,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, @@ -499,7 +498,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid request body. Missing field in body: publisher_id.", @@ -529,7 +528,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: $"Cannot perform INSERT and could not find {_integrationEntityName} with primary key to perform UPDATE on.", @@ -551,7 +550,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _entityWithCompositePrimaryKey, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: $"Cannot perform INSERT and could not find {_entityWithCompositePrimaryKey} with primary key to perform UPDATE on.", @@ -579,7 +578,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: $"Invalid request body. Missing field in body: publisher_id.", @@ -597,7 +596,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: $"Invalid request body. Missing field in body: categoryName.", @@ -624,7 +623,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_AutoGenNonPK_EntityName, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, expectedErrorMessage: @"Invalid request body. Either insufficient or extra fields supplied.", expectedStatusCode: HttpStatusCode.BadRequest @@ -653,7 +652,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, headers: new HeaderDictionary(headerDictionary), requestBody: requestBody, exceptionExpected: true, @@ -682,7 +681,7 @@ await SetupAndRunRestApiTest( queryString: null, entityNameOrPath: _integration_NonAutoGenPK_EntityName, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: RequestValidator.PRIMARY_KEY_NOT_PROVIDED_ERR_MESSAGE, @@ -708,7 +707,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _integrationEntityName, sqlQuery: null, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Parameter \"StringFailsToCastToInt\" cannot be resolved as column \"publisher_id\" with type \"Int32\".", @@ -737,7 +736,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid value for field categoryName in request body.", @@ -757,7 +756,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _Composite_NonAutoGenPK_EntityPath, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: "Invalid value for field categoryName in request body.", @@ -786,7 +785,7 @@ await SetupAndRunRestApiTest( queryString: string.Empty, entityNameOrPath: _composite_subset_bookPub, sqlQuery: string.Empty, - operationType: Operation.Upsert, + operationType: Config.Operation.Upsert, requestBody: requestBody, exceptionExpected: true, expectedErrorMessage: expectedErrorMessage, diff --git a/src/Service.Tests/SqlTests/SqlTestBase.cs b/src/Service.Tests/SqlTests/SqlTestBase.cs index 65abf290d9..c193fb018e 100644 --- a/src/Service.Tests/SqlTests/SqlTestBase.cs +++ b/src/Service.Tests/SqlTests/SqlTestBase.cs @@ -346,7 +346,7 @@ protected static async Task SetupAndRunRestApiTest( string queryString, string entityNameOrPath, string sqlQuery, - Operation operationType = Operation.Read, + Config.Operation operationType = Config.Operation.Read, string restPath = "api", IHeaderDictionary headers = null, string requestBody = null, @@ -422,11 +422,11 @@ protected static async Task SetupAndRunRestApiTest( // Initial DELETE request results in 204 no content, no exception thrown. // Subsequent DELETE requests result in 404, which result in an exception. string expected; - if ((operationType is Operation.Delete || - operationType is Operation.Upsert || - operationType is Operation.UpsertIncremental || - operationType is Operation.Update || - operationType is Operation.UpdateIncremental) + if ((operationType is Config.Operation.Delete || + operationType is Config.Operation.Upsert || + operationType is Config.Operation.UpsertIncremental || + operationType is Config.Operation.Update || + operationType is Config.Operation.UpdateIncremental) && response.StatusCode == HttpStatusCode.NoContent ) { @@ -452,7 +452,7 @@ operationType is Operation.Update || string dbResult = await GetDatabaseResultAsync(sqlQuery, expectJson); // For FIND requests, null result signifies an empty result set - dbResult = (operationType is Operation.Read && dbResult is null) ? "[]" : dbResult; + dbResult = (operationType is Config.Operation.Read && dbResult is null) ? "[]" : dbResult; expected = $"{{\"{SqlTestHelper.jsonResultTopLevelKey}\":" + $"{FormatExpectedValue(dbResult)}{ExpectedNextLinkIfAny(paginated, baseUrl, $"{expectedAfterQueryString}")}}}"; } diff --git a/src/Service.Tests/SqlTests/SqlTestHelper.cs b/src/Service.Tests/SqlTests/SqlTestHelper.cs index ba56f7698c..6dbb0f774c 100644 --- a/src/Service.Tests/SqlTests/SqlTestHelper.cs +++ b/src/Service.Tests/SqlTests/SqlTestHelper.cs @@ -153,19 +153,19 @@ public static async Task VerifyResultAsync( /// The operation to be executed on the entity. /// /// - public static HttpMethod GetHttpMethodFromOperation(Operation operationType) + public static HttpMethod GetHttpMethodFromOperation(Config.Operation operationType) { switch (operationType) { - case Operation.Read: + case Config.Operation.Read: return HttpMethod.Get; - case Operation.Insert: + case Config.Operation.Insert: return HttpMethod.Post; - case Operation.Delete: + case Config.Operation.Delete: return HttpMethod.Delete; - case Operation.Upsert: + case Config.Operation.Upsert: return HttpMethod.Put; - case Operation.UpsertIncremental: + case Config.Operation.UpsertIncremental: return HttpMethod.Patch; default: throw new DataApiBuilderException( diff --git a/src/Service.Tests/TestHelper.cs b/src/Service.Tests/TestHelper.cs index 1f29130395..491361bea4 100644 --- a/src/Service.Tests/TestHelper.cs +++ b/src/Service.Tests/TestHelper.cs @@ -141,18 +141,18 @@ public static void AddMissingEntitiesToConfig(RuntimeConfig config, string entit { ""role"": ""anonymous"", ""actions"": [" + - $" \"{Operation.Create.ToString().ToLower()}\"," + - $" \"{Operation.Read.ToString().ToLower()}\"," + - $" \"{Operation.Delete.ToString().ToLower()}\"," + - $" \"{Operation.Update.ToString().ToLower()}\" ]" + + $" \"{Config.Operation.Create.ToString().ToLower()}\"," + + $" \"{Config.Operation.Read.ToString().ToLower()}\"," + + $" \"{Config.Operation.Delete.ToString().ToLower()}\"," + + $" \"{Config.Operation.Update.ToString().ToLower()}\" ]" + @"}, { ""role"": ""authenticated"", ""actions"": [" + - $" \"{Operation.Create.ToString().ToLower()}\"," + - $" \"{Operation.Read.ToString().ToLower()}\"," + - $" \"{Operation.Delete.ToString().ToLower()}\"," + - $" \"{Operation.Update.ToString().ToLower()}\" ]" + + $" \"{Config.Operation.Create.ToString().ToLower()}\"," + + $" \"{Config.Operation.Read.ToString().ToLower()}\"," + + $" \"{Config.Operation.Delete.ToString().ToLower()}\"," + + $" \"{Config.Operation.Update.ToString().ToLower()}\" ]" + @"} ] }"; diff --git a/src/Service.Tests/Unittests/ConfigValidationUnitTests.cs b/src/Service.Tests/Unittests/ConfigValidationUnitTests.cs index a04b4b1221..39f7836015 100644 --- a/src/Service.Tests/Unittests/ConfigValidationUnitTests.cs +++ b/src/Service.Tests/Unittests/ConfigValidationUnitTests.cs @@ -34,7 +34,7 @@ public void InaccessibleFieldRequestedByPolicy(string dbPolicy) RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: new HashSet { "*" }, excludedCols: new HashSet { "id", "email" }, databasePolicy: dbPolicy @@ -112,10 +112,10 @@ public void InvalidCRUDForStoredProcedure(object[] operations, bool isValid) /// Database policy. /// The action to be validated. [DataTestMethod] - [DataRow("@claims.id eq @item.col1", Operation.Insert, DisplayName = "Invalid action Insert specified in config")] - [DataRow("@claims.id eq @item.col2", Operation.Upsert, DisplayName = "Invalid action Upsert specified in config")] - [DataRow("@claims.id eq @item.col3", Operation.UpsertIncremental, DisplayName = "Invalid action UpsertIncremental specified in config")] - public void InvalidActionSpecifiedForARole(string dbPolicy, Operation action) + [DataRow("@claims.id eq @item.col1", Config.Operation.Insert, DisplayName = "Invalid action Insert specified in config")] + [DataRow("@claims.id eq @item.col2", Config.Operation.Upsert, DisplayName = "Invalid action Upsert specified in config")] + [DataRow("@claims.id eq @item.col3", Config.Operation.UpsertIncremental, DisplayName = "Invalid action UpsertIncremental specified in config")] + public void InvalidActionSpecifiedForARole(string dbPolicy, Config.Operation action) { RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, @@ -142,13 +142,13 @@ public void InvalidActionSpecifiedForARole(string dbPolicy, Operation action) /// The action to be validated. /// Whether an error is expected. [DataTestMethod] - [DataRow("1 eq @item.col1", Operation.Create, true, DisplayName = "Database Policy defined for Create fails")] - [DataRow("", Operation.Create, true, DisplayName = "Database Policy left empty for Create fails")] - [DataRow(null, Operation.Create, false, DisplayName = "Database Policy NOT defined for Create passes")] - [DataRow("1 eq @item.col2", Operation.Read, false, DisplayName = "Database Policy defined for Read passes")] - [DataRow("2 eq @item.col3", Operation.Update, false, DisplayName = "Database Policy defined for Update passes")] - [DataRow("2 eq @item.col3", Operation.Delete, false, DisplayName = "Database Policy defined for Delete passes")] - public void AddDatabasePolicyToCreateOperationPermission(string dbPolicy, Operation action, bool errorExpected) + [DataRow("1 eq @item.col1", Config.Operation.Create, true, DisplayName = "Database Policy defined for Create fails")] + [DataRow("", Config.Operation.Create, true, DisplayName = "Database Policy left empty for Create fails")] + [DataRow(null, Config.Operation.Create, false, DisplayName = "Database Policy NOT defined for Create passes")] + [DataRow("1 eq @item.col2", Config.Operation.Read, false, DisplayName = "Database Policy defined for Read passes")] + [DataRow("2 eq @item.col3", Config.Operation.Update, false, DisplayName = "Database Policy defined for Update passes")] + [DataRow("2 eq @item.col3", Config.Operation.Delete, false, DisplayName = "Database Policy defined for Delete passes")] + public void AddDatabasePolicyToCreateOperationPermission(string dbPolicy, Config.Operation action, bool errorExpected) { RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, @@ -547,7 +547,7 @@ public void EmptyClaimTypeSuppliedInPolicy(string dbPolicy) RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: new HashSet { "col1", "col2", "col3" }, databasePolicy: dbPolicy ); @@ -579,7 +579,7 @@ public void ParseInvalidDbPolicyWithInvalidClaimTypeFormat(string policy) RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.Create, + operation: Config.Operation.Create, includedCols: new HashSet { "col1", "col2", "col3" }, databasePolicy: policy ); @@ -602,11 +602,11 @@ public void ParseInvalidDbPolicyWithInvalidClaimTypeFormat(string policy) /// The action for which database policy is defined. /// Boolean value indicating whether an exception is expected or not. [DataTestMethod] - [DataRow("StaticWebApps", "@claims.userId eq @item.col2", Operation.Read, false, DisplayName = "SWA- Database Policy defined for Read passes")] - [DataRow("staticwebapps", "@claims.userDetails eq @item.col3", Operation.Update, false, DisplayName = "SWA- Database Policy defined for Update passes")] - [DataRow("StaticWebAPPs", "@claims.email eq @item.col3", Operation.Delete, true, DisplayName = "SWA- Database Policy defined for Delete fails")] - [DataRow("appService", "@claims.email eq @item.col3", Operation.Delete, false, DisplayName = "AppService- Database Policy defined for Delete passes")] - public void TestInvalidClaimsForStaticWebApps(string authProvider, string dbPolicy, Operation action, bool errorExpected) + [DataRow("StaticWebApps", "@claims.userId eq @item.col2", Config.Operation.Read, false, DisplayName = "SWA- Database Policy defined for Read passes")] + [DataRow("staticwebapps", "@claims.userDetails eq @item.col3", Config.Operation.Update, false, DisplayName = "SWA- Database Policy defined for Update passes")] + [DataRow("StaticWebAPPs", "@claims.email eq @item.col3", Config.Operation.Delete, true, DisplayName = "SWA- Database Policy defined for Delete fails")] + [DataRow("appService", "@claims.email eq @item.col3", Config.Operation.Delete, false, DisplayName = "AppService- Database Policy defined for Delete passes")] + public void TestInvalidClaimsForStaticWebApps(string authProvider, string dbPolicy, Config.Operation action, bool errorExpected) { RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, @@ -640,7 +640,7 @@ public void WildcardActionSpecifiedForARole() RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, roleName: AuthorizationHelpers.TEST_ROLE, - operation: Operation.All, + operation: Config.Operation.All, includedCols: new HashSet { "col1", "col2", "col3" } ); RuntimeConfigValidator configValidator = AuthenticationConfigValidatorUnitTests.GetMockConfigValidator(ref runtimeConfig); @@ -654,9 +654,9 @@ public void WildcardActionSpecifiedForARole() /// in it. /// [DataTestMethod] - [DataRow(Operation.Create, DisplayName = "Wildcard Field with another field in included set and create action")] - [DataRow(Operation.Update, DisplayName = "Wildcard Field with another field in included set and update action")] - public void WildCardAndOtherFieldsPresentInIncludeSet(Operation actionOp) + [DataRow(Config.Operation.Create, DisplayName = "Wildcard Field with another field in included set and create action")] + [DataRow(Config.Operation.Update, DisplayName = "Wildcard Field with another field in included set and update action")] + public void WildCardAndOtherFieldsPresentInIncludeSet(Config.Operation actionOp) { RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, @@ -677,9 +677,9 @@ public void WildCardAndOtherFieldsPresentInIncludeSet(Operation actionOp) } [DataTestMethod] - [DataRow(Operation.Create, DisplayName = "Wildcard Field with another field in excluded set and create action")] - [DataRow(Operation.Update, DisplayName = "Wildcard Field with another field in excluded set and update action")] - public void WildCardAndOtherFieldsPresentInExcludeSet(Operation actionOp) + [DataRow(Config.Operation.Create, DisplayName = "Wildcard Field with another field in excluded set and create action")] + [DataRow(Config.Operation.Update, DisplayName = "Wildcard Field with another field in excluded set and update action")] + public void WildCardAndOtherFieldsPresentInExcludeSet(Config.Operation actionOp) { RuntimeConfig runtimeConfig = AuthorizationHelpers.InitRuntimeConfig( entityName: AuthorizationHelpers.TEST_ENTITY, @@ -1135,7 +1135,7 @@ object graphQLdetails ) { PermissionOperation actionForRole = new( - Name: Operation.Create, + Name: Config.Operation.Create, Fields: null, Policy: null); diff --git a/src/Service.Tests/Unittests/RequestContextUnitTests.cs b/src/Service.Tests/Unittests/RequestContextUnitTests.cs index 5fe6ff52a3..b459af0b8f 100644 --- a/src/Service.Tests/Unittests/RequestContextUnitTests.cs +++ b/src/Service.Tests/Unittests/RequestContextUnitTests.cs @@ -39,7 +39,7 @@ public void ExceptionOnInsertPayloadFailDeserialization() InsertRequestContext context = new(entityName: string.Empty, dbo: _defaultDbObject, insertPayloadRoot: payload, - operationType: Operation.Insert); + operationType: Config.Operation.Insert); Assert.Fail(); } catch (DataApiBuilderException e) @@ -64,7 +64,7 @@ public void EmptyInsertPayloadTest() InsertRequestContext context = new(entityName: string.Empty, dbo: _defaultDbObject, insertPayloadRoot: payload, - operationType: Operation.Insert); + operationType: Config.Operation.Insert); Assert.AreEqual(0, context.FieldValuePairsInBody.Count); } } diff --git a/src/Service/Authorization/AuthorizationResolver.cs b/src/Service/Authorization/AuthorizationResolver.cs index ceba4d9d01..bd87f1306c 100644 --- a/src/Service/Authorization/AuthorizationResolver.cs +++ b/src/Service/Authorization/AuthorizationResolver.cs @@ -102,7 +102,7 @@ public bool IsValidRoleContext(HttpContext httpContext) } /// - public bool AreRoleAndOperationDefinedForEntity(string entityName, string roleName, Operation operation) + public bool AreRoleAndOperationDefinedForEntity(string entityName, string roleName, Config.Operation operation) { if (EntityPermissionsMap.TryGetValue(entityName, out EntityMetadata? valueOfEntityToRole)) { @@ -119,7 +119,7 @@ public bool AreRoleAndOperationDefinedForEntity(string entityName, string roleNa } /// - public bool AreColumnsAllowedForOperation(string entityName, string roleName, Operation operation, IEnumerable columns) + public bool AreColumnsAllowedForOperation(string entityName, string roleName, Config.Operation operation, IEnumerable columns) { // Columns.Count() will never be zero because this method is called after a check ensures Count() > 0 Assert.IsFalse(columns.Count() == 0, message: "columns.Count() should be greater than 0."); @@ -159,7 +159,7 @@ public bool AreColumnsAllowedForOperation(string entityName, string roleName, Op } /// - public string ProcessDBPolicy(string entityName, string roleName, Operation operation, HttpContext httpContext) + public string ProcessDBPolicy(string entityName, string roleName, Config.Operation operation, HttpContext httpContext) { string dBpolicyWithClaimTypes = GetDBPolicyForRequest(entityName, roleName, operation); @@ -184,7 +184,7 @@ public string ProcessDBPolicy(string entityName, string roleName, Operation oper /// Role defined in client role header. /// Operation type: create, read, update, delete. /// Policy string if a policy exists in config. - private string GetDBPolicyForRequest(string entityName, string roleName, Operation operation) + private string GetDBPolicyForRequest(string entityName, string roleName, Config.Operation operation) { if (!EntityPermissionsMap[entityName].RoleToOperationMap.TryGetValue(roleName, out RoleMetadata? roleMetadata)) { @@ -226,7 +226,7 @@ public void SetEntityPermissionMap(RuntimeConfig? runtimeConfig) object[] Operations = permission.Operations; foreach (JsonElement operationElement in Operations) { - Operation operation = Operation.None; + Config.Operation operation = Config.Operation.None; OperationMetadata operationToColumn = new(); // Use a hashset to store all the backing field names @@ -239,7 +239,7 @@ public void SetEntityPermissionMap(RuntimeConfig? runtimeConfig) if (operationElement.ValueKind is JsonValueKind.String) { string operationName = operationElement.ToString(); - operation = AuthorizationResolver.WILDCARD.Equals(operationName) ? Operation.All : Enum.Parse(operationName, ignoreCase: true); + operation = AuthorizationResolver.WILDCARD.Equals(operationName) ? Config.Operation.All : Enum.Parse(operationName, ignoreCase: true); operationToColumn.Included.UnionWith(allTableColumns); allowedColumns.UnionWith(allTableColumns); } @@ -302,8 +302,8 @@ public void SetEntityPermissionMap(RuntimeConfig? runtimeConfig) // so that it doesn't need to be evaluated per request. PopulateAllowedExposedColumns(operationToColumn.AllowedExposedColumns, entityName, allowedColumns); - IEnumerable operations = GetAllOperations(operation); - foreach (Operation crudOperation in operations) + IEnumerable operations = GetAllOperations(operation); + foreach (Config.Operation crudOperation in operations) { // Try to add the opElement to the map if not present. // Builds up mapping: i.e. Operation.Create permitted in {Role1, Role2, ..., RoleN} @@ -361,9 +361,9 @@ private static void CopyOverPermissionsFromAnonymousToAuthenticatedRole( entityToRoleMap.RoleToOperationMap[ROLE_AUTHENTICATED] = entityToRoleMap.RoleToOperationMap[ROLE_ANONYMOUS]; // Copy over OperationToRolesMap for authenticated role from anonymous role. - Dictionary allowedOperationMap = + Dictionary allowedOperationMap = entityToRoleMap.RoleToOperationMap[ROLE_ANONYMOUS].OperationToColumnMap; - foreach (Operation operation in allowedOperationMap.Keys) + foreach (Config.Operation operation in allowedOperationMap.Keys) { entityToRoleMap.OperationToRolesMap[operation].Add(ROLE_AUTHENTICATED); } @@ -371,9 +371,9 @@ private static void CopyOverPermissionsFromAnonymousToAuthenticatedRole( // Copy over FieldToRolesMap for authenticated role from anonymous role. foreach (string allowedColumnInAnonymousRole in allowedColumnsForAnonymousRole) { - Dictionary> allowedOperationsForField = + Dictionary> allowedOperationsForField = entityToRoleMap.FieldToRolesMap[allowedColumnInAnonymousRole]; - foreach (Operation operation in allowedOperationsForField.Keys) + foreach (Config.Operation operation in allowedOperationsForField.Keys) { if (allowedOperationsForField[operation].Contains(ROLE_ANONYMOUS)) { @@ -389,9 +389,9 @@ private static void CopyOverPermissionsFromAnonymousToAuthenticatedRole( /// /// operation type. /// IEnumerable of all available operations. - public static IEnumerable GetAllOperations(Operation operation) + public static IEnumerable GetAllOperations(Config.Operation operation) { - return operation is Operation.All ? PermissionOperation.ValidPermissionOperations : new List { operation }; + return operation is Config.Operation.All ? PermissionOperation.ValidPermissionOperations : new List { operation }; } /// @@ -420,7 +420,7 @@ private void PopulateAllowedExposedColumns(HashSet allowedExposedColumns } /// - public IEnumerable GetAllowedExposedColumns(string entityName, string roleName, Operation operation) + public IEnumerable GetAllowedExposedColumns(string entityName, string roleName, Config.Operation operation) { return EntityPermissionsMap[entityName].RoleToOperationMap[roleName].OperationToColumnMap[operation].AllowedExposedColumns; } @@ -590,7 +590,7 @@ public IEnumerable GetRolesForEntity(string entityName) /// Entity to lookup permissions /// Operation to lookup applicable roles /// Collection of roles. - public IEnumerable GetRolesForOperation(string entityName, Operation operation) + public IEnumerable GetRolesForOperation(string entityName, Config.Operation operation) { if (EntityPermissionsMap[entityName].OperationToRolesMap.TryGetValue(operation, out List? roleList) && roleList is not null) { @@ -608,7 +608,7 @@ public IEnumerable GetRolesForOperation(string entityName, Operation ope /// Field to lookup operation permissions /// Specific operation to get collection of roles /// Collection of role names allowed to perform operation on Entity's field. - public IEnumerable GetRolesForField(string entityName, string field, Operation operation) + public IEnumerable GetRolesForField(string entityName, string field, Config.Operation operation) { return EntityPermissionsMap[entityName].FieldToRolesMap[field][operation]; } @@ -638,14 +638,14 @@ private IEnumerable ResolveEntityDefinitionColumns(string entityName) /// There are only four possible operations /// /// - private static Dictionary> CreateOperationToRoleMap() + private static Dictionary> CreateOperationToRoleMap() { - return new Dictionary>() + return new Dictionary>() { - { Operation.Create, new List()}, - { Operation.Read, new List()}, - { Operation.Update, new List()}, - { Operation.Delete, new List()} + { Config.Operation.Create, new List()}, + { Config.Operation.Read, new List()}, + { Config.Operation.Update, new List()}, + { Config.Operation.Delete, new List()} }; } diff --git a/src/Service/Authorization/RestAuthorizationHandler.cs b/src/Service/Authorization/RestAuthorizationHandler.cs index 0a83055350..e11d1b9aac 100644 --- a/src/Service/Authorization/RestAuthorizationHandler.cs +++ b/src/Service/Authorization/RestAuthorizationHandler.cs @@ -4,7 +4,6 @@ using System.Net; using System.Threading.Tasks; using Azure.DataApiBuilder.Auth; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Models; using Microsoft.AspNetCore.Authorization; @@ -102,9 +101,9 @@ public Task HandleAsync(AuthorizationHandlerContext context) } string roleName = httpContext.Request.Headers[AuthorizationResolver.CLIENT_ROLE_HEADER]; - IEnumerable operations = HttpVerbToOperations(httpContext.Request.Method); + IEnumerable operations = HttpVerbToOperations(httpContext.Request.Method); - foreach (Operation operation in operations) + foreach (Config.Operation operation in operations) { bool isAuthorized = _authorizationResolver.AreRoleAndOperationDefinedForEntity(entityName, roleName, operation); if (!isAuthorized) @@ -142,12 +141,12 @@ public Task HandleAsync(AuthorizationHandlerContext context) string entityName = restContext.EntityName; string roleName = httpContext.Request.Headers[AuthorizationResolver.CLIENT_ROLE_HEADER]; - IEnumerable operations = HttpVerbToOperations(httpContext.Request.Method); + IEnumerable operations = HttpVerbToOperations(httpContext.Request.Method); // Delete operations do not have column level restrictions. // If the operation is allowed for the role, the column requirement is implicitly successful, // and the authorization check can be short circuited here. - if (operations.Count() == 1 && operations.Contains(Operation.Delete)) + if (operations.Count() == 1 && operations.Contains(Config.Operation.Delete)) { context.Succeed(requirement); return Task.CompletedTask; @@ -160,7 +159,7 @@ public Task HandleAsync(AuthorizationHandlerContext context) // otherwise, just one operation is checked. // PUT and PATCH resolve to operations 'Create' and 'Update'. // A user must fulfill all operations' permissions requirements to proceed. - foreach (Operation operation in operations) + foreach (Config.Operation operation in operations) { // Get a list of all columns present in a request that need to be authorized. IEnumerable columnsToCheck = restContext.CumulativeColumns; @@ -175,14 +174,14 @@ public Task HandleAsync(AuthorizationHandlerContext context) // Find operations with no column filter in the query string will have FieldsToBeReturned == 0. // Then, the "allowed columns" resolved, will be set on FieldsToBeReturned. // When FieldsToBeReturned is originally >=1 column, the field is NOT modified here. - if (restContext.FieldsToBeReturned.Count == 0 && restContext.OperationType == Operation.Read) + if (restContext.FieldsToBeReturned.Count == 0 && restContext.OperationType == Config.Operation.Read) { // Union performed to avoid duplicate field names in FieldsToBeReturned. IEnumerable fieldsReturnedForFind = _authorizationResolver.GetAllowedExposedColumns(entityName, roleName, operation); restContext.UpdateReturnFields(fieldsReturnedForFind); } } - else if (columnsToCheck.Count() == 0 && restContext.OperationType is Operation.Read) + else if (columnsToCheck.Count() == 0 && restContext.OperationType is Config.Operation.Read) { // - Find operations typically return all metadata of a database record. // This check resolves all 'included' columns defined in permissions @@ -220,19 +219,19 @@ public Task HandleAsync(AuthorizationHandlerContext context) /// /// /// A collection of Operation types resolved from the http verb type of the request. - private static IEnumerable HttpVerbToOperations(string httpVerb) + private static IEnumerable HttpVerbToOperations(string httpVerb) { switch (httpVerb) { case HttpConstants.POST: - return new List(new Operation[] { Operation.Create }); + return new List(new Config.Operation[] { Config.Operation.Create }); case HttpConstants.PUT: case HttpConstants.PATCH: - return new List(new Operation[] { Operation.Create, Operation.Update }); + return new List(new Config.Operation[] { Config.Operation.Create, Config.Operation.Update }); case HttpConstants.DELETE: - return new List(new Operation[] { Operation.Delete }); + return new List(new Config.Operation[] { Config.Operation.Delete }); case HttpConstants.GET: - return new List(new Operation[] { Operation.Read }); + return new List(new Config.Operation[] { Config.Operation.Read }); default: throw new DataApiBuilderException( message: "Unsupported operation type.", diff --git a/src/Service/Configurations/RuntimeConfigValidator.cs b/src/Service/Configurations/RuntimeConfigValidator.cs index 06cf1cc85b..d664c037af 100644 --- a/src/Service/Configurations/RuntimeConfigValidator.cs +++ b/src/Service/Configurations/RuntimeConfigValidator.cs @@ -341,7 +341,7 @@ public void ValidatePermissionsInConfig(RuntimeConfig runtimeConfig) { string roleName = permissionSetting.Role; Object[] actions = permissionSetting.Operations; - List operationsList = new(); + List operationsList = new(); foreach (Object action in actions) { if (action is null) @@ -350,16 +350,16 @@ public void ValidatePermissionsInConfig(RuntimeConfig runtimeConfig) } // Evaluate actionOp as the current operation to be validated. - Operation actionOp; + Config.Operation actionOp; JsonElement actionJsonElement = JsonSerializer.SerializeToElement(action); if ((actionJsonElement!).ValueKind is JsonValueKind.String) { string actionName = action.ToString()!; if (AuthorizationResolver.WILDCARD.Equals(actionName)) { - actionOp = Operation.All; + actionOp = Config.Operation.All; } - else if (!Enum.TryParse(actionName, ignoreCase: true, out actionOp) || + else if (!Enum.TryParse(actionName, ignoreCase: true, out actionOp) || !IsValidPermissionAction(actionOp)) { throw GetInvalidActionException(entityName, roleName, actionName); @@ -410,7 +410,7 @@ public void ValidatePermissionsInConfig(RuntimeConfig runtimeConfig) // If thats the case with both of them, we specify 'included' in error. string misconfiguredColumnSet = configOperation.Fields.Include.Contains(AuthorizationResolver.WILDCARD) && configOperation.Fields.Include.Count > 1 ? "included" : "excluded"; - string actionName = actionOp is Operation.All ? "*" : actionOp.ToString(); + string actionName = actionOp is Config.Operation.All ? "*" : actionOp.ToString(); throw new DataApiBuilderException( message: $"No other field can be present with wildcard in the {misconfiguredColumnSet} set for:" + $" entity:{entityName}, role:{permissionSetting.Role}, action:{actionName}", @@ -446,7 +446,7 @@ public void ValidatePermissionsInConfig(RuntimeConfig runtimeConfig) if (entity.ObjectType is SourceType.StoredProcedure) { if ((operationsList.Count > 1) - || (operationsList.Count is 1 && operationsList[0] is Operation.All)) + || (operationsList.Count is 1 && operationsList[0] is Config.Operation.All)) { throw new DataApiBuilderException( message: $"Invalid Operations for Entity: {entityName}. " + @@ -469,7 +469,7 @@ public void ValidatePermissionsInConfig(RuntimeConfig runtimeConfig) /// public bool IsValidDatabasePolicyForAction(PermissionOperation permission) { - return !(permission.Policy?.Database != null && permission.Name == Operation.Create); + return !(permission.Policy?.Database != null && permission.Name == Config.Operation.Create); } /// @@ -599,7 +599,7 @@ public void ValidateStoredProceduresInConfig(RuntimeConfig runtimeConfig, ISqlMe entityName, dbObject, JsonSerializer.SerializeToElement(entity.Parameters), - Operation.All); + Config.Operation.All); try { RequestValidator.ValidateStoredProcedureRequestContext(sqRequestContext, sqlMetadataProvider); @@ -809,9 +809,9 @@ private static DataApiBuilderException GetInvalidActionException(string entityNa /// /// /// Boolean value indicating whether the action is valid or not. - public static bool IsValidPermissionAction(Operation action) + public static bool IsValidPermissionAction(Config.Operation action) { - return action is Operation.All || PermissionOperation.ValidPermissionOperations.Contains(action); + return action is Config.Operation.All || PermissionOperation.ValidPermissionOperations.Contains(action); } } } diff --git a/src/Service/Controllers/RestController.cs b/src/Service/Controllers/RestController.cs index 0d62cf61bf..0f4abf9846 100644 --- a/src/Service/Controllers/RestController.cs +++ b/src/Service/Controllers/RestController.cs @@ -1,7 +1,6 @@ using System; using System.Net; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Services; using Microsoft.AspNetCore.Http; @@ -85,7 +84,7 @@ public async Task Find( { return await HandleOperation( route, - Operation.Read); + Config.Operation.Read); } /// @@ -103,7 +102,7 @@ public async Task Insert( { return await HandleOperation( route, - Operation.Insert); + Config.Operation.Insert); } /// @@ -123,7 +122,7 @@ public async Task Delete( { return await HandleOperation( route, - Operation.Delete); + Config.Operation.Delete); } /// @@ -143,7 +142,7 @@ public async Task Upsert( { return await HandleOperation( route, - DeterminePatchPutSemantics(Operation.Upsert)); + DeterminePatchPutSemantics(Config.Operation.Upsert)); } /// @@ -163,7 +162,7 @@ public async Task UpsertIncremental( { return await HandleOperation( route, - DeterminePatchPutSemantics(Operation.UpsertIncremental)); + DeterminePatchPutSemantics(Config.Operation.UpsertIncremental)); } /// @@ -173,7 +172,7 @@ public async Task UpsertIncremental( /// The kind of operation to handle. private async Task HandleOperation( string route, - Operation operationType) + Config.Operation operationType) { try { @@ -253,7 +252,7 @@ private async Task HandleOperation( /// /// opertion to be used. /// correct opertion based on headers. - private Operation DeterminePatchPutSemantics(Operation operation) + private Config.Operation DeterminePatchPutSemantics(Config.Operation operation) { if (HttpContext.Request.Headers.ContainsKey("If-Match")) @@ -267,11 +266,11 @@ private Operation DeterminePatchPutSemantics(Operation operation) switch (operation) { - case Operation.Upsert: - operation = Operation.Update; + case Config.Operation.Upsert: + operation = Config.Operation.Update; break; - case Operation.UpsertIncremental: - operation = Operation.UpdateIncremental; + case Config.Operation.UpsertIncremental: + operation = Config.Operation.UpdateIncremental; break; } } diff --git a/src/Service/Models/CosmosOperationMetadata.cs b/src/Service/Models/CosmosOperationMetadata.cs index d5f9bcaa56..5d9bb4d0a5 100644 --- a/src/Service/Models/CosmosOperationMetadata.cs +++ b/src/Service/Models/CosmosOperationMetadata.cs @@ -1,5 +1,3 @@ -using Azure.DataApiBuilder.Config; - namespace Azure.DataApiBuilder.Service.Models { /// @@ -8,5 +6,5 @@ namespace Azure.DataApiBuilder.Service.Models /// Name of the database /// Name of the container /// Type of operation to perform - record CosmosOperationMetadata(string DatabaseName, string ContainerName, Operation OperationType); + record CosmosOperationMetadata(string DatabaseName, string ContainerName, Config.Operation OperationType); } diff --git a/src/Service/Models/MutationResolver.cs b/src/Service/Models/MutationResolver.cs index 6864959088..86e9ede1c1 100644 --- a/src/Service/Models/MutationResolver.cs +++ b/src/Service/Models/MutationResolver.cs @@ -1,5 +1,3 @@ -using Azure.DataApiBuilder.Config; - namespace Azure.DataApiBuilder.Service.Models { public record MutationResolver(string Id, Operation OperationType, string DatabaseName, string ContainerName, string Fields, string Table); diff --git a/src/Service/Models/RestRequestContexts/DeleteRequestContext.cs b/src/Service/Models/RestRequestContexts/DeleteRequestContext.cs index cb1685e9f9..61996798ac 100644 --- a/src/Service/Models/RestRequestContexts/DeleteRequestContext.cs +++ b/src/Service/Models/RestRequestContexts/DeleteRequestContext.cs @@ -18,7 +18,7 @@ public DeleteRequestContext(string entityName, DatabaseObject dbo, bool isList) PrimaryKeyValuePairs = new(); FieldValuePairsInBody = new(); IsMany = isList; - OperationType = Operation.Delete; + OperationType = Config.Operation.Delete; } } } diff --git a/src/Service/Models/RestRequestContexts/FindRequestContext.cs b/src/Service/Models/RestRequestContexts/FindRequestContext.cs index e7ab5022b7..8d175c1dd7 100644 --- a/src/Service/Models/RestRequestContexts/FindRequestContext.cs +++ b/src/Service/Models/RestRequestContexts/FindRequestContext.cs @@ -19,7 +19,7 @@ public FindRequestContext(string entityName, DatabaseObject dbo, bool isList) PrimaryKeyValuePairs = new(); FieldValuePairsInBody = new(); IsMany = isList; - OperationType = Operation.Read; + OperationType = Config.Operation.Read; } } diff --git a/src/Service/Models/RestRequestContexts/InsertRequestContext.cs b/src/Service/Models/RestRequestContexts/InsertRequestContext.cs index 30617ff73b..9ef5c52ced 100644 --- a/src/Service/Models/RestRequestContexts/InsertRequestContext.cs +++ b/src/Service/Models/RestRequestContexts/InsertRequestContext.cs @@ -16,7 +16,7 @@ public InsertRequestContext( string entityName, DatabaseObject dbo, JsonElement insertPayloadRoot, - Operation operationType) + Config.Operation operationType) : base(entityName, dbo) { FieldsToBeReturned = new(); diff --git a/src/Service/Models/RestRequestContexts/RestRequestContext.cs b/src/Service/Models/RestRequestContexts/RestRequestContext.cs index 72b00d4195..07c2ee7632 100644 --- a/src/Service/Models/RestRequestContexts/RestRequestContext.cs +++ b/src/Service/Models/RestRequestContexts/RestRequestContext.cs @@ -101,7 +101,7 @@ protected RestRequestContext(string entityName, DatabaseObject dbo) /// /// The database engine operation type this request is. /// - public Operation OperationType { get; set; } + public Config.Operation OperationType { get; set; } /// /// A collection of all unique column names present in the request. diff --git a/src/Service/Models/RestRequestContexts/StoredProcedureRequestContext.cs b/src/Service/Models/RestRequestContexts/StoredProcedureRequestContext.cs index bae8791b39..ff092db13b 100644 --- a/src/Service/Models/RestRequestContexts/StoredProcedureRequestContext.cs +++ b/src/Service/Models/RestRequestContexts/StoredProcedureRequestContext.cs @@ -24,7 +24,7 @@ public StoredProcedureRequestContext( string entityName, DatabaseObject dbo, JsonElement? requestPayloadRoot, - Operation operationType) + Config.Operation operationType) : base(entityName, dbo) { FieldsToBeReturned = new(); @@ -40,7 +40,7 @@ public StoredProcedureRequestContext( /// public void PopulateResolvedParameters() { - if (OperationType is Operation.Read) + if (OperationType is Config.Operation.Read) { // Query string may have malformed/null keys, if so just ignore them ResolvedParameters = ParsedQueryString.Cast() diff --git a/src/Service/Models/RestRequestContexts/UpsertRequestContext.cs b/src/Service/Models/RestRequestContexts/UpsertRequestContext.cs index f862a8a08e..ee460ef331 100644 --- a/src/Service/Models/RestRequestContexts/UpsertRequestContext.cs +++ b/src/Service/Models/RestRequestContexts/UpsertRequestContext.cs @@ -16,7 +16,7 @@ public UpsertRequestContext( string entityName, DatabaseObject dbo, JsonElement insertPayloadRoot, - Operation operationType) + Config.Operation operationType) : base(entityName, dbo) { FieldsToBeReturned = new(); diff --git a/src/Service/Resolvers/AuthorizationPolicyHelpers.cs b/src/Service/Resolvers/AuthorizationPolicyHelpers.cs index 70821e554c..e5cb562ec7 100644 --- a/src/Service/Resolvers/AuthorizationPolicyHelpers.cs +++ b/src/Service/Resolvers/AuthorizationPolicyHelpers.cs @@ -1,5 +1,4 @@ using Azure.DataApiBuilder.Auth; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Authorization; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Parsers; @@ -28,7 +27,7 @@ public static class AuthorizationPolicyHelpers /// Used to lookup authorization policies. /// Provides helper method to process ODataFilterClause. public static void ProcessAuthorizationPolicies( - Operation operationType, + Config.Operation operationType, BaseSqlQueryStructure queryStructure, HttpContext context, IAuthorizationResolver authorizationResolver, diff --git a/src/Service/Resolvers/CosmosMutationEngine.cs b/src/Service/Resolvers/CosmosMutationEngine.cs index eb61ad6671..d1379fc7b5 100644 --- a/src/Service/Resolvers/CosmosMutationEngine.cs +++ b/src/Service/Resolvers/CosmosMutationEngine.cs @@ -4,7 +4,6 @@ using System.Net; using System.Text.Json; using System.Threading.Tasks; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.GraphQLBuilder.Mutations; using Azure.DataApiBuilder.Service.GraphQLBuilder.Queries; @@ -57,9 +56,9 @@ private async Task ExecuteAsync(IDictionary queryArgs, ItemResponse? response = resolver.OperationType switch { - Operation.UpdateGraphQL => await HandleUpdateAsync(queryArgs, container), - Operation.Create => await HandleCreateAsync(queryArgs, container), - Operation.Delete => await HandleDeleteAsync(queryArgs, container), + Config.Operation.UpdateGraphQL => await HandleUpdateAsync(queryArgs, container), + Config.Operation.Create => await HandleCreateAsync(queryArgs, container), + Config.Operation.Delete => await HandleDeleteAsync(queryArgs, container), _ => throw new NotSupportedException($"unsupported operation type: {resolver.OperationType}") }; @@ -236,7 +235,7 @@ public async Task> ExecuteAsync(IMiddlewareContex string containerName = _metadataProvider.GetDatabaseObjectName(entityName); string graphqlMutationName = context.Selection.Field.Name.Value; - Operation mutationOperation = + Config.Operation mutationOperation = MutationBuilder.DetermineMutationOperationTypeBasedOnInputType(graphqlMutationName); CosmosOperationMetadata mutation = new(databaseName, containerName, mutationOperation); diff --git a/src/Service/Resolvers/Sql Query Structures/SqlQueryStructure.cs b/src/Service/Resolvers/Sql Query Structures/SqlQueryStructure.cs index 380002c13f..1747c3796a 100644 --- a/src/Service/Resolvers/Sql Query Structures/SqlQueryStructure.cs +++ b/src/Service/Resolvers/Sql Query Structures/SqlQueryStructure.cs @@ -354,7 +354,7 @@ private SqlQueryStructure( HttpContext httpContext = (HttpContext)httpContextValue!; // Process Authorization Policy of the entity being processed. - AuthorizationPolicyHelpers.ProcessAuthorizationPolicies(Operation.Read, queryStructure: this, httpContext, authorizationResolver, sqlMetadataProvider); + AuthorizationPolicyHelpers.ProcessAuthorizationPolicies(Config.Operation.Read, queryStructure: this, httpContext, authorizationResolver, sqlMetadataProvider); if (outputType.IsNonNullType()) { diff --git a/src/Service/Resolvers/SqlExistsQueryStructure.cs b/src/Service/Resolvers/SqlExistsQueryStructure.cs index 1ec2a2897c..dba7ae231a 100644 --- a/src/Service/Resolvers/SqlExistsQueryStructure.cs +++ b/src/Service/Resolvers/SqlExistsQueryStructure.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Azure.DataApiBuilder.Auth; -using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Service.Exceptions; using Azure.DataApiBuilder.Service.Models; using Azure.DataApiBuilder.Service.Services; @@ -48,7 +47,7 @@ public SqlExistsQueryStructure( // This adds any required DBPolicyPredicates to this Exists query structure. AuthorizationPolicyHelpers.ProcessAuthorizationPolicies( - Operation.Read, + Config.Operation.Read, queryStructure: this, httpContext, authorizationResolver, diff --git a/src/Service/Resolvers/SqlMutationEngine.cs b/src/Service/Resolvers/SqlMutationEngine.cs index 0861aec793..01a43a5466 100644 --- a/src/Service/Resolvers/SqlMutationEngine.cs +++ b/src/Service/Resolvers/SqlMutationEngine.cs @@ -86,13 +86,13 @@ public async Task> ExecuteAsync(IMiddlewareContex } Tuple? result = null; - Operation mutationOperation = + Config.Operation mutationOperation = MutationBuilder.DetermineMutationOperationTypeBasedOnInputType(graphqlMutationName); // If authorization fails, an exception will be thrown and request execution halts. AuthorizeMutationFields(context, parameters, entityName, mutationOperation); - if (mutationOperation is Operation.Delete) + if (mutationOperation is Config.Operation.Delete) { // compute the mutation result before removing the element, // since typical GraphQL delete mutations return the metadata of the deleted item. @@ -175,10 +175,10 @@ await _queryExecutor.ExecuteQueryAsync( // to each action, with data always from the first result set, as there may be arbitrarily many. switch (context.OperationType) { - case Operation.Delete: + case Config.Operation.Delete: // Returns a 204 No Content so long as the stored procedure executes without error return new NoContentResult(); - case Operation.Insert: + case Config.Operation.Insert: // Returns a 201 Created with whatever the first result set is returned from the procedure // A "correctly" configured stored procedure would INSERT INTO ... OUTPUT ... VALUES as the first and only result set if (resultRowAndProperties is not null && @@ -196,10 +196,10 @@ await _queryExecutor.ExecuteQueryAsync( } ); } - case Operation.Update: - case Operation.UpdateIncremental: - case Operation.Upsert: - case Operation.UpsertIncremental: + case Config.Operation.Update: + case Config.Operation.UpdateIncremental: + case Config.Operation.Upsert: + case Config.Operation.UpsertIncremental: // Since we cannot check if anything was created, just return a 200 Ok response with first result set output // A "correctly" configured stored procedure would UPDATE ... SET ... OUTPUT as the first and only result set if (resultRowAndProperties is not null && @@ -235,7 +235,7 @@ await _queryExecutor.ExecuteQueryAsync( { Dictionary parameters = PrepareParameters(context); - if (context.OperationType is Operation.Delete) + if (context.OperationType is Config.Operation.Delete) { Dictionary? resultProperties = await PerformDeleteOperation( @@ -251,7 +251,7 @@ await PerformDeleteOperation( return new NoContentResult(); } } - else if (context.OperationType is Operation.Upsert || context.OperationType is Operation.UpsertIncremental) + else if (context.OperationType is Config.Operation.Upsert || context.OperationType is Config.Operation.UpsertIncremental) { Tuple?, Dictionary>? resultRowAndProperties = await PerformUpsertOperation( @@ -292,7 +292,7 @@ await PerformMutationOperation( context.OperationType, parameters); - if (context.OperationType is Operation.Insert) + if (context.OperationType is Config.Operation.Insert) { if (resultRowAndProperties is null || resultRowAndProperties.Item1 is null) { @@ -307,7 +307,7 @@ await PerformMutationOperation( return new CreatedResult(location: primaryKeyRoute, OkMutationResponse(resultRow).Value); } - if (context.OperationType is Operation.Update || context.OperationType is Operation.UpdateIncremental) + if (context.OperationType is Config.Operation.Update || context.OperationType is Config.Operation.UpdateIncremental) { // Nothing to update means we throw Exception if (resultRowAndProperties is null || @@ -362,7 +362,7 @@ private static OkObjectResult OkMutationResponse(Dictionary? re private async Task?, Dictionary>?> PerformMutationOperation( string entityName, - Operation operationType, + Config.Operation operationType, IDictionary parameters, IMiddlewareContext? context = null) { @@ -370,8 +370,8 @@ private static OkObjectResult OkMutationResponse(Dictionary? re Dictionary queryParameters; switch (operationType) { - case Operation.Insert: - case Operation.Create: + case Config.Operation.Insert: + case Config.Operation.Create: SqlInsertStructure insertQueryStruct = context is null ? new( entityName, @@ -388,7 +388,7 @@ private static OkObjectResult OkMutationResponse(Dictionary? re queryString = _queryBuilder.Build(insertQueryStruct); queryParameters = insertQueryStruct.Parameters; break; - case Operation.Update: + case Config.Operation.Update: SqlUpdateStructure updateStructure = new( entityName, _sqlMetadataProvider, @@ -399,7 +399,7 @@ private static OkObjectResult OkMutationResponse(Dictionary? re queryString = _queryBuilder.Build(updateStructure); queryParameters = updateStructure.Parameters; break; - case Operation.UpdateIncremental: + case Config.Operation.UpdateIncremental: SqlUpdateStructure updateIncrementalStructure = new( entityName, _sqlMetadataProvider, @@ -410,7 +410,7 @@ private static OkObjectResult OkMutationResponse(Dictionary? re queryString = _queryBuilder.Build(updateIncrementalStructure); queryParameters = updateIncrementalStructure.Parameters; break; - case Operation.UpdateGraphQL: + case Config.Operation.UpdateGraphQL: if (context is null) { throw new ArgumentNullException("Context should not be null for a GraphQL operation."); @@ -424,7 +424,7 @@ private static OkObjectResult OkMutationResponse(Dictionary? re _gQLFilterParser, parameters); AuthorizationPolicyHelpers.ProcessAuthorizationPolicies( - Operation.Update, + Config.Operation.Update, updateGraphQLStructure, _httpContextAccessor.HttpContext!, _authorizationResolver, @@ -501,7 +501,7 @@ private async Task?> _gQLFilterParser, parameters); AuthorizationPolicyHelpers.ProcessAuthorizationPolicies( - Operation.Delete, + Config.Operation.Delete, deleteStructure, _httpContextAccessor.HttpContext!, _authorizationResolver, @@ -536,10 +536,10 @@ private async Task?> { string queryString; Dictionary queryParameters; - Operation operationType = context.OperationType; + Config.Operation operationType = context.OperationType; string entityName = context.EntityName; - if (operationType is Operation.Upsert) + if (operationType is Config.Operation.Upsert) { SqlUpsertQueryStructure upsertStructure = new( entityName, @@ -618,14 +618,14 @@ public string ConstructPrimaryKeyRoute(RestRequestContext context, Dictionary parameters, string entityName, - Operation mutationOperation) + Config.Operation mutationOperation) { string role = string.Empty; if (context.ContextData.TryGetValue(key: AuthorizationResolver.CLIENT_ROLE_HEADER, out object? value)) @@ -686,7 +686,7 @@ public void AuthorizeMutationFields( } List inputArgumentKeys; - if (mutationOperation != Operation.Delete) + if (mutationOperation != Config.Operation.Delete) { inputArgumentKeys = BaseSqlQueryStructure.GetSubArgumentNamesFromGQLMutArguments(MutationBuilder.INPUT_ARGUMENT_NAME, parameters); } @@ -699,13 +699,13 @@ public void AuthorizeMutationFields( switch (mutationOperation) { - case Operation.UpdateGraphQL: - isAuthorized = _authorizationResolver.AreColumnsAllowedForOperation(entityName, roleName: role, operation: Operation.Update, inputArgumentKeys); + case Config.Operation.UpdateGraphQL: + isAuthorized = _authorizationResolver.AreColumnsAllowedForOperation(entityName, roleName: role, operation: Config.Operation.Update, inputArgumentKeys); break; - case Operation.Create: - isAuthorized = _authorizationResolver.AreColumnsAllowedForOperation(entityName, roleName: role, operation: Operation.Create, inputArgumentKeys); + case Config.Operation.Create: + isAuthorized = _authorizationResolver.AreColumnsAllowedForOperation(entityName, roleName: role, operation: Config.Operation.Create, inputArgumentKeys); break; - case Operation.Delete: + case Config.Operation.Delete: // Delete operations are not checked for authorization on field level, // and instead at the mutation level and would be rejected before this time in the pipeline. // Continuing on with operation. diff --git a/src/Service/Resolvers/SqlQueryEngine.cs b/src/Service/Resolvers/SqlQueryEngine.cs index 8a43c12474..a6c5522096 100644 --- a/src/Service/Resolvers/SqlQueryEngine.cs +++ b/src/Service/Resolvers/SqlQueryEngine.cs @@ -108,7 +108,7 @@ public async Task, IMetadata>> ExecuteListAsync( // checking if role has read permission on the result _authorizationResolver.EntityPermissionsMap.TryGetValue(context.Field.Name.Value, out EntityMetadata entityMetadata); string role = context.ContextData[CLIENT_ROLE_HEADER].ToString(); - bool IsReadAllowed = entityMetadata.RoleToOperationMap[role].OperationToColumnMap.ContainsKey(Operation.Read); + bool IsReadAllowed = entityMetadata.RoleToOperationMap[role].OperationToColumnMap.ContainsKey(Config.Operation.Read); return new Tuple, IMetadata>( FormatStoredProcedureResultAsJsonList(IsReadAllowed, await ExecuteAsync(sqlExecuteStructure)), diff --git a/src/Service/Services/GraphQLSchemaCreator.cs b/src/Service/Services/GraphQLSchemaCreator.cs index bed327e6ee..bcd4091496 100644 --- a/src/Service/Services/GraphQLSchemaCreator.cs +++ b/src/Service/Services/GraphQLSchemaCreator.cs @@ -149,7 +149,7 @@ DatabaseType.postgresql or foreach (string column in sourceDefinition.Columns.Keys) { - IEnumerable roles = _authorizationResolver.GetRolesForField(entityName, field: column, operation: Operation.Read); + IEnumerable roles = _authorizationResolver.GetRolesForField(entityName, field: column, operation: Config.Operation.Read); if (!rolesAllowedForFields.TryAdd(key: column, value: roles)) { throw new DataApiBuilderException( diff --git a/src/Service/Services/RequestValidator.cs b/src/Service/Services/RequestValidator.cs index c842421e5b..85bea062fb 100644 --- a/src/Service/Services/RequestValidator.cs +++ b/src/Service/Services/RequestValidator.cs @@ -385,7 +385,7 @@ public static void ValidateUpsertRequestContext( } } - bool isReplacementUpdate = (upsertRequestCtx.OperationType == Operation.Upsert) ? true : false; + bool isReplacementUpdate = (upsertRequestCtx.OperationType == Config.Operation.Upsert) ? true : false; if (ValidateColumn(column.Value, exposedName!, fieldsInRequestBody, isReplacementUpdate)) { unValidatedFields.Remove(exposedName!); diff --git a/src/Service/Services/RestService.cs b/src/Service/Services/RestService.cs index b658918b15..3c32a77d38 100644 --- a/src/Service/Services/RestService.cs +++ b/src/Service/Services/RestService.cs @@ -59,7 +59,7 @@ RuntimeConfigProvider runtimeConfigProvider /// The primary key route. e.g. customerName/Xyz/saleOrderId/123 public async Task ExecuteAsync( string entityName, - Operation operationType, + Config.Operation operationType, string? primaryKeyRoute) { RequestValidator.ValidateEntity(entityName, _sqlMetadataProvider.EntityToDatabaseObject.Keys); @@ -93,13 +93,13 @@ RuntimeConfigProvider runtimeConfigProvider { switch (operationType) { - case Operation.Read: + case Config.Operation.Read: context = new FindRequestContext( entityName, dbo: dbObject, isList: string.IsNullOrEmpty(primaryKeyRoute)); break; - case Operation.Insert: + case Config.Operation.Insert: JsonElement insertPayloadRoot = RequestValidator.ValidateInsertRequest(queryString, requestBody); context = new InsertRequestContext( entityName, @@ -114,16 +114,16 @@ RuntimeConfigProvider runtimeConfigProvider } break; - case Operation.Delete: + case Config.Operation.Delete: RequestValidator.ValidateDeleteRequest(primaryKeyRoute); context = new DeleteRequestContext(entityName, dbo: dbObject, isList: false); break; - case Operation.Update: - case Operation.UpdateIncremental: - case Operation.Upsert: - case Operation.UpsertIncremental: + case Config.Operation.Update: + case Config.Operation.UpdateIncremental: + case Config.Operation.Upsert: + case Config.Operation.UpsertIncremental: JsonElement upsertPayloadRoot = RequestValidator.ValidateUpdateOrUpsertRequest(primaryKeyRoute, requestBody); context = new UpsertRequestContext( entityName, @@ -160,7 +160,7 @@ RuntimeConfigProvider runtimeConfigProvider } string role = GetHttpContext().Request.Headers[AuthorizationResolver.CLIENT_ROLE_HEADER]; - Operation operation = HttpVerbToOperations(GetHttpContext().Request.Method); + Config.Operation operation = HttpVerbToOperations(GetHttpContext().Request.Method); string dbPolicy = _authorizationResolver.ProcessDBPolicy(entityName, role, operation, GetHttpContext()); if (!string.IsNullOrEmpty(dbPolicy)) { @@ -189,14 +189,14 @@ RuntimeConfigProvider runtimeConfigProvider switch (operationType) { - case Operation.Read: + case Config.Operation.Read: return await DispatchQuery(context); - case Operation.Insert: - case Operation.Delete: - case Operation.Update: - case Operation.UpdateIncremental: - case Operation.Upsert: - case Operation.UpsertIncremental: + case Config.Operation.Insert: + case Config.Operation.Delete: + case Config.Operation.Update: + case Config.Operation.UpdateIncremental: + case Config.Operation.Upsert: + case Config.Operation.UpsertIncremental: return await DispatchMutation(context); default: throw new NotSupportedException("This operation is not yet supported."); @@ -233,7 +233,7 @@ private Task DispatchQuery(RestRequestContext context) /// /// Helper method to populate the context in case the database object for this request is a stored procedure /// - private void PopulateStoredProcedureContext(Operation operationType, + private void PopulateStoredProcedureContext(Config.Operation operationType, DatabaseObject dbObject, string entityName, string queryString, @@ -244,7 +244,7 @@ private void PopulateStoredProcedureContext(Operation operationType, switch (operationType) { - case Operation.Read: + case Config.Operation.Read: // Parameters passed in query string, request body is ignored for find requests context = new StoredProcedureRequestContext( entityName, @@ -262,12 +262,12 @@ private void PopulateStoredProcedureContext(Operation operationType, } break; - case Operation.Insert: - case Operation.Delete: - case Operation.Update: - case Operation.UpdateIncremental: - case Operation.Upsert: - case Operation.UpsertIncremental: + case Config.Operation.Insert: + case Config.Operation.Delete: + case Config.Operation.Update: + case Config.Operation.UpdateIncremental: + case Config.Operation.Upsert: + case Config.Operation.UpsertIncremental: // Stored procedure call is semantically identical for all methods except Find, so we can // effectively reuse the ValidateInsertRequest - throws error if query string is nonempty // and parses the body into json @@ -393,21 +393,21 @@ public async Task AuthorizationCheckForRequirementAsync(object? resource, IAutho /// /// /// The CRUD operation for the given httpverb. - public static Operation HttpVerbToOperations(string httpVerbName) + public static Config.Operation HttpVerbToOperations(string httpVerbName) { switch (httpVerbName) { case "POST": - return Operation.Create; + return Config.Operation.Create; case "PUT": case "PATCH": // Please refer to the use of this method, which is to look out for policy based on crud operation type. // Since create doesn't have filter predicates, PUT/PATCH would resolve to update operation. - return Operation.Update; + return Config.Operation.Update; case "DELETE": - return Operation.Delete; + return Config.Operation.Delete; case "GET": - return Operation.Read; + return Config.Operation.Read; default: throw new DataApiBuilderException( message: "Unsupported operation type.",