From 60dd852afb8b99e2959d37d9dcb925d55c9ccebb Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Fri, 16 Aug 2024 11:41:11 +0200 Subject: [PATCH 01/13] pp --- Dockerfile | 2 +- src/Service/.config/dotnet-tools.json | 5 ++++ .../Azure.DataApiBuilder.Service.csproj | 5 +++- .../PublishProfiles/crweudev01.pubxml | 30 +++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/Service/.config/dotnet-tools.json create mode 100644 src/Service/Properties/PublishProfiles/crweudev01.pubxml diff --git a/Dockerfile b/Dockerfile index d6d950733c..e05ba35327 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0. AS build WORKDIR /src COPY [".", "./"] -RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64 +RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -f net8.0 -o /out -r linux-x64 --self-contained FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS runtime diff --git a/src/Service/.config/dotnet-tools.json b/src/Service/.config/dotnet-tools.json new file mode 100644 index 0000000000..b0e38abdac --- /dev/null +++ b/src/Service/.config/dotnet-tools.json @@ -0,0 +1,5 @@ +{ + "version": 1, + "isRoot": true, + "tools": {} +} \ No newline at end of file diff --git a/src/Service/Azure.DataApiBuilder.Service.csproj b/src/Service/Azure.DataApiBuilder.Service.csproj index 7d41aaef28..bcf03928b4 100644 --- a/src/Service/Azure.DataApiBuilder.Service.csproj +++ b/src/Service/Azure.DataApiBuilder.Service.csproj @@ -36,6 +36,10 @@ True + + True + + $(CopyToOutputDirectoryAction) @@ -45,7 +49,6 @@ - diff --git a/src/Service/Properties/PublishProfiles/crweudev01.pubxml b/src/Service/Properties/PublishProfiles/crweudev01.pubxml new file mode 100644 index 0000000000..a785ab2cac --- /dev/null +++ b/src/Service/Properties/PublishProfiles/crweudev01.pubxml @@ -0,0 +1,30 @@ + + + + + Container + NetSdk + /subscriptions/d81425a2-a8ea-4ea4-9bdd-ca9db5cdfbc6/resourceGroups/rg-weu-api/providers/Microsoft.ContainerRegistry/registries/crweudev01 + crweudev01 + rg-weu-api + sub-mdm-weu-dev + crweudev01.azurecr.io + + latest + ContainerRegistry + Release + Any CPU + linux-x64 + 208fc26c-a21c-4c96-98ee-f10fdaeac508 + <_TargetId>NetSdkAzureContainerRegistry + + true + false + net8.0 + true + true + true + + \ No newline at end of file From 0d86a3fcc9e49b42b8761538c63ebe26f86a822b Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Tue, 20 Aug 2024 22:18:09 +0200 Subject: [PATCH 02/13] Preserve original roles claim and allow session context updates Added a new constant `ORIGINAL_ROLE_CLAIM_TYPE` in `AuthenticationOptions.cs` to store the original roles claim type. Modified `AuthorizationResolver` to preserve the original 'roles' claim by adding it to the `resolvedClaims` dictionary under the new key. Changed `MsSqlQueryExecutor` to set session context parameters with `@read_only = 0` to allow modifications. --- src/Config/ObjectModel/AuthenticationOptions.cs | 1 + src/Core/Authorization/AuthorizationResolver.cs | 7 ++++++- src/Core/Resolvers/MsSqlQueryExecutor.cs | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Config/ObjectModel/AuthenticationOptions.cs b/src/Config/ObjectModel/AuthenticationOptions.cs index 189540fbe6..6750d6e807 100644 --- a/src/Config/ObjectModel/AuthenticationOptions.cs +++ b/src/Config/ObjectModel/AuthenticationOptions.cs @@ -17,6 +17,7 @@ public record AuthenticationOptions(string Provider = nameof(EasyAuthType.Static public const string CLIENT_PRINCIPAL_HEADER = "X-MS-CLIENT-PRINCIPAL"; public const string NAME_CLAIM_TYPE = "name"; public const string ROLE_CLAIM_TYPE = "roles"; + public const string ORIGINAL_ROLE_CLAIM_TYPE = "original_roles"; /// /// Returns whether the configured Provider matches an diff --git a/src/Core/Authorization/AuthorizationResolver.cs b/src/Core/Authorization/AuthorizationResolver.cs index 2ab6e70a4c..10442fd948 100644 --- a/src/Core/Authorization/AuthorizationResolver.cs +++ b/src/Core/Authorization/AuthorizationResolver.cs @@ -617,9 +617,14 @@ public static Dictionary> GetAllAuthenticatedUserClaims(Http // into a list and storing that in resolvedClaims using the claimType as the key. foreach (Claim claim in identity.Claims) { - // 'roles' claim has already been processed. + // 'roles' claim has already been processed. But we preserve the original 'roles' claim if (claim.Type.Equals(AuthenticationOptions.ROLE_CLAIM_TYPE)) { + if(!resolvedClaims.TryAdd(AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE, new List() { claim })) + { + resolvedClaims[AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE].Add(claim); + } + continue; } diff --git a/src/Core/Resolvers/MsSqlQueryExecutor.cs b/src/Core/Resolvers/MsSqlQueryExecutor.cs index 45d641bb32..9b22eeb591 100644 --- a/src/Core/Resolvers/MsSqlQueryExecutor.cs +++ b/src/Core/Resolvers/MsSqlQueryExecutor.cs @@ -282,9 +282,9 @@ public override string GetSessionParamsQuery(HttpContext? httpContext, IDictiona foreach ((string claimType, string claimValue) in sessionParams) { string paramName = $"{SESSION_PARAM_NAME}{counter.Next()}"; - parameters.Add(paramName, new(claimValue)); + parameters.Add(paramName, new(claimValue)); // Append statement to set read only param value - can be set only once for a connection. - string statementToSetReadOnlyParam = "EXEC sp_set_session_context " + $"'{claimType}', " + paramName + ", @read_only = 1;"; + string statementToSetReadOnlyParam = "EXEC sp_set_session_context " + $"'{claimType}', " + paramName + ", @read_only = 0;"; sessionMapQuery = sessionMapQuery.Append(statementToSetReadOnlyParam); } From bc468edb69458a11417e48122e003679014e7c8e Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Tue, 20 Aug 2024 22:38:54 +0200 Subject: [PATCH 03/13] Revert "pp" This reverts commit 08f741c41ddae4d6ca0ad8e849cb5b727554d1f2. --- Dockerfile | 2 +- src/Auth/Azure.DataApiBuilder.Auth.csproj | 2 +- src/Cli.Tests/Cli.Tests.csproj | 2 +- src/Cli/Cli.csproj | 2 +- src/Config/Azure.DataApiBuilder.Config.csproj | 2 +- src/Core/Azure.DataApiBuilder.Core.csproj | 2 +- .../Azure.DataApiBuilder.Product.csproj | 2 +- ...taApiBuilder.Service.GraphQLBuilder.csproj | 2 +- .../Azure.DataApiBuilder.Service.Tests.csproj | 2 +- src/Service/.config/dotnet-tools.json | 5 ---- .../Azure.DataApiBuilder.Service.csproj | 7 ++--- .../PublishProfiles/crweudev01.pubxml | 30 ------------------- 12 files changed, 11 insertions(+), 49 deletions(-) delete mode 100644 src/Service/.config/dotnet-tools.json delete mode 100644 src/Service/Properties/PublishProfiles/crweudev01.pubxml diff --git a/Dockerfile b/Dockerfile index e05ba35327..d6d950733c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0. AS build WORKDIR /src COPY [".", "./"] -RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -f net8.0 -o /out -r linux-x64 --self-contained +RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64 FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS runtime diff --git a/src/Auth/Azure.DataApiBuilder.Auth.csproj b/src/Auth/Azure.DataApiBuilder.Auth.csproj index 9537d48834..d3582a3eb5 100644 --- a/src/Auth/Azure.DataApiBuilder.Auth.csproj +++ b/src/Auth/Azure.DataApiBuilder.Auth.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Cli.Tests/Cli.Tests.csproj b/src/Cli.Tests/Cli.Tests.csproj index a8081f5250..46192e3802 100644 --- a/src/Cli.Tests/Cli.Tests.csproj +++ b/src/Cli.Tests/Cli.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 enable enable false diff --git a/src/Cli/Cli.csproj b/src/Cli/Cli.csproj index 2f26b932ef..e06ff2b4cd 100644 --- a/src/Cli/Cli.csproj +++ b/src/Cli/Cli.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net8.0;net6.0 Cli enable enable diff --git a/src/Config/Azure.DataApiBuilder.Config.csproj b/src/Config/Azure.DataApiBuilder.Config.csproj index 25dd0716f9..0b1f12e65c 100644 --- a/src/Config/Azure.DataApiBuilder.Config.csproj +++ b/src/Config/Azure.DataApiBuilder.Config.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Core/Azure.DataApiBuilder.Core.csproj b/src/Core/Azure.DataApiBuilder.Core.csproj index 8a64dcfd0c..3e20a3d671 100644 --- a/src/Core/Azure.DataApiBuilder.Core.csproj +++ b/src/Core/Azure.DataApiBuilder.Core.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 enable enable true diff --git a/src/Product/Azure.DataApiBuilder.Product.csproj b/src/Product/Azure.DataApiBuilder.Product.csproj index a385f21a53..e5c8a369ff 100644 --- a/src/Product/Azure.DataApiBuilder.Product.csproj +++ b/src/Product/Azure.DataApiBuilder.Product.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj b/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj index c2df983509..323c8392fc 100644 --- a/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj +++ b/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj b/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj index d250822359..4b5ebe6117 100644 --- a/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj +++ b/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0;net6.0 false disable $(BaseOutputPath)\tests diff --git a/src/Service/.config/dotnet-tools.json b/src/Service/.config/dotnet-tools.json deleted file mode 100644 index b0e38abdac..0000000000 --- a/src/Service/.config/dotnet-tools.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": {} -} \ No newline at end of file diff --git a/src/Service/Azure.DataApiBuilder.Service.csproj b/src/Service/Azure.DataApiBuilder.Service.csproj index bcf03928b4..b29abbb6bb 100644 --- a/src/Service/Azure.DataApiBuilder.Service.csproj +++ b/src/Service/Azure.DataApiBuilder.Service.csproj @@ -1,7 +1,7 @@  - net8.0 + net8.0;net6.0 Debug;Release;Docker $(BaseOutputPath)\engine win-x64;linux-x64;osx-x64 @@ -36,10 +36,6 @@ True - - True - - $(CopyToOutputDirectoryAction) @@ -49,6 +45,7 @@ + diff --git a/src/Service/Properties/PublishProfiles/crweudev01.pubxml b/src/Service/Properties/PublishProfiles/crweudev01.pubxml deleted file mode 100644 index a785ab2cac..0000000000 --- a/src/Service/Properties/PublishProfiles/crweudev01.pubxml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Container - NetSdk - /subscriptions/d81425a2-a8ea-4ea4-9bdd-ca9db5cdfbc6/resourceGroups/rg-weu-api/providers/Microsoft.ContainerRegistry/registries/crweudev01 - crweudev01 - rg-weu-api - sub-mdm-weu-dev - crweudev01.azurecr.io - - latest - ContainerRegistry - Release - Any CPU - linux-x64 - 208fc26c-a21c-4c96-98ee-f10fdaeac508 - <_TargetId>NetSdkAzureContainerRegistry - - true - false - net8.0 - true - true - true - - \ No newline at end of file From ab4fe7569fd0de3de262bddc46940a282c9d2c73 Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Wed, 21 Aug 2024 09:11:40 +0200 Subject: [PATCH 04/13] Adjust the relevant tests --- .../Authorization/AuthorizationResolverUnitTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs b/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs index 3c7c31a8ca..733ec15b24 100644 --- a/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs +++ b/src/Service.Tests/Authorization/AuthorizationResolverUnitTests.cs @@ -1293,7 +1293,8 @@ public void UniqueClaimsResolvedForDbPolicy_SessionCtx_Usage() new("sub", "Aa_0RISCzzZ-abC1De2fGHIjKLMNo123pQ4rStUVWXY"), new("oid", "55296aad-ea7f-4c44-9a4c-bb1e8d43a005"), new(AuthenticationOptions.ROLE_CLAIM_TYPE, TEST_ROLE), - new(AuthenticationOptions.ROLE_CLAIM_TYPE, "ROLE2") + new(AuthenticationOptions.ROLE_CLAIM_TYPE, "ROLE2"), + new(AuthenticationOptions.ROLE_CLAIM_TYPE, "ROLE3") }; //Add identity object to the Mock context object. @@ -1315,6 +1316,7 @@ public void UniqueClaimsResolvedForDbPolicy_SessionCtx_Usage() Assert.AreEqual(expected: "Aa_0RISCzzZ-abC1De2fGHIjKLMNo123pQ4rStUVWXY", actual: claimsInRequestContext["sub"], message: "Expected the sub claim to be present."); Assert.AreEqual(expected: "55296aad-ea7f-4c44-9a4c-bb1e8d43a005", actual: claimsInRequestContext["oid"], message: "Expected the oid claim to be present."); Assert.AreEqual(claimsInRequestContext[AuthenticationOptions.ROLE_CLAIM_TYPE], actual: TEST_ROLE, message: "The roles claim should have the value:" + TEST_ROLE); + Assert.AreEqual(expected: "[\"" + TEST_ROLE + "\",\"ROLE2\",\"ROLE3\"]", actual: claimsInRequestContext[AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE], message: "Original roles should be preserved in a new context"); } /// @@ -1365,7 +1367,7 @@ public void ValidateUnauthenticatedUserClaimsAreNotResolvedWhenProcessingUserCla Dictionary resolvedClaims = AuthorizationResolver.GetProcessedUserClaims(context.Object); // Assert - Assert.AreEqual(expected: authenticatedUserclaims.Count, actual: resolvedClaims.Count, message: "Only two claims should be present."); + Assert.AreEqual(expected: authenticatedUserclaims.Count + 1, actual: resolvedClaims.Count, message: "Only " + (authenticatedUserclaims.Count + 1) + " claims should be present."); Assert.AreEqual(expected: "openid", actual: resolvedClaims["scp"], message: "Unexpected scp claim returned."); bool didResolveUnauthenticatedRoleClaim = resolvedClaims[AuthenticationOptions.ROLE_CLAIM_TYPE] == "Don't_Parse_This_Role"; From 93a27dc5c5db771206b119e8afa8dfe052ba3647 Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Tue, 3 Sep 2024 23:35:39 +0200 Subject: [PATCH 05/13] Add recordcount --- src/Core/Resolvers/DWSqlQueryBuilder.cs | 17 +++++++++++++-- src/Core/Resolvers/SqlResponseHelpers.cs | 27 +++++++++++++++++++++--- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/Core/Resolvers/DWSqlQueryBuilder.cs b/src/Core/Resolvers/DWSqlQueryBuilder.cs index 510155fbfb..0135b645a2 100644 --- a/src/Core/Resolvers/DWSqlQueryBuilder.cs +++ b/src/Core/Resolvers/DWSqlQueryBuilder.cs @@ -170,8 +170,21 @@ private string BuildWithJsonFunc(SqlQueryStructure structure) /// private string BuildWithStringAgg(SqlQueryStructure structure, bool subQueryStructure = false) { + string subQueryAlias = "CountQuery"; + + string countSql = $" CROSS JOIN ( {BuildSqlCountQuery(structure)} ) {subQueryAlias}"; + + //Add a new column to the structure + structure.Columns.Add(new LabelledColumn("", subQueryAlias, "RecordCount", "RecordCount", subQueryAlias)); + + //Add a subquery 'a' ti the structure + structure.JoinQueries.Add(subQueryAlias, structure); + string columns = GenerateColumnsAsJson(structure, subQueryStructure); - string fromSql = $"{BuildSqlQuery(structure)}"; + + structure.JoinQueries.Remove(subQueryAlias); + + string fromSql = $"{BuildSqlQuery(structure, countSql)}"; string query = $"SELECT {columns}" + $" FROM ({fromSql}) AS {QuoteIdentifier(structure.SourceAlias)}"; return query; @@ -188,7 +201,7 @@ private string BuildWithStringAgg(SqlQueryStructure structure, bool subQueryStru /// FROM dbo_books AS[table0] /// OUTER APPLY(SubQuery generated by recursive call to build function, will create the _subq tables) /// - private string BuildSqlQuery(SqlQueryStructure structure) + private string BuildSqlQuery(SqlQueryStructure structure, string? subQuery) { string dataIdent = QuoteIdentifier(SqlQueryStructure.DATA_IDENT); StringBuilder fromSql = new(); diff --git a/src/Core/Resolvers/SqlResponseHelpers.cs b/src/Core/Resolvers/SqlResponseHelpers.cs index 7701d662d3..9171a3a322 100644 --- a/src/Core/Resolvers/SqlResponseHelpers.cs +++ b/src/Core/Resolvers/SqlResponseHelpers.cs @@ -51,6 +51,13 @@ public static OkObjectResult FormatFindResult( ? DetermineExtraFieldsInResponse(findOperationResponse, context.FieldsToBeReturned) : DetermineExtraFieldsInResponse(findOperationResponse.EnumerateArray().First(), context.FieldsToBeReturned); + //Remove RecordCOunt from extraFieldsInResponse if present + /* + if (extraFieldsInResponse.Contains("RecordCount")) + { + extraFieldsInResponse.Remove("RecordCount"); + } + */ uint defaultPageSize = runtimeConfig.DefaultPageSize(); uint maxPageSize = runtimeConfig.MaxPageSize(); @@ -113,6 +120,16 @@ public static OkObjectResult FormatFindResult( queryStringParameters: context!.ParsedQueryString, after); + //Get the element RecordCount from the first element of the array + JsonElement recordCountElement = rootEnumerated[0].GetProperty("RecordCount"); + string jsonRecordCount = JsonSerializer.Serialize(new[] + { + new + { + recordCount = @$"{rootEnumerated[0].GetProperty("RecordCount")}" + } + }); + // When there are extra fields present, they are removed before returning the response. if (extraFieldsInResponse.Count > 0) { @@ -120,6 +137,7 @@ public static OkObjectResult FormatFindResult( } rootEnumerated.Add(nextLink); + rootEnumerated.Add(JsonSerializer.Deserialize(jsonRecordCount)); return OkResponse(JsonSerializer.SerializeToElement(rootEnumerated)); } @@ -218,13 +236,16 @@ public static OkObjectResult OkResponse(JsonElement jsonResult) // we strip the "[" and "]" and then save the nextLink element // into a dictionary with a key of "nextLink" and a value that // represents the nextLink data we require. - string nextLinkJsonString = JsonSerializer.Serialize(resultEnumerated[resultEnumerated.Count - 1]); + string nextLinkJsonString = JsonSerializer.Serialize(resultEnumerated[resultEnumerated.Count - 2]); + string recordCountJsonString = JsonSerializer.Serialize(resultEnumerated[resultEnumerated.Count - 1]); Dictionary nextLink = JsonSerializer.Deserialize>(nextLinkJsonString[1..^1])!; - IEnumerable value = resultEnumerated.Take(resultEnumerated.Count - 1); + Dictionary recordCount = JsonSerializer.Deserialize>(recordCountJsonString[1..^1])!; + IEnumerable value = resultEnumerated.Take(resultEnumerated.Count - 2); return new OkObjectResult(new { value = value, - @nextLink = nextLink["nextLink"] + @nextLink = nextLink["nextLink"], + @recordCount = recordCount["recordCount"] }); } From ec0365b45d853cefe5ec00dd516273df14a435b4 Mon Sep 17 00:00:00 2001 From: M4Al Date: Fri, 30 Aug 2024 09:50:44 +0200 Subject: [PATCH 06/13] Update src/Core/Resolvers/MsSqlQueryExecutor.cs remove trailing space Co-authored-by: Aniruddh Munde --- src/Core/Resolvers/MsSqlQueryExecutor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Resolvers/MsSqlQueryExecutor.cs b/src/Core/Resolvers/MsSqlQueryExecutor.cs index 9b22eeb591..4187532d30 100644 --- a/src/Core/Resolvers/MsSqlQueryExecutor.cs +++ b/src/Core/Resolvers/MsSqlQueryExecutor.cs @@ -282,7 +282,7 @@ public override string GetSessionParamsQuery(HttpContext? httpContext, IDictiona foreach ((string claimType, string claimValue) in sessionParams) { string paramName = $"{SESSION_PARAM_NAME}{counter.Next()}"; - parameters.Add(paramName, new(claimValue)); + parameters.Add(paramName, new(claimValue)); // Append statement to set read only param value - can be set only once for a connection. string statementToSetReadOnlyParam = "EXEC sp_set_session_context " + $"'{claimType}', " + paramName + ", @read_only = 0;"; sessionMapQuery = sessionMapQuery.Append(statementToSetReadOnlyParam); From 2cecda7757992a36bb22b6eb7724bf3f4bfdbbb2 Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Wed, 4 Sep 2024 10:25:05 +0200 Subject: [PATCH 07/13] Update dockerfile to .net8 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d6d950733c..e05ba35327 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0. AS build WORKDIR /src COPY [".", "./"] -RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64 +RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -f net8.0 -o /out -r linux-x64 --self-contained FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS runtime From de8752e74d29a3141ea7e1d0d1e412dfe07557c9 Mon Sep 17 00:00:00 2001 From: KobeLenjou Date: Thu, 5 Sep 2024 16:40:29 +0200 Subject: [PATCH 08/13] Rename FIRST_URL constant value from "$first" to "$top" Updated the constant `FIRST_URL` in `RequestParser.cs` within the `Azure.DataApiBuilder.Core.Parsers` namespace to use the value `"$top"` instead of `"$first"`. This change aligns with naming conventions or standards used elsewhere in the codebase or API, ensuring consistency and improving clarity for developers. --- src/Core/Parsers/RequestParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Parsers/RequestParser.cs b/src/Core/Parsers/RequestParser.cs index bb4dd8d51e..51c1ff1042 100644 --- a/src/Core/Parsers/RequestParser.cs +++ b/src/Core/Parsers/RequestParser.cs @@ -30,7 +30,7 @@ public class RequestParser /// /// Prefix used for specifying limit in the query string of the URL. /// - public const string FIRST_URL = "$first"; + public const string FIRST_URL = "$top"; /// /// Prefix used for specifying paging in the query string of the URL. /// From bebd9d2766317dedab8fd7d8f4da83bf2964d173 Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Fri, 23 May 2025 11:01:19 -0700 Subject: [PATCH 09/13] Rebase fixes --- src/Auth/Azure.DataApiBuilder.Auth.csproj | 2 +- src/Cli.Tests/Cli.Tests.csproj | 2 +- src/Cli/Cli.csproj | 2 +- src/Config/Azure.DataApiBuilder.Config.csproj | 2 +- src/Core/Authorization/AuthorizationResolver.cs | 2 +- src/Core/Azure.DataApiBuilder.Core.csproj | 2 +- src/Core/Parsers/RequestParser.cs | 2 +- src/Core/Resolvers/SqlResponseHelpers.cs | 7 ------- src/Product/Azure.DataApiBuilder.Product.csproj | 2 +- .../Azure.DataApiBuilder.Service.GraphQLBuilder.csproj | 2 +- .../Azure.DataApiBuilder.Service.Tests.csproj | 2 +- src/Service/Azure.DataApiBuilder.Service.csproj | 2 +- 12 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/Auth/Azure.DataApiBuilder.Auth.csproj b/src/Auth/Azure.DataApiBuilder.Auth.csproj index d3582a3eb5..9537d48834 100644 --- a/src/Auth/Azure.DataApiBuilder.Auth.csproj +++ b/src/Auth/Azure.DataApiBuilder.Auth.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Cli.Tests/Cli.Tests.csproj b/src/Cli.Tests/Cli.Tests.csproj index 46192e3802..a8081f5250 100644 --- a/src/Cli.Tests/Cli.Tests.csproj +++ b/src/Cli.Tests/Cli.Tests.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 enable enable false diff --git a/src/Cli/Cli.csproj b/src/Cli/Cli.csproj index e06ff2b4cd..2f26b932ef 100644 --- a/src/Cli/Cli.csproj +++ b/src/Cli/Cli.csproj @@ -2,7 +2,7 @@ Exe - net8.0;net6.0 + net8.0 Cli enable enable diff --git a/src/Config/Azure.DataApiBuilder.Config.csproj b/src/Config/Azure.DataApiBuilder.Config.csproj index 0b1f12e65c..25dd0716f9 100644 --- a/src/Config/Azure.DataApiBuilder.Config.csproj +++ b/src/Config/Azure.DataApiBuilder.Config.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Core/Authorization/AuthorizationResolver.cs b/src/Core/Authorization/AuthorizationResolver.cs index 10442fd948..c71e374d18 100644 --- a/src/Core/Authorization/AuthorizationResolver.cs +++ b/src/Core/Authorization/AuthorizationResolver.cs @@ -617,7 +617,7 @@ public static Dictionary> GetAllAuthenticatedUserClaims(Http // into a list and storing that in resolvedClaims using the claimType as the key. foreach (Claim claim in identity.Claims) { - // 'roles' claim has already been processed. But we preserve the original 'roles' claim + // 'roles' claim has already been processed. But we preserve the original 'roles' claim. if (claim.Type.Equals(AuthenticationOptions.ROLE_CLAIM_TYPE)) { if(!resolvedClaims.TryAdd(AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE, new List() { claim })) diff --git a/src/Core/Azure.DataApiBuilder.Core.csproj b/src/Core/Azure.DataApiBuilder.Core.csproj index 3e20a3d671..8a64dcfd0c 100644 --- a/src/Core/Azure.DataApiBuilder.Core.csproj +++ b/src/Core/Azure.DataApiBuilder.Core.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 enable enable true diff --git a/src/Core/Parsers/RequestParser.cs b/src/Core/Parsers/RequestParser.cs index 51c1ff1042..bb4dd8d51e 100644 --- a/src/Core/Parsers/RequestParser.cs +++ b/src/Core/Parsers/RequestParser.cs @@ -30,7 +30,7 @@ public class RequestParser /// /// Prefix used for specifying limit in the query string of the URL. /// - public const string FIRST_URL = "$top"; + public const string FIRST_URL = "$first"; /// /// Prefix used for specifying paging in the query string of the URL. /// diff --git a/src/Core/Resolvers/SqlResponseHelpers.cs b/src/Core/Resolvers/SqlResponseHelpers.cs index 9171a3a322..417b22e91d 100644 --- a/src/Core/Resolvers/SqlResponseHelpers.cs +++ b/src/Core/Resolvers/SqlResponseHelpers.cs @@ -51,13 +51,6 @@ public static OkObjectResult FormatFindResult( ? DetermineExtraFieldsInResponse(findOperationResponse, context.FieldsToBeReturned) : DetermineExtraFieldsInResponse(findOperationResponse.EnumerateArray().First(), context.FieldsToBeReturned); - //Remove RecordCOunt from extraFieldsInResponse if present - /* - if (extraFieldsInResponse.Contains("RecordCount")) - { - extraFieldsInResponse.Remove("RecordCount"); - } - */ uint defaultPageSize = runtimeConfig.DefaultPageSize(); uint maxPageSize = runtimeConfig.MaxPageSize(); diff --git a/src/Product/Azure.DataApiBuilder.Product.csproj b/src/Product/Azure.DataApiBuilder.Product.csproj index e5c8a369ff..a385f21a53 100644 --- a/src/Product/Azure.DataApiBuilder.Product.csproj +++ b/src/Product/Azure.DataApiBuilder.Product.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj b/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj index 323c8392fc..c2df983509 100644 --- a/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj +++ b/src/Service.GraphQLBuilder/Azure.DataApiBuilder.Service.GraphQLBuilder.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 enable enable $(BaseOutputPath)\engine diff --git a/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj b/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj index 4b5ebe6117..d250822359 100644 --- a/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj +++ b/src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj @@ -1,7 +1,7 @@ - net8.0;net6.0 + net8.0 false disable $(BaseOutputPath)\tests diff --git a/src/Service/Azure.DataApiBuilder.Service.csproj b/src/Service/Azure.DataApiBuilder.Service.csproj index b29abbb6bb..7d41aaef28 100644 --- a/src/Service/Azure.DataApiBuilder.Service.csproj +++ b/src/Service/Azure.DataApiBuilder.Service.csproj @@ -1,7 +1,7 @@  - net8.0;net6.0 + net8.0 Debug;Release;Docker $(BaseOutputPath)\engine win-x64;linux-x64;osx-x64 From 773f77268b6f61c3237774d748af58446cf725fd Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Fri, 23 May 2025 14:02:16 -0700 Subject: [PATCH 10/13] Fixed Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e05ba35327..d6d950733c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0. AS build WORKDIR /src COPY [".", "./"] -RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -f net8.0 -o /out -r linux-x64 --self-contained +RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64 FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS runtime From 98032982ec5a8079e804970d43885ebc679b7b97 Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Mon, 16 Jun 2025 12:20:09 -0700 Subject: [PATCH 11/13] Remove changes from DW SQL Builder --- src/Core/Resolvers/DWSqlQueryBuilder.cs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/Core/Resolvers/DWSqlQueryBuilder.cs b/src/Core/Resolvers/DWSqlQueryBuilder.cs index 0135b645a2..510155fbfb 100644 --- a/src/Core/Resolvers/DWSqlQueryBuilder.cs +++ b/src/Core/Resolvers/DWSqlQueryBuilder.cs @@ -170,21 +170,8 @@ private string BuildWithJsonFunc(SqlQueryStructure structure) /// private string BuildWithStringAgg(SqlQueryStructure structure, bool subQueryStructure = false) { - string subQueryAlias = "CountQuery"; - - string countSql = $" CROSS JOIN ( {BuildSqlCountQuery(structure)} ) {subQueryAlias}"; - - //Add a new column to the structure - structure.Columns.Add(new LabelledColumn("", subQueryAlias, "RecordCount", "RecordCount", subQueryAlias)); - - //Add a subquery 'a' ti the structure - structure.JoinQueries.Add(subQueryAlias, structure); - string columns = GenerateColumnsAsJson(structure, subQueryStructure); - - structure.JoinQueries.Remove(subQueryAlias); - - string fromSql = $"{BuildSqlQuery(structure, countSql)}"; + string fromSql = $"{BuildSqlQuery(structure)}"; string query = $"SELECT {columns}" + $" FROM ({fromSql}) AS {QuoteIdentifier(structure.SourceAlias)}"; return query; @@ -201,7 +188,7 @@ private string BuildWithStringAgg(SqlQueryStructure structure, bool subQueryStru /// FROM dbo_books AS[table0] /// OUTER APPLY(SubQuery generated by recursive call to build function, will create the _subq tables) /// - private string BuildSqlQuery(SqlQueryStructure structure, string? subQuery) + private string BuildSqlQuery(SqlQueryStructure structure) { string dataIdent = QuoteIdentifier(SqlQueryStructure.DATA_IDENT); StringBuilder fromSql = new(); From 60859a13bc364da129d48c399450f7fa93509c3e Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Tue, 17 Jun 2025 11:39:35 -0700 Subject: [PATCH 12/13] Fix unit test failure --- src/Core/Resolvers/SqlResponseHelpers.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/Resolvers/SqlResponseHelpers.cs b/src/Core/Resolvers/SqlResponseHelpers.cs index 417b22e91d..2dc45f5455 100644 --- a/src/Core/Resolvers/SqlResponseHelpers.cs +++ b/src/Core/Resolvers/SqlResponseHelpers.cs @@ -114,7 +114,6 @@ public static OkObjectResult FormatFindResult( after); //Get the element RecordCount from the first element of the array - JsonElement recordCountElement = rootEnumerated[0].GetProperty("RecordCount"); string jsonRecordCount = JsonSerializer.Serialize(new[] { new From 97ac4c9bb986ba03ebe4a7ddbe7045a978211c37 Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Tue, 17 Jun 2025 11:55:10 -0700 Subject: [PATCH 13/13] Fix Unit Test Failure --- src/Core/Authorization/AuthorizationResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Authorization/AuthorizationResolver.cs b/src/Core/Authorization/AuthorizationResolver.cs index c71e374d18..0f22b9cd28 100644 --- a/src/Core/Authorization/AuthorizationResolver.cs +++ b/src/Core/Authorization/AuthorizationResolver.cs @@ -620,7 +620,7 @@ public static Dictionary> GetAllAuthenticatedUserClaims(Http // 'roles' claim has already been processed. But we preserve the original 'roles' claim. if (claim.Type.Equals(AuthenticationOptions.ROLE_CLAIM_TYPE)) { - if(!resolvedClaims.TryAdd(AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE, new List() { claim })) + if (!resolvedClaims.TryAdd(AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE, new List() { claim })) { resolvedClaims[AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE].Add(claim); }