diff --git a/src/Microsoft.WindowsPackageManager.Rest/Utils/AzureFunctionHelper.cs b/src/Microsoft.WindowsPackageManager.Rest/Utils/AzureFunctionHelper.cs
index b2ce5948..622ee6fe 100644
--- a/src/Microsoft.WindowsPackageManager.Rest/Utils/AzureFunctionHelper.cs
+++ b/src/Microsoft.WindowsPackageManager.Rest/Utils/AzureFunctionHelper.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -38,7 +38,7 @@ public static async Task TriggerAzureFunctionAsync(
string postRequestBody = null,
Dictionary headers = null)
{
- // Create Post Request.
+ // Create Request.
HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, azureFunctionURL);
requestMessage.Headers.Add(FunctionKeyHeader, functionKey);
diff --git a/src/WinGet.RestSource.AppConfig/WinGet.RestSource.AppConfig.csproj b/src/WinGet.RestSource.AppConfig/WinGet.RestSource.AppConfig.csproj
index d50639c9..53299286 100644
--- a/src/WinGet.RestSource.AppConfig/WinGet.RestSource.AppConfig.csproj
+++ b/src/WinGet.RestSource.AppConfig/WinGet.RestSource.AppConfig.csproj
@@ -53,7 +53,6 @@
-
diff --git a/src/WinGet.RestSource.Functions/Common/ActionResultHelper.cs b/src/WinGet.RestSource.Functions/Common/ActionResultHelper.cs
index be6480fa..88165d8a 100644
--- a/src/WinGet.RestSource.Functions/Common/ActionResultHelper.cs
+++ b/src/WinGet.RestSource.Functions/Common/ActionResultHelper.cs
@@ -50,7 +50,7 @@ public static ApiObjectResult ProcessError(InternalRestError internalRestError)
case ErrorConstants.ValidationFailureErrorCode:
case ErrorConstants.HeadersAreNullErrorCode:
case ErrorConstants.ServerVersionNotSupportedErrorCode:
- case ErrorConstants.ToManyContinuationTokensErrorCode:
+ case ErrorConstants.TooManyContinuationTokensErrorCode:
return CreateObjectResult(internalRestError, (int)HttpStatusCode.BadRequest);
case ErrorConstants.ForbiddenErrorCode:
diff --git a/src/WinGet.RestSource.Functions/Common/CertificateValidationHelper.cs b/src/WinGet.RestSource.Functions/Common/CertificateValidationHelper.cs
deleted file mode 100644
index 269acfc8..00000000
--- a/src/WinGet.RestSource.Functions/Common/CertificateValidationHelper.cs
+++ /dev/null
@@ -1,188 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
-//
-// -----------------------------------------------------------------------
-
-namespace Microsoft.WinGet.RestSource.Functions.Common
-{
- using System;
- using System.Linq;
- using System.Security.Cryptography.X509Certificates;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Primitives;
- using Microsoft.WinGet.RestSource.Utils.Constants;
- using Microsoft.WinGet.RestSource.Utils.Exceptions;
- using Microsoft.WinGet.RestSource.Utils.Models.Errors;
-
- ///
- /// Provides common certificate validation helpers.
- ///
- public static class CertificateValidationHelper
- {
- ///
- /// This will check for a client certificate and verify its applicability.
- ///
- /// the httprequest to process.
- /// Log output.
- public static void ValidateAuthentication(HttpRequest req, ILogger log)
- {
- if (ApiConstants.CertificateAuthenticationRequired)
- {
- StringValues certHeader;
- bool headerPresent = req.Headers.TryGetValue(HeaderConstants.XARRClientCert, out certHeader);
-
- if (!headerPresent || StringValues.IsNullOrEmpty(certHeader))
- {
- throw new ForbiddenException(
- new InternalRestError(
- ErrorConstants.ForbiddenErrorCode,
- string.Format(ErrorConstants.ForbiddenErrorMessage, ApiConstants.CertificateAuthenticationSubjectName)));
- }
-
- byte[] clientCertBytes = Convert.FromBase64String(certHeader);
- X509Certificate2 certificate = new X509Certificate2(clientCertBytes);
-
- if (!IsClientCertValid(certificate, log))
- {
- throw new ForbiddenException(
- new InternalRestError(
- ErrorConstants.ForbiddenErrorCode,
- string.Format(ErrorConstants.ForbiddenErrorMessage, ApiConstants.CertificateAuthenticationSubjectName)));
- }
- }
- }
-
- ///
- /// Checks the validity of a given client certificate.
- ///
- /// Certificate to validate.
- /// Log output.
- /// True if the certificate is valid. False otherwise.
- private static bool IsClientCertValid(X509Certificate2 certificate, ILogger log)
- {
- // Do we have a certificate?
- if (certificate == null)
- {
- log.LogInformation("No client certificate found.");
- return false;
- }
-
- // Is the Certificate not expired?
- if (DateTime.Compare(DateTime.Now, certificate.NotBefore) < 0 || DateTime.Compare(DateTime.Now, certificate.NotAfter) > 0)
- {
- log.LogInformation("Client certificate is expired.");
- return false;
- }
-
- // Fetch server root certificate to perform comparison and chaining
- bool validOnly = false;
- using (X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
- {
- certStore.Open(OpenFlags.ReadOnly);
-
- X509Certificate2Collection certCollection = certStore.Certificates.Find(
- X509FindType.FindBySubjectName,
- ApiConstants.CertificateAuthenticationSubjectName,
- validOnly);
-
- X509Certificate2 serverCert = certCollection.OfType().FirstOrDefault();
-
- if (serverCert is null)
- {
- log.LogError("No configured server certificate found.");
- return false;
- }
-
- // Note: We skip subject name validation for client cert as the subject may differ per client machine.
- // Our primary validation is that the cert itself was signed by the server certificate.
- if (string.Compare(certificate.Issuer, serverCert.Subject) != 0)
- {
- log.LogInformation("Client certificate is not issued by the expected issuer.");
- return false;
- }
-
- // Does the certificate chain of trust to our root certificate?
- var chain = new X509Chain();
- chain.ChainPolicy.ExtraStore.Add(serverCert);
-
- if (ApiConstants.CertificateAuthenticationSelfSigned)
- {
- // Disable revocation check as this is selfsigned.
- chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
-
- // Explicitly allow unknown roots since we are testing a self signed cert.
- chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
- }
-
- if (!chain.Build(certificate))
- {
- // If the chain failed, dump diagnostic information to trace logging.
- log.LogTrace("Chain revocation flag: {0}", chain.ChainPolicy.RevocationFlag);
- log.LogTrace("Chain revocation mode: {0}", chain.ChainPolicy.RevocationMode);
- log.LogTrace("Chain verification flag: {0}", chain.ChainPolicy.VerificationFlags);
- log.LogTrace("Chain verification time: {0}", chain.ChainPolicy.VerificationTime);
- log.LogTrace("Chain status length: {0}", chain.ChainStatus.Length);
- log.LogTrace("Chain application policy count: {0}", chain.ChainPolicy.ApplicationPolicy.Count);
- log.LogTrace("Chain certificate policy count: {0}", chain.ChainPolicy.CertificatePolicy.Count);
-
- log.LogTrace("Number of chain elements: {0}", chain.ChainElements.Count);
- log.LogTrace("Chain elements synchronized? {0}", chain.ChainElements.IsSynchronized);
-
- foreach (X509ChainElement element in chain.ChainElements)
- {
- log.LogTrace("Element issuer name: {0}", element.Certificate.Issuer);
- log.LogTrace("Element certificate valid until: {0}", element.Certificate.NotAfter);
- log.LogTrace("Element certificate is valid: {0}", element.Certificate.Verify());
- log.LogTrace("Element error status length: {0}", element.ChainElementStatus.Length);
- log.LogTrace("Element information: {0}", element.Information);
- log.LogTrace("Number of element extensions: {0}", element.Certificate.Extensions.Count);
-
- if (chain.ChainStatus.Length > 1)
- {
- for (int index = 0; index < element.ChainElementStatus.Length; index++)
- {
- log.LogTrace(element.ChainElementStatus[index].Status.ToString());
- log.LogTrace(element.ChainElementStatus[index].StatusInformation);
- }
- }
- }
-
- return false;
- }
-
- if (ApiConstants.CertificateAuthenticationSelfSigned)
- {
- // Selfsigned: If we have a valid chain, double check that it chained to the item we planned to chain to.
- var chainRoot = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
- if (!chainRoot.RawData.SequenceEqual(serverCert.RawData))
- {
- log.LogInformation("Server certificate was not the root was the chain.");
- return false;
- }
- }
- else
- {
- // Check that the server certificate is present in the certificate chain.
- bool found = false;
- foreach (var element in chain.ChainElements)
- {
- if (element.Certificate.RawData.SequenceEqual(serverCert.RawData))
- {
- found = true;
- }
- }
-
- if (!found)
- {
- log.LogInformation("Server certificate was not found in the client certificate chain of trust.");
- return false;
- }
- }
- }
-
- return true;
- }
- }
-}
diff --git a/src/WinGet.RestSource.Functions/InstallerFunctions.cs b/src/WinGet.RestSource.Functions/InstallerFunctions.cs
index 22a3f328..a6509c3c 100644
--- a/src/WinGet.RestSource.Functions/InstallerFunctions.cs
+++ b/src/WinGet.RestSource.Functions/InstallerFunctions.cs
@@ -12,6 +12,7 @@ namespace Microsoft.WinGet.RestSource.Functions
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+ using Microsoft.Azure.Cosmos.Linq;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
@@ -69,8 +70,6 @@ public async Task InstallerPostAsync(
Dictionary headers = null;
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -133,8 +132,6 @@ public async Task InstallerDeleteAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
await this.dataStore.DeleteInstaller(packageIdentifier, packageVersion, installerIdentifier);
@@ -192,8 +189,6 @@ public async Task InstallerPutAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -251,7 +246,7 @@ public async Task InstallerPutAsync(
[FunctionName(FunctionConstants.InstallerGet)]
public async Task InstallerGetAsync(
[HttpTrigger(
- AuthorizationLevel.Anonymous,
+ AuthorizationLevel.Function,
FunctionConstants.FunctionGet,
Route = "packages/{packageIdentifier}/versions/{packageVersion}/installers/{installerIdentifier?}")]
HttpRequest req,
@@ -265,8 +260,6 @@ public async Task InstallerGetAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
diff --git a/src/WinGet.RestSource.Functions/LocaleFunctions.cs b/src/WinGet.RestSource.Functions/LocaleFunctions.cs
index a685d3c7..a633f7a2 100644
--- a/src/WinGet.RestSource.Functions/LocaleFunctions.cs
+++ b/src/WinGet.RestSource.Functions/LocaleFunctions.cs
@@ -67,8 +67,6 @@ public async Task LocalePostAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -131,8 +129,6 @@ public async Task LocaleDeleteAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
await this.dataStore.DeleteLocale(packageIdentifier, packageVersion, packageLocale);
@@ -190,8 +186,6 @@ public async Task LocalePutAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -249,7 +243,7 @@ public async Task LocalePutAsync(
[FunctionName(FunctionConstants.LocaleGet)]
public async Task LocaleGetAsync(
[HttpTrigger(
- AuthorizationLevel.Anonymous,
+ AuthorizationLevel.Function,
FunctionConstants.FunctionGet,
Route = "packages/{packageIdentifier}/versions/{packageVersion}/locales/{packageLocale?}")]
HttpRequest req,
@@ -263,8 +257,6 @@ public async Task LocaleGetAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
diff --git a/src/WinGet.RestSource.Functions/ManifestSearchFunctions.cs b/src/WinGet.RestSource.Functions/ManifestSearchFunctions.cs
index 20b95deb..b24d66c6 100644
--- a/src/WinGet.RestSource.Functions/ManifestSearchFunctions.cs
+++ b/src/WinGet.RestSource.Functions/ManifestSearchFunctions.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -53,7 +53,7 @@ public ManifestSearchFunctions(IApiDataStore dataStore, IWinGetAppConfig appConf
/// IActionResult.
[FunctionName(FunctionConstants.ManifestSearchPost)]
public async Task ManifestSearchPostAsync(
- [HttpTrigger(AuthorizationLevel.Anonymous, FunctionConstants.FunctionPost, Route = "manifestSearch")]
+ [HttpTrigger(AuthorizationLevel.Function, FunctionConstants.FunctionPost, Route = "manifestSearch")]
HttpRequest req,
ILogger log)
{
@@ -65,8 +65,6 @@ public async Task ManifestSearchPostAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
string continuationToken = headers.GetValueOrDefault(HeaderConstants.ContinuationToken);
diff --git a/src/WinGet.RestSource.Functions/PackageFunctions.cs b/src/WinGet.RestSource.Functions/PackageFunctions.cs
index a9674d91..45fabbc5 100644
--- a/src/WinGet.RestSource.Functions/PackageFunctions.cs
+++ b/src/WinGet.RestSource.Functions/PackageFunctions.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -63,8 +63,6 @@ public async Task PackagesPostAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -122,8 +120,6 @@ public async Task PackageDeleteAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
await this.dataStore.DeletePackage(packageIdentifier);
@@ -174,8 +170,6 @@ public async Task PackagesPutAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -232,7 +226,7 @@ public async Task PackagesPutAsync(
/// IActionResult.
[FunctionName(FunctionConstants.PackageGet)]
public async Task PackagesGetAsync(
- [HttpTrigger(AuthorizationLevel.Anonymous, FunctionConstants.FunctionGet, Route = "packages/{packageIdentifier?}")]
+ [HttpTrigger(AuthorizationLevel.Function, FunctionConstants.FunctionGet, Route = "packages/{packageIdentifier?}")]
HttpRequest req,
string packageIdentifier,
ILogger log)
@@ -242,8 +236,6 @@ public async Task PackagesGetAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
diff --git a/src/WinGet.RestSource.Functions/PackageManifestFunctions.cs b/src/WinGet.RestSource.Functions/PackageManifestFunctions.cs
index c3cc70e9..c4934675 100644
--- a/src/WinGet.RestSource.Functions/PackageManifestFunctions.cs
+++ b/src/WinGet.RestSource.Functions/PackageManifestFunctions.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -64,8 +64,6 @@ public async Task ManifestPostAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -121,8 +119,6 @@ public async Task ManifestDeleteAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
await this.dataStore.DeletePackageManifest(packageIdentifier);
@@ -173,8 +169,6 @@ public async Task ManifestPutAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -230,7 +224,7 @@ public async Task ManifestPutAsync(
/// IActionResult.
[FunctionName(FunctionConstants.ManifestGet)]
public async Task ManifestGetAsync(
- [HttpTrigger(AuthorizationLevel.Anonymous, FunctionConstants.FunctionGet, Route = "packageManifests/{packageIdentifier?}")]
+ [HttpTrigger(AuthorizationLevel.Function, FunctionConstants.FunctionGet, Route = "packageManifests/{packageIdentifier?}")]
HttpRequest req,
string packageIdentifier,
ILogger log)
@@ -242,8 +236,6 @@ public async Task ManifestGetAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
string continuationToken = headers.GetValueOrDefault(QueryConstants.ContinuationToken);
diff --git a/src/WinGet.RestSource.Functions/ServerFunctions.cs b/src/WinGet.RestSource.Functions/ServerFunctions.cs
index 701444c7..ed0b2aae 100644
--- a/src/WinGet.RestSource.Functions/ServerFunctions.cs
+++ b/src/WinGet.RestSource.Functions/ServerFunctions.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -8,7 +8,6 @@ namespace Microsoft.WinGet.RestSource.Functions
{
using System;
using System.Collections.Generic;
- using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
@@ -50,7 +49,7 @@ public ServerFunctions(IWinGetAppConfig appConfig)
/// IActionResult.
[FunctionName(FunctionConstants.InformationGet)]
public IActionResult InformationGetAsync(
- [HttpTrigger(AuthorizationLevel.Anonymous, FunctionConstants.FunctionGet, Route = "information")]
+ [HttpTrigger(AuthorizationLevel.Function, FunctionConstants.FunctionGet, Route = "information")]
HttpRequest req,
ILogger log)
{
@@ -59,8 +58,6 @@ public IActionResult InformationGetAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
information = new Information();
diff --git a/src/WinGet.RestSource.Functions/Startup.cs b/src/WinGet.RestSource.Functions/Startup.cs
index bdd33544..2670b1f3 100644
--- a/src/WinGet.RestSource.Functions/Startup.cs
+++ b/src/WinGet.RestSource.Functions/Startup.cs
@@ -38,8 +38,6 @@ public override void Configure(IFunctionsHostBuilder builder)
builder.Services.AddHttpClient();
string endpoint = Environment.GetEnvironmentVariable(CosmosConnectionConstants.CosmosAccountEndpointSetting) ?? throw new InvalidDataException();
- string readOnlyKey = Environment.GetEnvironmentVariable(CosmosConnectionConstants.CosmosReadWriteKeySetting);
- string readWriteKey = Environment.GetEnvironmentVariable(CosmosConnectionConstants.CosmosReadWriteKeySetting);
string databaseId = Environment.GetEnvironmentVariable(CosmosConnectionConstants.DatabaseNameSetting) ?? throw new InvalidDataException();
string containerId = Environment.GetEnvironmentVariable(CosmosConnectionConstants.ContainerNameSetting) ?? throw new InvalidDataException();
@@ -49,8 +47,6 @@ public override void Configure(IFunctionsHostBuilder builder)
sp => new CosmosDataStore(
sp.GetRequiredService>(),
endpoint,
- readWriteKey,
- readOnlyKey,
databaseId,
containerId));
diff --git a/src/WinGet.RestSource.Functions/VersionFunctions.cs b/src/WinGet.RestSource.Functions/VersionFunctions.cs
index 9beba068..384083fd 100644
--- a/src/WinGet.RestSource.Functions/VersionFunctions.cs
+++ b/src/WinGet.RestSource.Functions/VersionFunctions.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -65,8 +65,6 @@ public async Task VersionsPostAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -125,8 +123,6 @@ public async Task VersionsDeleteAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
await this.dataStore.DeleteVersion(packageIdentifier, packageVersion);
@@ -179,8 +175,6 @@ public async Task VersionsPutAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
@@ -237,7 +231,7 @@ public async Task VersionsPutAsync(
/// IActionResult.
[FunctionName(FunctionConstants.VersionGet)]
public async Task VersionsGetAsync(
- [HttpTrigger(AuthorizationLevel.Anonymous, FunctionConstants.FunctionGet, Route = "packages/{packageIdentifier}/versions/{packageVersion?}")]
+ [HttpTrigger(AuthorizationLevel.Function, FunctionConstants.FunctionGet, Route = "packages/{packageIdentifier}/versions/{packageVersion?}")]
HttpRequest req,
string packageIdentifier,
string packageVersion,
@@ -248,8 +242,6 @@ public async Task VersionsGetAsync(
try
{
- CertificateValidationHelper.ValidateAuthentication(req, log);
-
// Parse Headers
headers = HeaderProcessor.ToDictionary(req.Headers);
diff --git a/src/WinGet.RestSource.Functions/WinGet.RestSource.Functions.csproj b/src/WinGet.RestSource.Functions/WinGet.RestSource.Functions.csproj
index 51f54dbb..90886424 100644
--- a/src/WinGet.RestSource.Functions/WinGet.RestSource.Functions.csproj
+++ b/src/WinGet.RestSource.Functions/WinGet.RestSource.Functions.csproj
@@ -52,7 +52,6 @@
-
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.centus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.centus.json
index 2a2cdc2a..2de24d45 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.centus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.centus.json
@@ -6,7 +6,7 @@
"value": "centralus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-int"
+ "value": "winget-pkgs-rest-int"
},
"manifestCacheEndpoint": {
"value": "https://winget-int.azureedge.net/cache/"
@@ -50,7 +50,10 @@
}
},
"azFuncStorageName": {
- "value": "stwgrestcentusint"
+ "value": "stwgrestcentusint"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.westus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.westus.json
index a8032013..f78d5e54 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.westus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.int.westus.json
@@ -6,7 +6,7 @@
"value": "westus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-int"
+ "value": "winget-pkgs-rest-int"
},
"manifestCacheEndpoint": {
"value": "https://winget-int.azureedge.net/cache/"
@@ -51,6 +51,9 @@
},
"azFuncStorageName": {
"value": "stwgrestwestusint"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.centus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.centus.json
index 953420bb..03b58a79 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.centus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.centus.json
@@ -6,7 +6,7 @@
"value": "centralus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-pme"
+ "value": "winget-pkgs-rest-pme"
},
"manifestCacheEndpoint": {
"value": "https://cdn.winget.microsoft.com/cache/"
@@ -51,6 +51,9 @@
},
"azFuncStorageName": {
"value": "stwgrestcentuspme"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.westus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.westus.json
index e5b0a4ac..89d089b4 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.westus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.pme.westus.json
@@ -6,7 +6,7 @@
"value": "westus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-pme"
+ "value": "winget-pkgs-rest-pme"
},
"manifestCacheEndpoint": {
"value": "https://cdn.winget.microsoft.com/cache/"
@@ -51,6 +51,9 @@
},
"azFuncStorageName": {
"value": "stwgrestwestuspme"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.centus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.centus.json
index 1dacf199..5e8b0a44 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.centus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.centus.json
@@ -6,7 +6,7 @@
"value": "centralus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-ppe"
+ "value": "winget-pkgs-rest-ppe"
},
"manifestCacheEndpoint": {
"value": "https://winget-ppe.azureedge.net/cache/"
@@ -51,6 +51,9 @@
},
"azFuncStorageName": {
"value": "stwgrestcentusppe"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.westus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.westus.json
index bb5516c6..cbce6254 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.westus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.ppe.westus.json
@@ -6,7 +6,7 @@
"value": "westus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-ppe"
+ "value": "winget-pkgs-rest-ppe"
},
"manifestCacheEndpoint": {
"value": "https://winget-ppe.azureedge.net/cache/"
@@ -51,6 +51,9 @@
},
"azFuncStorageName": {
"value": "stwgrestwestusppe"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.test.westus.json b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.test.westus.json
index b76f7d10..1fb99600 100644
--- a/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.test.westus.json
+++ b/src/WinGet.RestSource.Infrastructure/Parameters/AzureFunction/azurefunction.test.westus.json
@@ -6,7 +6,7 @@
"value": "westus"
},
"serverIdentifier": {
- "value": "winget-pkgs-intune-rest-test"
+ "value": "winget-pkgs-rest-test"
},
"manifestCacheEndpoint": {
"value": "https://winget-test.azureedge.net/cache/"
@@ -40,6 +40,9 @@
},
"azFuncStorageName": {
"value": "stwgrestwestustest"
+ },
+ "serverAuthenticationType": {
+ "value": "none"
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Templates/ApiManagement/apimanagement.json b/src/WinGet.RestSource.Infrastructure/Templates/ApiManagement/apimanagement.json
new file mode 100644
index 00000000..f412c1b7
--- /dev/null
+++ b/src/WinGet.RestSource.Infrastructure/Templates/ApiManagement/apimanagement.json
@@ -0,0 +1,981 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "serviceName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the API Management service instance"
+ }
+ },
+ "publisherEmail": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "The email address of the owner of the service"
+ }
+ },
+ "publisherName": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "The name of the owner of the service"
+ }
+ },
+ "sku": {
+ "type": "string",
+ "allowedValues": [
+ "Consumption",
+ "Developer",
+ "Basic",
+ "Basicv2",
+ "Standard",
+ "Standardv2",
+ "Premium"
+ ],
+ "metadata": {
+ "description": "The pricing tier of this API Management service"
+ }
+ },
+ "skuCount": {
+ "type": "int",
+ "defaultValue": 1,
+ "allowedValues": [
+ 0,
+ 1,
+ 2
+ ],
+ "metadata": {
+ "description": "The instance size of this API Management service."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Location for all resources."
+ }
+ },
+ "apiName": {
+ "type": "string",
+ "defaultValue": "winget",
+ "metadata": {
+ "description": "The API name for the winget rest source."
+ }
+ },
+ "subscriptionRequired": {
+ "type": "bool",
+ "defaultValue": false,
+ "metadata": {
+ "description": "Whether an API or Product subscription is required for accessing the API."
+ }
+ },
+ "keyVaultName": {
+ "type": "string",
+ "metadata": {
+ "description": "Key Vault Name"
+ }
+ },
+ "backendUrls": {
+ "type": "array",
+ "metadata": {
+ "description": "String array containing backend urls"
+ }
+ },
+ "queryApiValidationEnabled": {
+ "type": "bool",
+ "defaultValue": false,
+ "metadata": {
+ "description": "Whether all GET apis and manifestSearch api should perform request validation."
+ }
+ },
+ "queryApiValidationPolicy": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Api validation policy for source query apis (all GET apis and manifestSearch POST api). If queryApiValidationEnabled is true and this parameter is empty, a default validate-azure-ad-token policy is used."
+ }
+ },
+ "manageApiValidationPolicy": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Api validation policy for source management apis. If this parameter is empty, a default validate-azure-ad-token policy is used."
+ }
+ }
+ },
+ "variables": {
+ "kv_secreturi_path": "[concat('https://', parameters('keyVaultName'), '.vault.azure.net/secrets/')]",
+ "kv_functionHostKey_SecretName": "AzureFunctionHostKey",
+ "backendPoolName": "[concat(parameters('apiName'), '-backend-pool')]",
+ "queryApiValidation": "[if(parameters('queryApiValidationEnabled'), if(empty(parameters('queryApiValidationPolicy')), concat('7b8ea11a-7f45-4b3a-ab51-794d5863af1504b07795-8ddb-461a-bbee-02f9e1bf7b461950a258-227b-4e31-a9cf-717495945fc2'), parameters('queryApiValidationPolicy')), '')]",
+ "manageApiValidation": "[if(empty(parameters('manageApiValidationPolicy')), concat('04b07795-8ddb-461a-bbee-02f9e1bf7b461950a258-227b-4e31-a9cf-717495945fc29b895d92-2cd3-44c7-9d02-a6ac2d5ea5c362e90394-69f5-4237-9190-012177145e10'), parameters('manageApiValidationPolicy'))]",
+ "publicApiPolicy": {
+ "value": "[concat('')]",
+ "format": "xml"
+ },
+ "queryApiPolicy": {
+ "value": "[concat('', variables('queryApiValidation'), '')]",
+ "format": "xml"
+ },
+ "manageApiPolicy": {
+ "value": "[concat('', variables('manageApiValidation'), '')]",
+ "format": "xml"
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.ApiManagement/service",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[parameters('serviceName')]",
+ "location": "[parameters('location')]",
+ "sku": {
+ "name": "Developer",
+ "capacity": 1
+ },
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "publisherEmail": "[parameters('publisherEmail')]",
+ "publisherName": "[parameters('publisherName')]"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service', parameters('serviceName'))]"
+ ],
+ "properties": {
+ "displayName": "winget rest source api",
+ "description": "winget rest source api",
+ "subscriptionRequired": "[parameters('subscriptionRequired')]",
+ "path": "[parameters('apiName')]",
+ "protocols": [
+ "https"
+ ],
+ "subscriptionKeyParameterNames": {
+ "header": "Ocp-Apim-Subscription-Key",
+ "query": "subscription-key"
+ },
+ "isCurrent": true
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/namedValues",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/winget-functions-access-key')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service', parameters('serviceName'))]"
+ ],
+ "properties": {
+ "displayName": "winget-functions-access-key",
+ "keyVault": {
+ "secretIdentifier": "[concat(variables('kv_secreturi_path'), variables('kv_functionHostKey_SecretName'))]"
+ },
+ "secret": true
+ }
+ },
+ {
+ "copy": {
+ "name": "backendcopy",
+ "count": "[length(parameters('backendUrls'))]"
+ },
+ "type": "Microsoft.ApiManagement/service/backends",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[format('{0}/{1}-backend{2}', parameters('serviceName'), parameters('apiName'), copyIndex())]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/namedValues', parameters('serviceName'), 'winget-functions-access-key')]"
+ ],
+ "properties": {
+ "description": "winget rest source backend function",
+ "url": "[parameters('backendUrls')[copyIndex()]]",
+ "protocol": "http",
+ "credentials": {
+ "header": {
+ "x-functions-key": [
+ "{{winget-functions-access-key}}"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/backends",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', variables('backendPoolName'))]",
+ "dependsOn": [
+ "backendcopy"
+ ],
+ "properties": {
+ "description": "winget rest source backend function pool",
+ "type": "pool",
+ "pool": {
+ "copy": [
+ {
+ "name": "services",
+ "count": "[length(parameters('backendUrls'))]",
+ "input": {
+ "id": "[format('/backends/{0}-backend{1}', parameters('apiName'), copyIndex('services'))]"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-installerdelete')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "InstallerDelete",
+ "method": "DELETE",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/installers/{installerIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "installerIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-installerdelete/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'delete-installerdelete')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-localedelete')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "LocaleDelete",
+ "method": "DELETE",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/locales/{packageLocale}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageLocale",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-localedelete/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'delete-localedelete')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-manifestdelete')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "ManifestDelete",
+ "method": "DELETE",
+ "urlTemplate": "/packageManifests/{packageIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-manifestdelete/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'delete-manifestdelete')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-packagedelete')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "PackageDelete",
+ "method": "DELETE",
+ "urlTemplate": "/packages/{packageIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-packagedelete/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'delete-packagedelete')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-versiondelete')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "VersionDelete",
+ "method": "DELETE",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/delete-versiondelete/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'delete-versiondelete')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-informationget')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "InformationGet",
+ "method": "GET",
+ "urlTemplate": "/information"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-informationget/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'get-informationget')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('publicApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-installerget')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "InstallerGet",
+ "method": "GET",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/installers/{installerIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "installerIdentifier",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-installerget/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'get-installerget')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('queryApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-localeget')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "LocaleGet",
+ "method": "GET",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/locales/{packageLocale}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageLocale",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-localeget/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'get-localeget')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('queryApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-manifestget')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "ManifestGet",
+ "method": "GET",
+ "urlTemplate": "/packageManifests/{packageIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-manifestget/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'get-manifestget')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('queryApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-packageget')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "PackageGet",
+ "method": "GET",
+ "urlTemplate": "/packages/{packageIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-packageget/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'get-packageget')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('queryApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-versionget')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "VersionGet",
+ "method": "GET",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/get-versionget/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'get-versionget')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('queryApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-installerpost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "InstallerPost",
+ "method": "POST",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/installers",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-installerpost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-installerpost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-localepost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "LocalePost",
+ "method": "POST",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/locales",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-localepost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-localepost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-manifestpost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "ManifestPost",
+ "method": "POST",
+ "urlTemplate": "/packageManifests"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-manifestpost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-manifestpost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-manifestsearchpost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "ManifestSearchPost",
+ "method": "POST",
+ "urlTemplate": "/manifestSearch"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-manifestsearchpost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-manifestsearchpost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('queryApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-packagepost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "PackagePost",
+ "method": "POST",
+ "urlTemplate": "/packages"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-packagepost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-packagepost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-rebuildpost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "RebuildPost",
+ "method": "POST",
+ "urlTemplate": "/rebuild"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-rebuildpost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-rebuildpost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-updatepost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "UpdatePost",
+ "method": "POST",
+ "urlTemplate": "/update"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-updatepost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-updatepost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-versionpost')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "VersionPost",
+ "method": "POST",
+ "urlTemplate": "/packages/"
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/post-versionpost/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'post-versionpost')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-installerput')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "InstallerPut",
+ "method": "PUT",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/installers/{installerIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "installerIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-installerput/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'put-installerput')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-localeput')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "LocalePut",
+ "method": "PUT",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}/locales/{packageLocale}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageLocale",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-localeput/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'put-localeput')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-manifestput')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "ManifestPut",
+ "method": "PUT",
+ "urlTemplate": "/packageManifests/{packageIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-manifestput/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'put-manifestput')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-packageput')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "PackagePut",
+ "method": "PUT",
+ "urlTemplate": "/packages/{packageIdentifier}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-packageput/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'put-packageput')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-versionput')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), parameters('apiName'))]"
+ ],
+ "properties": {
+ "displayName": "VersionPut",
+ "method": "PUT",
+ "urlTemplate": "/packages/{packageIdentifier}/versions/{packageVersion}",
+ "templateParameters": [
+ {
+ "name": "packageIdentifier",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "packageVersion",
+ "required": true,
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.ApiManagement/service/apis/operations/policies",
+ "apiVersion": "2023-09-01-preview",
+ "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), '/put-versionput/policy')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('serviceName'), parameters('apiName'), 'put-versionput')]",
+ "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), variables('backendPoolName'))]"
+ ],
+ "properties": "[variables('manageApiPolicy')]"
+ }
+ ]
+}
diff --git a/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json b/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json
index e04007e2..1c385eee 100644
--- a/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json
+++ b/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json
@@ -126,39 +126,6 @@
"description": "This is the thumbprint loading Certs."
}
},
- "clientCertEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Enable Client Cert Authentication for the Function App."
- }
- },
- "clientCertMode": {
- "type": "string",
- "defaultValue": "Required",
- "allowedValues": [
- "Required",
- "OptionalInteractiveUser",
- "Optional"
- ],
- "metadata": {
- "description": "Client Cert Authentication Mode. Is only active if clientCertEnabled is set to true."
- }
- },
- "certificateAuthenticationAllowSelfSigned": {
- "type": "string",
- "defaultValue": "false",
- "metadata": {
- "description": "Whether self signed certificates are allowed as the server root/intermediate certificate."
- }
- },
- "certificateAuthenticationSubjectName": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "Subject name of the server root/intermediate certificate. The key vault of this rest souce must be provisioned manually with the appropriate root/intermediate certificate for client certificate validation."
- }
- },
"cors": {
"type": "object",
"defaultValue": {
@@ -196,17 +163,39 @@
"metadata": {
"description": "The url of the zip package of this azure function. The az function must have at least Storage Blob Data Reader role to the storage account."
}
+ },
+ "serverAuthenticationType": {
+ "type": "string",
+ "defaultValue": "none",
+ "allowedValues": [
+ "none",
+ "microsoftEntraId"
+ ],
+ "metadata": {
+ "description": "The authentication type to query the server."
+ }
+ },
+ "microsoftEntraIdResource": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Required if serverAuthenticationType is microsoftEntraId. The Microsoft EntraId target resource."
+ }
+ },
+ "microsoftEntraIdResourceScope": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. The Microsoft EntraId target resource scope."
+ }
}
},
"variables": {
"appInsightResourceId": "[resourceId(parameters('appInsightSubscription'), parameters('appInsightResourceGroup'), 'microsoft.insights/components', parameters('appInsightName'))]",
"appServiceResourceId": "[resourceId(parameters('appServiceSubscription'), parameters('appServiceResourceGroup'), 'Microsoft.Web/serverfarms/', parameters('appServiceName'))]",
- "certificateAuthenticationEnabled": "[if(parameters('clientCertEnabled'), 'true', 'false' )]",
"kv_appConfigPrimary_SecretName": "AppConfigPrimaryEndpoint",
"kv_appConfigSecondary_SecretName": "AppConfigSecondaryEndpoint",
"kv_cosmosAccountEndpoint_secretName": "CosmosAccountEndpoint",
- "kv_cosmosAccountReadKey_secretName": "CosmosReadOnlyKey",
- "kv_cosmosAccountWriteKey_secretName": "CosmosReadWriteKey",
"kv_functionHostKey_SecretName": "AzureFunctionHostKey",
"kv_restSourceApiEndpoint_SecretName": "AzFuncRestSourceEndpoint",
"kv_secreturi_path": "[concat('https://',parameters('keyVaultName'),'.vault.azure.net/secrets/')]"
@@ -235,9 +224,7 @@
"value": "[parameters('functionExtensionVersion')]"
}
],
- "httpsOnly": true,
- "clientCertEnabled": "[parameters('clientCertEnabled')]",
- "clientCertMode": "[parameters('clientCertMode')]"
+ "httpsOnly": true
},
"resources": [
{
@@ -252,9 +239,6 @@
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(variables('appInsightResourceId'), '2015-05-01').InstrumentationKey]",
"AzFuncRestSourceEndpoint": "[concat('@Microsoft.KeyVault(SecretUri=', variables('kv_secreturi_path'), variables('kv_restSourceApiEndpoint_SecretName'), '/)')]",
"AzureWebJobsStorage__accountName": "[parameters('azFuncStorageName')]",
- "CertificateAuthenticationRequired": "[variables('certificateAuthenticationEnabled')]",
- "CertificateAuthenticationSelfSigned": "[parameters('certificateAuthenticationAllowSelfSigned')]",
- "CertificateAuthenticationSubjectName": "[parameters('certificateAuthenticationSubjectName')]",
"CosmosAccountEndpoint": "[concat('@Microsoft.KeyVault(SecretUri=', variables('kv_secreturi_path'), variables('kv_cosmosAccountEndpoint_secretName'), '/)')]",
"CosmosContainer": "[parameters('cosmosContainer')]",
"CosmosDatabase": "[parameters('cosmosDatabase')]",
@@ -271,7 +255,10 @@
"WinGetRest::SubscriptionId": "[parameters('appServiceSubscription')]",
"WinGetRest:Telemetry:Metrics": "[parameters('monitoringMetricsAccount')]",
"WinGetRest:Telemetry:Role": "[parameters('monitoringRole')]",
- "WinGetRest:Telemetry:Tenant": "[parameters('monitoringTenant')]"
+ "WinGetRest:Telemetry:Tenant": "[parameters('monitoringTenant')]",
+ "ServerAuthenticationType": "[parameters('serverAuthenticationType')]",
+ "MicrosoftEntraIdResource": "[parameters('microsoftEntraIdResource')]",
+ "MicrosoftEntraIdResourceScope": "[parameters('microsoftEntraIdResourceScope')]"
}
},
{
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/ManifestSearchFunctionsTests.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/ManifestSearchFunctionsTests.cs
index 18099705..ebd908c5 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/ManifestSearchFunctionsTests.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/ManifestSearchFunctionsTests.cs
@@ -1,10 +1,10 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions
{
using System;
using System.Collections.Generic;
@@ -18,7 +18,7 @@ namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions
using Microsoft.WinGet.RestSource.IntegrationTest.Common;
using Microsoft.WinGet.RestSource.IntegrationTest.Common.Fixtures;
using Microsoft.WinGet.RestSource.IntegrationTest.Common.Helpers;
- using Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData;
+ using Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData;
using Microsoft.WinGet.RestSource.Utils.Common;
using Microsoft.WinGet.RestSource.Utils.Constants;
using Microsoft.WinGet.RestSource.Utils.Constants.Enumerations;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageFunctionsTests.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageFunctionsTests.cs
index d097e775..d7ad9b76 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageFunctionsTests.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageFunctionsTests.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions
{
using System;
using System.Collections.Generic;
@@ -15,7 +15,7 @@ namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions
using Flurl.Http;
using Microsoft.WinGet.RestSource.IntegrationTest.Common.Fixtures;
using Microsoft.WinGet.RestSource.IntegrationTest.Common.Helpers;
- using Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData;
+ using Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData;
using Microsoft.WinGet.RestSource.Utils.Constants;
using Microsoft.WinGet.RestSource.Utils.Models.ExtendedSchemas;
using Microsoft.WinGet.RestSource.Utils.Models.Schemas;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageManifestFunctionsTests.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageManifestFunctionsTests.cs
index e0b2c229..2d8ba3c3 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageManifestFunctionsTests.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/PackageManifestFunctionsTests.cs
@@ -18,7 +18,7 @@ namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions
using Microsoft.WinGet.RestSource.IntegrationTest.Common;
using Microsoft.WinGet.RestSource.IntegrationTest.Common.Fixtures;
using Microsoft.WinGet.RestSource.IntegrationTest.Common.Helpers;
- using Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData;
+ using Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData;
using Microsoft.WinGet.RestSource.Utils.Constants.Enumerations;
using Microsoft.WinGet.RestSource.Utils.Models;
using Microsoft.WinGet.RestSource.Utils.Models.ExtendedSchemas;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionDataFactory.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionDataFactory.cs
index cdada7f6..8ea60514 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionDataFactory.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionDataFactory.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData
{
using System;
using System.Collections.Generic;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionTestData.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionTestData.cs
index fec8b6f8..303f7c5f 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionTestData.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/ManifestSearchFunctionTestData.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData
{
using System;
using System.Collections.Generic;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageManifestVersionTestData.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageManifestVersionTestData.cs
index 99e4c151..1f2ebbb9 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageManifestVersionTestData.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageManifestVersionTestData.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData
{
using System.Collections.Generic;
using Microsoft.WinGet.RestSource.IntegrationTest.Common;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageTestData.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageTestData.cs
index 4a16f681..dd295e03 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageTestData.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageTestData.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData
{
using System;
using System.Collections.Generic;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageVersionTestData.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageVersionTestData.cs
index fd363d6d..e4d013e7 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageVersionTestData.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/PackageVersionTestData.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData
{
using System.Collections.Generic;
using Microsoft.WinGet.RestSource.IntegrationTest.Common;
diff --git a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/TestDataConstants.cs b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/TestDataConstants.cs
index d3a89303..9a3c327d 100644
--- a/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/TestDataConstants.cs
+++ b/src/WinGet.RestSource.IntegrationTest/Tests/Functions/TestData/TestDataConstants.cs
@@ -4,7 +4,7 @@
//
// -----------------------------------------------------------------------
-namespace Microsoft.WinGet.RestSource.IntegrationTest.Tests.Functions.TestData
+namespace Microsoft.WinGet.RestSource.IntegrationTest.Functions.TestData
{
using System;
using System.Collections.Generic;
diff --git a/src/WinGet.RestSource.IntegrationTest/WinGet.RestSource.IntegrationTest.csproj b/src/WinGet.RestSource.IntegrationTest/WinGet.RestSource.IntegrationTest.csproj
index df0d3c42..90b6f39d 100644
--- a/src/WinGet.RestSource.IntegrationTest/WinGet.RestSource.IntegrationTest.csproj
+++ b/src/WinGet.RestSource.IntegrationTest/WinGet.RestSource.IntegrationTest.csproj
@@ -58,7 +58,6 @@
-
diff --git a/src/WinGet.RestSource.UnitTest/Tests/Functions/Common/CertificateValidationHelperTest.cs b/src/WinGet.RestSource.UnitTest/Tests/Functions/Common/CertificateValidationHelperTest.cs
deleted file mode 100644
index 48e48b96..00000000
--- a/src/WinGet.RestSource.UnitTest/Tests/Functions/Common/CertificateValidationHelperTest.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
-//
-// -----------------------------------------------------------------------
-
-namespace Microsoft.Winget.RestSource.UnitTest.Tests.Functions.Common
-{
- using System;
- using System.Collections.Generic;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Primitives;
- using Microsoft.WinGet.RestSource.Functions.Common;
- using Microsoft.Winget.RestSource.UnitTest.Common.Mocks;
- using Microsoft.Winget.RestSource.UnitTest.Tests.Utils.Common;
- using Microsoft.WinGet.RestSource.Utils.Constants;
- using Microsoft.WinGet.RestSource.Utils.Exceptions;
- using Moq;
- using Xunit;
- using Xunit.Abstractions;
-
- ///
- /// Certificate Validation Helper Test.
- ///
- public class CertificateValidationHelperTest : IDisposable
- {
- private const string Payload = "Payload";
- private const string CertSubject = "devauth";
- private const string Cert = "MIIDKjCCAhKgAwIBAgIQZCpkZ//ETPK6BVAsqAfmhjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwdkZXZhdXRoMB4XDTIyMDcwNTIwNTQwNVoXDTMyMDcwNTIxMDQwNVowEjEQMA4GA1UEAxMHZGV2YXV0aDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANvLHTeBoQya1vMxmJl1xmd1+V1lGKFlUadAy3xGMIIvB5o7fbTMtv1PnZ9VF25DoYNGBNZznZYVck0ZXqX0FsEB5iA2gENg9sk5sOAF8pQnSYNSZx1ABCnLNpQfYYk0U/DziHbHCqc5sVIoI2TzoeRrPh4W5kXLloys4anY15LrR++lEmiDDnpL8WUR2XKia28/UWEG84xMbz4WZ0J0yltmfw2xigWFf+BPqDJVBJ4MTW62BXIKjaJT7XX5EMWGnPZz7BlznrQqcRw845gGFNjDN8bvdKmx9IVOhQeOBfvZmo9jARrk+ODO97o32jQOfYDKyWdNEXOPZrD6AZx4hG0CAwEAAaN8MHowDgYDVR0PAQH/BAQDAgWgMAkGA1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFEMiX/5DITRc8rm2HQz63EAqtXPZMB0GA1UdDgQWBBRDIl/+QyE0XPK5th0M+txAKrVz2TANBgkqhkiG9w0BAQsFAAOCAQEA1Xc0Mo1Ex6aXlZHkfJn0yZVa/+6z0QFK95D+9wWZ4K5v4lGvANLNxU28IlJyg3kJ8kV720WR4NYsyCcn6mWxNHYKxivO/xhoDsIgIllsJcvC4GWeUx+67xeNPQuSH20IZuNSqMoqpD5+aedzk24pVkWudIz5sEWE0+TGik4y6DeqWIhNIzSphlUYODaAbMTFn40rI4Afugv6518FkVFyZKYX/mDgD/jn2RarOph2k3ffJY3gclQ0yH4DggAA82vF35j2B5xKzBBnuF5AlojjDM9oHLukVYDtGs5yAfMAebRK7TAtcQjpzIPZv7jseW7LBBdKO5A9cQxKEBAIOa33Dw==";
- private const string UserAgentHeaderTitle = "User-Agent";
- private const string UserAgentHeaderValue = "Agent2";
- private readonly ITestOutputHelper log;
- private readonly Mock loggerMock = new Mock();
- private EnvironmentVariables env;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// ITestOutputHelper.
- public CertificateValidationHelperTest(ITestOutputHelper log)
- {
- this.log = log;
- Dictionary environmentVars = new Dictionary()
- {
- [ApiConstants.CertificateAuthenticationRequiredEnvName] = "false",
- [ApiConstants.CertificateAuthenticationSelfSignedEnvName] = "true",
- [ApiConstants.CertificateAuthenticationSubjectNameEnvName] = CertSubject,
- };
- this.env = EnvironmentVariables.PrepareEnvironmentVariable(environmentVars);
- }
-
- ///
- public void Dispose()
- {
- EnvironmentVariables.RestoreEnvironmentVariables(this.env, new List()
- {
- ApiConstants.CertificateAuthenticationRequiredEnvName,
- });
- }
-
- ///
- /// This verifies that the auth function exits successfully when disabled.
- ///
- [Fact]
- public void DisabledAuth()
- {
- // Disable Cert Auth
- this.env.BackupIfNeededAndReplace(ApiConstants.CertificateAuthenticationRequiredEnvName, "false");
-
- // Execute Validation
- Mock request = MoqHTTPRequest.CreateMockRequest(
- Payload,
- new HeaderDictionary(new Dictionary
- {
- { UserAgentHeaderTitle, UserAgentHeaderValue },
- }));
- CertificateValidationHelper.ValidateAuthentication(null, null);
- }
-
- ///
- /// This verifies that the auth function exits successfully when disabled.
- ///
- [Fact]
- public void EnabledAuthNoCert()
- {
- // Enable Cert Auth
- this.env.BackupIfNeededAndReplace(ApiConstants.CertificateAuthenticationRequiredEnvName, "true");
-
- // Create Payload
- Mock request = MoqHTTPRequest.CreateMockRequest(
- Payload,
- new HeaderDictionary(new Dictionary
- {
- { UserAgentHeaderTitle, UserAgentHeaderValue },
- }));
-
- // Verify Failure
- Assert.Throws(() => CertificateValidationHelper.ValidateAuthentication(request.Object, null));
- }
-
- ///
- /// This verifies that the auth function exits successfully when disabled.
- ///
- [Fact]
- public void EnabledAuthCertValidCertNotConfigured()
- {
- // Disable Cert Auth
- this.env.BackupIfNeededAndReplace(ApiConstants.CertificateAuthenticationRequiredEnvName, "true");
-
- // Create Payload
- Mock request = MoqHTTPRequest.CreateMockRequest(
- Payload,
- new HeaderDictionary(new Dictionary
- {
- { UserAgentHeaderTitle, UserAgentHeaderValue },
- { HeaderConstants.XARRClientCert, Cert },
- }));
-
- // Verify Failure
- Assert.Throws(() => CertificateValidationHelper.ValidateAuthentication(request.Object, this.loggerMock.Object));
- }
- }
-}
diff --git a/src/WinGet.RestSource.UnitTest/Tests/RestSource/Cosmos/CosmosDataStoreTests.cs b/src/WinGet.RestSource.UnitTest/Tests/RestSource/Cosmos/CosmosDataStoreTests.cs
index 975c0b16..82efb867 100644
--- a/src/WinGet.RestSource.UnitTest/Tests/RestSource/Cosmos/CosmosDataStoreTests.cs
+++ b/src/WinGet.RestSource.UnitTest/Tests/RestSource/Cosmos/CosmosDataStoreTests.cs
@@ -70,7 +70,7 @@ public CosmosDataStoreTests(ITestOutputHelper log)
this.log.WriteLine($"{CosmosConnectionConstants.ContainerNameSetting}: {containerId}");
var logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger();
- this.cosmosDataStore = new CosmosDataStore(logger, endpoint, readWriteKey, readOnlyKey, databaseId, containerId);
+ this.cosmosDataStore = new CosmosDataStore(logger, endpoint, databaseId, containerId, readOnlyKey, readWriteKey);
}
///
diff --git a/src/WinGet.RestSource.UnitTest/WinGet.RestSource.UnitTest.csproj b/src/WinGet.RestSource.UnitTest/WinGet.RestSource.UnitTest.csproj
index e6d05b53..89009b13 100644
--- a/src/WinGet.RestSource.UnitTest/WinGet.RestSource.UnitTest.csproj
+++ b/src/WinGet.RestSource.UnitTest/WinGet.RestSource.UnitTest.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
@@ -51,7 +51,6 @@
-
diff --git a/src/WinGet.RestSource.Utils/Common/HeaderProcessor.cs b/src/WinGet.RestSource.Utils/Common/HeaderProcessor.cs
index 656784e4..8a0ef915 100644
--- a/src/WinGet.RestSource.Utils/Common/HeaderProcessor.cs
+++ b/src/WinGet.RestSource.Utils/Common/HeaderProcessor.cs
@@ -79,7 +79,7 @@ private static void ProcessContinuationToken(Dictionary headers,
{
throw new InvalidArgumentException(
new InternalRestError(
- ErrorConstants.ToManyContinuationTokensErrorCode,
+ ErrorConstants.TooManyContinuationTokensErrorCode,
ErrorConstants.ToManyContinuationTokensErrorMessage));
}
diff --git a/src/WinGet.RestSource.Utils/Constants/ApiConstants.cs b/src/WinGet.RestSource.Utils/Constants/ApiConstants.cs
index c8f1e8c8..a67001d8 100644
--- a/src/WinGet.RestSource.Utils/Constants/ApiConstants.cs
+++ b/src/WinGet.RestSource.Utils/Constants/ApiConstants.cs
@@ -20,34 +20,34 @@ public class ApiConstants
public const string AzFuncRestSourceEndpointEnvName = "AzFuncRestSourceEndpoint";
///
- /// CertificateAuthenticationRequiredName environmental variable name.
+ /// FunctionHostKey environmental variable name.
///
- public const string CertificateAuthenticationRequiredEnvName = "CertificateAuthenticationRequired";
+ public const string FunctionHostKeyEnvName = "FunctionHostKey";
///
- /// CertificateAuthenticationSelfSigned environmental variable name.
+ /// ManifestCacheEndpoint environmental variable name.
///
- public const string CertificateAuthenticationSelfSignedEnvName = "CertificateAuthenticationSelfSigned";
+ public const string ManifestCacheEndpointEnvName = "ManifestCacheEndpoint";
///
- /// CertificateAuthenticationSubjectName environmental variable name.
+ /// ServerIdentifier environmental variable name.
///
- public const string CertificateAuthenticationSubjectNameEnvName = "CertificateAuthenticationSubjectName";
+ public const string ServerIdentifierEnvName = "ServerIdentifier";
///
- /// FunctionHostKey environmental variable name.
+ /// ServerAuthenticationType environmental variable name.
///
- public const string FunctionHostKeyEnvName = "FunctionHostKey";
+ public const string ServerAuthenticationTypeEnvName = "ServerAuthenticationType";
///
- /// ManifestCacheEndpoint environmental variable name.
+ /// MicrosoftEntraIdResource environmental variable name.
///
- public const string ManifestCacheEndpointEnvName = "ManifestCacheEndpoint";
+ public const string MicrosoftEntraIdResourceEnvName = "MicrosoftEntraIdResource";
///
- /// ServerIdentifier environmental variable name.
+ /// MicrosoftEntraIdResourceScope environmental variable name.
///
- public const string ServerIdentifierEnvName = "ServerIdentifier";
+ public const string MicrosoftEntraIdResourceScopeEnvName = "MicrosoftEntraIdResourceScope";
///
/// Server Supported Versions.
@@ -63,7 +63,11 @@ public class ApiConstants
};
///
- /// Server Supported Versions.
+ /// Min version for Microsoft Entra Id support.
+ ///
+ public static readonly string MinVersionForMicrosoftEntraId = "1.7.0";
+
+ ///
/// Unsupported package match fields.
/// TODO: NormalizedPackageNameAndPublisher field support is currently not implemented.
/// GitHub Issue: https://github.com/microsoft/winget-cli-restsource/issues/59.
@@ -97,48 +101,33 @@ public class ApiConstants
public static string AzFuncRestSourceEndpoint => Environment.GetEnvironmentVariable(AzFuncRestSourceEndpointEnvName);
///
- /// Gets whether certificate authentication is enabled.
- ///
- public static string CertificateAuthenticationRequiredEnv => Environment.GetEnvironmentVariable(CertificateAuthenticationRequiredEnvName);
-
- ///
- /// Gets a value indicating whether certificate authentication is enabled.
- ///
- public static bool CertificateAuthenticationRequired => bool.Parse(ApiConstants.CertificateAuthenticationRequiredEnv);
-
- ///
- /// Gets whether self signed certificates are allowed.
- ///
- public static string CertificateAuthenticationSelfSignedEnv => Environment.GetEnvironmentVariable(CertificateAuthenticationSelfSignedEnvName);
-
- ///
- /// Gets a value indicating whether self signed certificates are allowed as the root/intermediate certificate.
+ /// Gets Functions host key.
///
- public static bool CertificateAuthenticationSelfSigned => bool.Parse(ApiConstants.CertificateAuthenticationSelfSignedEnv);
+ public static string AzureFunctionHostKey => Environment.GetEnvironmentVariable(FunctionHostKeyEnvName);
///
- /// Gets the expected root/intermediate cert subject name.
+ /// Gets manifest cache endpoint.
///
- public static string CertificateAuthenticationSubjectNameEnv => Environment.GetEnvironmentVariable(CertificateAuthenticationSubjectNameEnvName);
+ public static string ManifestCacheEndpoint => Environment.GetEnvironmentVariable(ManifestCacheEndpointEnvName);
///
- /// Gets Subject name of the root/intermediate certificate.
+ /// Gets server identifier.
///
- public static string CertificateAuthenticationSubjectName => ApiConstants.CertificateAuthenticationSubjectNameEnv;
+ public static string ServerIdentifier => Environment.GetEnvironmentVariable(ServerIdentifierEnvName);
///
- /// Gets Functions host key.
+ /// Gets Microsoft Entra Id resource.
///
- public static string AzureFunctionHostKey => Environment.GetEnvironmentVariable(FunctionHostKeyEnvName);
+ public static string ServerAuthenticationType => Environment.GetEnvironmentVariable(ServerAuthenticationTypeEnvName);
///
- /// Gets manifest cache endpoint.
+ /// Gets Microsoft Entra Id resource.
///
- public static string ManifestCacheEndpoint => Environment.GetEnvironmentVariable(ManifestCacheEndpointEnvName);
+ public static string MicrosoftEntraIdResource => Environment.GetEnvironmentVariable(MicrosoftEntraIdResourceEnvName);
///
- /// Gets server Identifier.
+ /// Gets optional Microsoft Entra Id resource scope.
///
- public static string ServerIdentifier => Environment.GetEnvironmentVariable(ServerIdentifierEnvName);
+ public static string MicrosoftEntraIdResourceScope => Environment.GetEnvironmentVariable(MicrosoftEntraIdResourceScopeEnvName);
}
}
diff --git a/src/WinGet.RestSource.Utils/Constants/Enumerations/AuthenticationType.cs b/src/WinGet.RestSource.Utils/Constants/Enumerations/AuthenticationType.cs
new file mode 100644
index 00000000..7500d238
--- /dev/null
+++ b/src/WinGet.RestSource.Utils/Constants/Enumerations/AuthenticationType.cs
@@ -0,0 +1,24 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------
+
+namespace Microsoft.WinGet.RestSource.Utils.Constants.Enumerations
+{
+ ///
+ /// Authentication Type Constants.
+ ///
+ public class AuthenticationType
+ {
+ ///
+ /// None.
+ ///
+ public const string None = "none";
+
+ ///
+ /// MicrosoftEntraId.
+ ///
+ public const string MicrosoftEntraId = "microsoftEntraId";
+ }
+}
diff --git a/src/WinGet.RestSource.Utils/Constants/ErrorConstants.cs b/src/WinGet.RestSource.Utils/Constants/ErrorConstants.cs
index 0716077f..b8891c5d 100644
--- a/src/WinGet.RestSource.Utils/Constants/ErrorConstants.cs
+++ b/src/WinGet.RestSource.Utils/Constants/ErrorConstants.cs
@@ -196,7 +196,7 @@ public class ErrorConstants
///
/// This is the code for when to many continuation tokens are provided.
///
- public const int ToManyContinuationTokensErrorCode = 19;
+ public const int TooManyContinuationTokensErrorCode = 19;
///
/// This is the message for when to many continuation tokens are provided.
@@ -204,16 +204,10 @@ public class ErrorConstants
public const string ToManyContinuationTokensErrorMessage = "To many continuations were provided to the server.";
///
- /// This is the code for an invalid certificate.
+ /// This is the code for forbidden.
///
public const int ForbiddenErrorCode = 403;
- ///
- /// This is the message for a invalid certificate.
- ///
- public const string ForbiddenErrorMessage =
- "The client must provide a trusted certificate for {0}";
-
///
/// This is the code for a resource not found.
///
diff --git a/src/WinGet.RestSource.Utils/Exceptions/ForbiddenException.cs b/src/WinGet.RestSource.Utils/Exceptions/ForbiddenException.cs
index 94ec4dab..af26c5a1 100644
--- a/src/WinGet.RestSource.Utils/Exceptions/ForbiddenException.cs
+++ b/src/WinGet.RestSource.Utils/Exceptions/ForbiddenException.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -10,7 +10,7 @@ namespace Microsoft.WinGet.RestSource.Utils.Exceptions
using Microsoft.WinGet.RestSource.Utils.Models.Errors;
///
- /// This is for exceptions that occur when validating client certificates.
+ /// This is for exceptions that occur when validating client identities.
///
public class ForbiddenException : DefaultException
{
diff --git a/src/WinGet.RestSource.Utils/Models/Core/ApiArray.cs b/src/WinGet.RestSource.Utils/Models/Core/ApiArray.cs
index e2d70016..79e6145c 100644
--- a/src/WinGet.RestSource.Utils/Models/Core/ApiArray.cs
+++ b/src/WinGet.RestSource.Utils/Models/Core/ApiArray.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -69,7 +69,7 @@ public ApiArray(IEnumerable enumerable)
protected uint MaxItems { get; set; }
///
- /// Gets or sets MaxItems.
+ /// Gets or sets MemberValidator.
///
protected Type MemberValidator { get; set; }
diff --git a/src/WinGet.RestSource.Utils/Models/Objects/Authentication.cs b/src/WinGet.RestSource.Utils/Models/Objects/Authentication.cs
new file mode 100644
index 00000000..56f9ead0
--- /dev/null
+++ b/src/WinGet.RestSource.Utils/Models/Objects/Authentication.cs
@@ -0,0 +1,103 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------
+
+namespace Microsoft.WinGet.RestSource.Utils.Models.Objects
+{
+ using System.Collections.Generic;
+ using System.ComponentModel.DataAnnotations;
+ using Microsoft.WinGet.RestSource.Utils.Models.Core;
+ using Microsoft.WinGet.RestSource.Utils.Validators;
+ using Microsoft.WinGet.RestSource.Utils.Validators.EnumValidators;
+ using Microsoft.WinGet.RestSource.Utils.Validators.StringValidators;
+
+ ///
+ /// Authentication.
+ ///
+ public class Authentication : IApiObject
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Authentication()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Authentication.
+ public Authentication(Authentication authentication)
+ {
+ this.Update(authentication);
+ }
+
+ ///
+ /// Gets or sets AuthenticationType.
+ ///
+ [AuthenticationTypeValidator]
+ public string AuthenticationType { get; set; }
+
+ ///
+ /// Gets or sets MicrosoftEntraIdAuthenticationInfo.
+ ///
+ public MicrosoftEntraIdAuthenticationInfo MicrosoftEntraIdAuthenticationInfo { get; set; }
+
+ ///
+ /// Operator==.
+ ///
+ /// Left.
+ /// Right.
+ /// Bool.
+ public static bool operator ==(Authentication left, Authentication right)
+ {
+ return Equals(left, right);
+ }
+
+ ///
+ /// Operator!=.
+ ///
+ /// Left.
+ /// Right.
+ /// Bool.
+ public static bool operator !=(Authentication left, Authentication right)
+ {
+ return !Equals(left, right);
+ }
+
+ ///
+ public void Update(Authentication obj)
+ {
+ this.AuthenticationType = obj.AuthenticationType;
+ this.MicrosoftEntraIdAuthenticationInfo = obj.MicrosoftEntraIdAuthenticationInfo;
+ }
+
+ ///
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+ // No custom validation
+ return new List();
+ }
+
+ ///
+ public bool Equals(Authentication other)
+ {
+ return (this.AuthenticationType, this.MicrosoftEntraIdAuthenticationInfo) ==
+ (other.AuthenticationType, other.MicrosoftEntraIdAuthenticationInfo);
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj is Authentication auth && this.Equals(auth);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return (this.AuthenticationType, this.MicrosoftEntraIdAuthenticationInfo).GetHashCode();
+ }
+ }
+}
diff --git a/src/WinGet.RestSource.Utils/Models/Objects/MicrosoftEntraIdAuthenticationInfo.cs b/src/WinGet.RestSource.Utils/Models/Objects/MicrosoftEntraIdAuthenticationInfo.cs
new file mode 100644
index 00000000..a409cadd
--- /dev/null
+++ b/src/WinGet.RestSource.Utils/Models/Objects/MicrosoftEntraIdAuthenticationInfo.cs
@@ -0,0 +1,105 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------
+
+namespace Microsoft.WinGet.RestSource.Utils.Models.Objects
+{
+ using System.Collections.Generic;
+ using System.ComponentModel.DataAnnotations;
+ using System.Linq;
+ using Microsoft.WinGet.RestSource.Utils.Constants;
+ using Microsoft.WinGet.RestSource.Utils.Models.Core;
+ using Microsoft.WinGet.RestSource.Utils.Validators;
+ using Microsoft.WinGet.RestSource.Utils.Validators.EnumValidators;
+ using Microsoft.WinGet.RestSource.Utils.Validators.StringValidators;
+
+ ///
+ /// MicrosoftEntraIdAuthenticationInfo.
+ ///
+ public class MicrosoftEntraIdAuthenticationInfo : IApiObject
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MicrosoftEntraIdAuthenticationInfo()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// MicrosoftEntraIdAuthenticationInfo.
+ public MicrosoftEntraIdAuthenticationInfo(MicrosoftEntraIdAuthenticationInfo authInfo)
+ {
+ this.Update(authInfo);
+ }
+
+ ///
+ /// Gets or sets Resource.
+ ///
+ [MicrosoftEntraIdResourceValidator]
+ public string Resource { get; set; }
+
+ ///
+ /// Gets or sets Scope.
+ ///
+ [MicrosoftEntraIdResourceScopeValidator]
+ public string Scope { get; set; }
+
+ ///
+ /// Operator==.
+ ///
+ /// Left.
+ /// Right.
+ /// Bool.
+ public static bool operator ==(MicrosoftEntraIdAuthenticationInfo left, MicrosoftEntraIdAuthenticationInfo right)
+ {
+ return Equals(left, right);
+ }
+
+ ///
+ /// Operator!=.
+ ///
+ /// Left.
+ /// Right.
+ /// Bool.
+ public static bool operator !=(MicrosoftEntraIdAuthenticationInfo left, MicrosoftEntraIdAuthenticationInfo right)
+ {
+ return !Equals(left, right);
+ }
+
+ ///
+ public void Update(MicrosoftEntraIdAuthenticationInfo obj)
+ {
+ this.Resource = obj.Resource;
+ this.Scope = obj.Scope;
+ }
+
+ ///
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+ // No custom validation
+ return new List();
+ }
+
+ ///
+ public bool Equals(MicrosoftEntraIdAuthenticationInfo other)
+ {
+ return (this.Resource, this.Scope) == (other.Resource, other.Scope);
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj is MicrosoftEntraIdAuthenticationInfo authInfo && this.Equals(authInfo);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return (this.Resource, this.Scope).GetHashCode();
+ }
+ }
+}
diff --git a/src/WinGet.RestSource.Utils/Models/Schemas/Information.cs b/src/WinGet.RestSource.Utils/Models/Schemas/Information.cs
index bc5fb513..423a50fb 100644
--- a/src/WinGet.RestSource.Utils/Models/Schemas/Information.cs
+++ b/src/WinGet.RestSource.Utils/Models/Schemas/Information.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -6,7 +6,10 @@
namespace Microsoft.WinGet.RestSource.Utils.Models.Schemas
{
+ using System;
+ using System.Linq;
using Microsoft.WinGet.RestSource.Utils.Constants;
+ using Microsoft.WinGet.RestSource.Utils.Constants.Enumerations;
using Microsoft.WinGet.RestSource.Utils.Models.Arrays;
using Microsoft.WinGet.RestSource.Utils.Models.Objects;
using Microsoft.WinGet.RestSource.Utils.Validators.StringValidators;
@@ -23,11 +26,35 @@ public Information()
{
if (string.IsNullOrEmpty(ApiConstants.ServerIdentifier))
{
- throw new System.ArgumentNullException("SourceIdentifier environment variable is not configured and needs to be setup.");
+ throw new ArgumentNullException("SourceIdentifier environment variable is not configured and needs to be setup.");
}
this.SourceIdentifier = ApiConstants.ServerIdentifier;
- this.ServerSupportedVersions = ApiConstants.ServerSupportedVersions;
+
+ if (string.IsNullOrEmpty(ApiConstants.ServerAuthenticationType) ||
+ AuthenticationType.None.Equals(ApiConstants.ServerAuthenticationType, StringComparison.OrdinalIgnoreCase))
+ {
+ this.ServerSupportedVersions = this.GetServerSupportedVersions();
+ }
+ else if (AuthenticationType.MicrosoftEntraId.Equals(ApiConstants.ServerAuthenticationType, StringComparison.OrdinalIgnoreCase))
+ {
+ if (string.IsNullOrEmpty(ApiConstants.MicrosoftEntraIdResource))
+ {
+ throw new ArgumentNullException("MicrosoftEntraIdResource environment variable is not configured and needs to be setup when authentication type is Microsoft Entra Id.");
+ }
+
+ this.ServerSupportedVersions = this.GetServerSupportedVersions(ApiConstants.MinVersionForMicrosoftEntraId);
+
+ this.Authentication = new Authentication();
+ this.Authentication.AuthenticationType = AuthenticationType.MicrosoftEntraId;
+ this.Authentication.MicrosoftEntraIdAuthenticationInfo = new MicrosoftEntraIdAuthenticationInfo();
+ this.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource = ApiConstants.MicrosoftEntraIdResource;
+ this.Authentication.MicrosoftEntraIdAuthenticationInfo.Scope = ApiConstants.MicrosoftEntraIdResourceScope;
+ }
+ else
+ {
+ throw new ArgumentException($"Authentication type not recognized: {ApiConstants.ServerAuthenticationType}");
+ }
this.UnsupportedPackageMatchFields = ApiConstants.UnsupportedPackageMatchFields;
this.RequiredPackageMatchFields = ApiConstants.RequiredPackageMatchFields;
@@ -54,12 +81,12 @@ public Information()
///
/// Gets UnsupportedPackageMatchFields.
///
- public PackageMatchFields UnsupportedPackageMatchFields { get; }
+ public Arrays.PackageMatchFields UnsupportedPackageMatchFields { get; }
///
/// Gets RequiredPackageMatchFields.
///
- public PackageMatchFields RequiredPackageMatchFields { get; }
+ public Arrays.PackageMatchFields RequiredPackageMatchFields { get; }
///
/// Gets UnsupportedQueryParameters.
@@ -70,5 +97,23 @@ public Information()
/// Gets RequiredQueryParameters.
///
public QueryParameters RequiredQueryParameters { get; }
+
+ ///
+ /// Gets Authentication.
+ ///
+ public Authentication Authentication { get; }
+
+ private ApiVersions GetServerSupportedVersions(string minVersion = null)
+ {
+ var result = ApiConstants.ServerSupportedVersions;
+
+ if (!string.IsNullOrEmpty(minVersion))
+ {
+ result = new ApiVersions();
+ result.AddRange(ApiConstants.ServerSupportedVersions.Where(v => new System.Version(v) >= new System.Version(minVersion)));
+ }
+
+ return result;
+ }
}
}
diff --git a/src/WinGet.RestSource.Utils/Validators/EnumValidators/AuthenticationTypeValidator.cs b/src/WinGet.RestSource.Utils/Validators/EnumValidators/AuthenticationTypeValidator.cs
new file mode 100644
index 00000000..d624db6a
--- /dev/null
+++ b/src/WinGet.RestSource.Utils/Validators/EnumValidators/AuthenticationTypeValidator.cs
@@ -0,0 +1,33 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------
+
+namespace Microsoft.WinGet.RestSource.Utils.Validators.EnumValidators
+{
+ using System.Collections.Generic;
+ using Microsoft.WinGet.RestSource.Utils.Constants.Enumerations;
+
+ ///
+ /// AuthenticationTypeValidator.
+ ///
+ public class AuthenticationTypeValidator : ApiEnumValidator
+ {
+ private const bool Nullable = false;
+ private List enumList = new List
+ {
+ AuthenticationType.None,
+ AuthenticationType.MicrosoftEntraId,
+ };
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AuthenticationTypeValidator()
+ {
+ this.AllowNull = Nullable;
+ this.Values = this.enumList;
+ }
+ }
+}
diff --git a/src/WinGet.RestSource.Utils/Validators/StringValidators/MicrosoftEntraIdResourceScopeValidator.cs b/src/WinGet.RestSource.Utils/Validators/StringValidators/MicrosoftEntraIdResourceScopeValidator.cs
new file mode 100644
index 00000000..9d523c97
--- /dev/null
+++ b/src/WinGet.RestSource.Utils/Validators/StringValidators/MicrosoftEntraIdResourceScopeValidator.cs
@@ -0,0 +1,28 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------
+
+namespace Microsoft.WinGet.RestSource.Utils.Validators.StringValidators
+{
+ ///
+ /// MicrosoftEntraIdResourceScopeValidator.
+ ///
+ public class MicrosoftEntraIdResourceScopeValidator : ApiStringValidator
+ {
+ private const bool Nullable = true;
+ private const uint Max = 512;
+ private const uint Min = 1;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MicrosoftEntraIdResourceScopeValidator()
+ {
+ this.AllowNull = Nullable;
+ this.MaxLength = Max;
+ this.MinLength = Min;
+ }
+ }
+}
diff --git a/src/WinGet.RestSource.Utils/Validators/StringValidators/MicrosoftEntraIdResourceValidator.cs b/src/WinGet.RestSource.Utils/Validators/StringValidators/MicrosoftEntraIdResourceValidator.cs
new file mode 100644
index 00000000..e808e287
--- /dev/null
+++ b/src/WinGet.RestSource.Utils/Validators/StringValidators/MicrosoftEntraIdResourceValidator.cs
@@ -0,0 +1,28 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------
+
+namespace Microsoft.WinGet.RestSource.Utils.Validators.StringValidators
+{
+ ///
+ /// MicrosoftEntraIdResourceValidator.
+ ///
+ public class MicrosoftEntraIdResourceValidator : ApiStringValidator
+ {
+ private const bool Nullable = false;
+ private const uint Max = 512;
+ private const uint Min = 1;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MicrosoftEntraIdResourceValidator()
+ {
+ this.AllowNull = Nullable;
+ this.MaxLength = Max;
+ this.MinLength = Min;
+ }
+ }
+}
diff --git a/src/WinGet.RestSource.Utils/WinGet.RestSource.Utils.csproj b/src/WinGet.RestSource.Utils/WinGet.RestSource.Utils.csproj
index e583fd7a..2afd5158 100644
--- a/src/WinGet.RestSource.Utils/WinGet.RestSource.Utils.csproj
+++ b/src/WinGet.RestSource.Utils/WinGet.RestSource.Utils.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
@@ -51,7 +51,6 @@
-
diff --git a/src/WinGet.RestSource/Cosmos/CosmosDataStore.cs b/src/WinGet.RestSource/Cosmos/CosmosDataStore.cs
index 7dd5036b..fab0679d 100644
--- a/src/WinGet.RestSource/Cosmos/CosmosDataStore.cs
+++ b/src/WinGet.RestSource/Cosmos/CosmosDataStore.cs
@@ -1,4 +1,4 @@
-// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
//
@@ -51,18 +51,31 @@ public class CosmosDataStore : IApiDataStore
*/
};
+ ///
+ /// Initializes a new instance of the class with default credentials.
+ ///
+ /// Log.
+ /// Service Endpoint.
+ /// Database.
+ /// Database container.
+ public CosmosDataStore(ILogger log, string serviceEndpoint, string databaseId, string containerId)
+ {
+ this.cosmosDatabase = new CosmosDatabase(serviceEndpoint, databaseId, containerId);
+ this.log = log;
+ }
+
///
/// Initializes a new instance of the class.
///
/// Log.
/// Service Endpoint.
- /// Authorization Key with read-write permissions.
- /// Authorization Key with read-only permissions.
/// Database.
/// Database container.
- public CosmosDataStore(ILogger log, string serviceEndpoint, string readWriteKey, string readOnlyKey, string databaseId, string containerId)
+ /// Authorization Key with read-only permissions.
+ /// Authorization Key with read-write permissions.
+ public CosmosDataStore(ILogger log, string serviceEndpoint, string databaseId, string containerId, string readOnlyKey, string readWriteKey)
{
- this.cosmosDatabase = new CosmosDatabase(serviceEndpoint, readWriteKey, readOnlyKey, databaseId, containerId);
+ this.cosmosDatabase = new CosmosDatabase(serviceEndpoint, databaseId, containerId, readOnlyKey, readWriteKey);
this.log = log;
}
diff --git a/src/WinGet.RestSource/Cosmos/CosmosDatabase.cs b/src/WinGet.RestSource/Cosmos/CosmosDatabase.cs
index 03fa1cfa..d6bfbea0 100644
--- a/src/WinGet.RestSource/Cosmos/CosmosDatabase.cs
+++ b/src/WinGet.RestSource/Cosmos/CosmosDatabase.cs
@@ -33,34 +33,41 @@ public class CosmosDatabase : ICosmosDatabase
// Container use for read-only database operations.
private readonly Container readOnlyContainer;
+ ///
+ /// Initializes a new instance of the class with default credentials.
+ ///
+ /// Service Endpoint.
+ /// Database.
+ /// Database container.
+ public CosmosDatabase(string serviceEndpoint, string databaseId, string containerId)
+ {
+ this.databaseId = databaseId;
+ this.containerId = containerId;
+
+ // The azure function will have read and write roles. It doesn't make a lot of sense
+ // to have to user managed identity just to split it if the same resource have both roles.
+ this.readWriteClient = new CosmosClient(serviceEndpoint, new DefaultAzureCredential());
+ this.readOnlyContainer = this.readWriteContainer = this.readWriteClient.GetContainer(databaseId, containerId);
+ }
+
///
/// Initializes a new instance of the class.
///
/// Service Endpoint.
- /// Authorization Key with read-write permissions.
- /// Authorization Key with read-only permissions.
/// Database.
/// Database container.
- public CosmosDatabase(string serviceEndpoint, string readWriteKey, string readOnlyKey, string databaseId, string containerId)
+ /// Authorization Key with read-only permissions.
+ /// Authorization Key with read-write permissions.
+ public CosmosDatabase(string serviceEndpoint, string databaseId, string containerId, string readOnlyKey, string readWriteKey)
{
this.databaseId = databaseId;
this.containerId = containerId;
- if (!string.IsNullOrEmpty(readWriteKey) && !string.IsNullOrEmpty(readOnlyKey))
- {
- var readOnlyClient = new CosmosClient(serviceEndpoint, readOnlyKey);
- this.readOnlyContainer = readOnlyClient.GetContainer(databaseId, containerId);
+ var readOnlyClient = new CosmosClient(serviceEndpoint, readOnlyKey);
+ this.readOnlyContainer = readOnlyClient.GetContainer(databaseId, containerId);
- this.readWriteClient = new CosmosClient(serviceEndpoint, readWriteKey);
- this.readWriteContainer = this.readWriteClient.GetContainer(databaseId, containerId);
- }
- else
- {
- // The azure function will have read and write roles. It doesn't make a lot of sense
- // to have to user managed identity just to split it if the same resource have both roles.
- this.readWriteClient = new CosmosClient(serviceEndpoint, new DefaultAzureCredential());
- this.readOnlyContainer = this.readWriteContainer = this.readWriteClient.GetContainer(databaseId, containerId);
- }
+ this.readWriteClient = new CosmosClient(serviceEndpoint, readWriteKey);
+ this.readWriteContainer = this.readWriteClient.GetContainer(databaseId, containerId);
}
///
diff --git a/src/WinGet.RestSource/WinGet.RestSource.csproj b/src/WinGet.RestSource/WinGet.RestSource.csproj
index c4622315..21614470 100644
--- a/src/WinGet.RestSource/WinGet.RestSource.csproj
+++ b/src/WinGet.RestSource/WinGet.RestSource.csproj
@@ -52,7 +52,6 @@
-