From 37e2cd340bfae8d4b7467baae5a4e43a500d86e1 Mon Sep 17 00:00:00 2001 From: Ashwini Patil Date: Thu, 25 Mar 2021 23:25:38 -0700 Subject: [PATCH 1/2] Fixing endpoint and checking field value presence in json deserialization --- .../AppInstallerRepositoryCore.vcxproj | 2 + ...AppInstallerRepositoryCore.vcxproj.filters | 6 +++ .../Rest/RestClient.cpp | 3 +- .../Rest/Schema/1_0/Interface.cpp | 13 +---- .../Rest/Schema/Json/ManifestDeserializer.cpp | 54 ++++++++++++------- .../Rest/Schema/RestHelper.cpp | 17 ++++++ .../Rest/Schema/RestHelper.h | 12 +++++ 7 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.h diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj index d9bfa7eafe..70af4932e3 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj @@ -216,6 +216,7 @@ + @@ -266,6 +267,7 @@ + diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters index 3210bf6c2c..a755eef116 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters @@ -198,6 +198,9 @@ Rest\Schema\Json + + Rest\Schema + @@ -302,6 +305,9 @@ Rest\Schema\Json + + Rest\Schema + diff --git a/src/AppInstallerRepositoryCore/Rest/RestClient.cpp b/src/AppInstallerRepositoryCore/Rest/RestClient.cpp index 0a7fa35eda..36e7ea2bb4 100644 --- a/src/AppInstallerRepositoryCore/Rest/RestClient.cpp +++ b/src/AppInstallerRepositoryCore/Rest/RestClient.cpp @@ -7,6 +7,7 @@ #include "Rest/Schema/Json/InformationResponseDeserializer.h" #include "Rest/Schema/Json/JsonHelper.h" #include "Rest/Schema/Json/CommonRestConstants.h" +#include "Rest/Schema/RestHelper.h" using namespace AppInstaller::Repository::Rest::Schema; using namespace AppInstaller::Repository::Rest::Schema::Json; @@ -30,7 +31,7 @@ namespace AppInstaller::Repository::Rest utility::string_t RestClient::GetInformationEndpoint(const std::string& restApiUri) { - std::string informationApi = restApiUri; + std::string informationApi = RestHelper::GetRestAPIBaseUri(restApiUri); return utility::conversions::to_string_t(informationApi.append(InformationGetEndpoint)); } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp index cb7ef38800..6f8938c660 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.cpp @@ -9,6 +9,7 @@ #include "Rest/Schema/Json/JsonHelper.h" #include "Rest/Schema/Json/CommonRestConstants.h" #include "Rest/Schema/Json/ManifestDeserializer.h" +#include "Rest/Schema/RestHelper.h" #include "Rest/Schema/Json/SearchResponseDeserializer.h" #include "winget/ManifestValidation.h" @@ -37,16 +38,6 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 return json_body; } - std::string GetRestAPIBaseUri(std::string restApiUri) - { - if (!restApiUri.empty() && restApiUri.back() == '/') - { - restApiUri.pop_back(); - } - - return restApiUri; - } - utility::string_t GetSearchEndpoint(const std::string& restApiUri) { std::string fullSearchAPI = restApiUri; @@ -82,7 +73,7 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0 Interface::Interface(const std::string& restApi) { - m_restApiUri = GetRestAPIBaseUri(restApi); + m_restApiUri = RestHelper::GetRestAPIBaseUri(restApi); m_searchEndpoint = GetSearchEndpoint(m_restApiUri); m_requiredRestApiHeaders.emplace_back( std::pair(JsonHelper::GetUtilityString(ContractVersion), JsonHelper::GetUtilityString(GetVersion()))); diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/Json/ManifestDeserializer.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/Json/ManifestDeserializer.cpp index c49c6109cb..05762c40a7 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/Json/ManifestDeserializer.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/Json/ManifestDeserializer.cpp @@ -142,17 +142,26 @@ namespace AppInstaller::Repository::Rest::Schema::Json manifest.Channel = JsonHelper::GetRawStringValueFromJsonNode(versionItem, JsonHelper::GetUtilityString(Channel)).value_or(""); // Default locale - auto& defaultLocale = versionItem.at(JsonHelper::GetUtilityString(DefaultLocale)); - std::optional defaultLocaleObject = DeserializeLocale(defaultLocale); - if (!defaultLocaleObject) + std::optional> defaultLocale = + JsonHelper::GetJsonValueFromNode(versionItem, JsonHelper::GetUtilityString(DefaultLocale)); + if (!defaultLocale) { AICLI_LOG(Repo, Error, << "Missing default locale in package: " << manifest.Id); return {}; } - manifest.DefaultLocalization = std::move(defaultLocaleObject.value()); + else + { + std::optional defaultLocaleObject = DeserializeLocale(defaultLocale.value().get()); + if (!defaultLocaleObject) + { + AICLI_LOG(Repo, Error, << "Missing default locale in package: " << manifest.Id); + return {}; + } + manifest.DefaultLocalization = std::move(defaultLocaleObject.value()); - // Moniker is in Default locale - manifest.Moniker = JsonHelper::GetRawStringValueFromJsonNode(defaultLocale, JsonHelper::GetUtilityString(Moniker)).value_or(""); + // Moniker is in Default locale + manifest.Moniker = JsonHelper::GetRawStringValueFromJsonNode(defaultLocale.value().get(), JsonHelper::GetUtilityString(Moniker)).value_or(""); + } // Installers std::optional> installers = JsonHelper::GetRawJsonArrayFromJsonNode(versionItem, JsonHelper::GetUtilityString(Installers)); @@ -335,14 +344,19 @@ namespace AppInstaller::Repository::Rest::Schema::Json } // Installer Switches - auto& installerSwitches = installerJsonObject.at(JsonHelper::GetUtilityString(InstallerSwitches)); - installer.Switches[InstallerSwitchType::Silent] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Silent)).value_or(""); - installer.Switches[InstallerSwitchType::SilentWithProgress] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(SilentWithProgress)).value_or(""); - installer.Switches[InstallerSwitchType::Interactive] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Interactive)).value_or(""); - installer.Switches[InstallerSwitchType::InstallLocation] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(InstallLocation)).value_or(""); - installer.Switches[InstallerSwitchType::Log] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Log)).value_or(""); - installer.Switches[InstallerSwitchType::Update] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Upgrade)).value_or(""); - installer.Switches[InstallerSwitchType::Custom] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Custom)).value_or(""); + std::optional> switches = + JsonHelper::GetJsonValueFromNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerSwitches)); + if (switches) + { + auto& installerSwitches = switches.value().get(); + installer.Switches[InstallerSwitchType::Silent] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Silent)).value_or(""); + installer.Switches[InstallerSwitchType::SilentWithProgress] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(SilentWithProgress)).value_or(""); + installer.Switches[InstallerSwitchType::Interactive] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Interactive)).value_or(""); + installer.Switches[InstallerSwitchType::InstallLocation] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(InstallLocation)).value_or(""); + installer.Switches[InstallerSwitchType::Log] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Log)).value_or(""); + installer.Switches[InstallerSwitchType::Update] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Upgrade)).value_or(""); + installer.Switches[InstallerSwitchType::Custom] = JsonHelper::GetRawStringValueFromJsonNode(installerSwitches, JsonHelper::GetUtilityString(Custom)).value_or(""); + } // Installer SuccessCodes std::optional> installSuccessCodes = JsonHelper::GetRawJsonArrayFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(InstallerSuccessCodes)); @@ -369,11 +383,15 @@ namespace AppInstaller::Repository::Rest::Schema::Json installer.FileExtensions = JsonHelper::GetRawStringArrayFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(FileExtensions)); // Dependencies - auto& dependenciesObject = installerJsonObject.at(JsonHelper::GetUtilityString(Dependencies)); - std::optional dependency = DeserializeDependency(dependenciesObject); - if (dependency) + std::optional> dependenciesObject = + JsonHelper::GetJsonValueFromNode(installerJsonObject, JsonHelper::GetUtilityString(Dependencies)); + if (dependenciesObject) { - installer.Dependencies = std::move(dependency.value()); + std::optional dependency = DeserializeDependency(dependenciesObject.value().get()); + if (dependency) + { + installer.Dependencies = std::move(dependency.value()); + } } installer.PackageFamilyName = JsonHelper::GetRawStringValueFromJsonNode(installerJsonObject, JsonHelper::GetUtilityString(PackageFamilyName)).value_or(""); diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp new file mode 100644 index 0000000000..bb08b4c991 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "RestHelper.h" + +namespace AppInstaller::Repository::Rest::Schema +{ + std::string RestHelper::GetRestAPIBaseUri(std::string restApiUri) + { + if (!restApiUri.empty() && restApiUri.back() == '/') + { + restApiUri.pop_back(); + } + + return restApiUri; + } +} \ No newline at end of file diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.h b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.h new file mode 100644 index 0000000000..2d9dbe6b17 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.h @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once + +namespace AppInstaller::Repository::Rest::Schema +{ + // Rest source helper. + struct RestHelper + { + static std::string GetRestAPIBaseUri(std::string restApiUri); + }; +} From 0c35d216a8be082e51bddccda288e3ca12e9c580 Mon Sep 17 00:00:00 2001 From: Ashwini Patil Date: Thu, 25 Mar 2021 23:48:07 -0700 Subject: [PATCH 2/2] empty at eof --- src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp index bb08b4c991..e7a2c60409 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/RestHelper.cpp @@ -14,4 +14,4 @@ namespace AppInstaller::Repository::Rest::Schema return restApiUri; } -} \ No newline at end of file +}