AuthenticationInfoParser.cpp (5280B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "AuthenticationInfoParser.h" 5 #include <winget/JsonUtil.h> 6 7 namespace AppInstaller::Repository::Rest::Schema 8 { 9 namespace 10 { 11 // Authentication info constants 12 constexpr std::string_view Authentication = "Authentication"sv; 13 constexpr std::string_view AuthenticationType = "AuthenticationType"sv; 14 constexpr std::string_view MicrosoftEntraIdAuthenticationInfo = "MicrosoftEntraIdAuthenticationInfo"sv; 15 constexpr std::string_view MicrosoftEntraId_Resource = "Resource"sv; 16 constexpr std::string_view MicrosoftEntraId_Scope = "Scope"sv; 17 18 Authentication::AuthenticationType ConvertToAuthenticationTypeForSource(std::string_view in) 19 { 20 std::string inStrLower = Utility::ToLower(in); 21 Authentication::AuthenticationType result = Authentication::AuthenticationType::Unknown; 22 23 if (inStrLower == "none") 24 { 25 result = Authentication::AuthenticationType::None; 26 } 27 else if (inStrLower == "microsoftentraid") 28 { 29 result = Authentication::AuthenticationType::MicrosoftEntraId; 30 } 31 32 return result; 33 } 34 35 Authentication::AuthenticationType ConvertToAuthenticationTypeForInstaller(std::string_view in, Manifest::ManifestVer manifestVersion) 36 { 37 if (manifestVersion >= Manifest::ManifestVer{ Manifest::s_ManifestVersionV1_10 }) 38 { 39 return Authentication::ConvertToAuthenticationType(in); 40 } 41 42 return Authentication::AuthenticationType::Unknown; 43 } 44 } 45 46 // The authentication info json looks like below: 47 // "Authentication": { 48 // "AuthenticationType": "microsoftEntraId", 49 // "MicrosoftEntraIdAuthenticationInfo" : { 50 // "Resource": "GUID", 51 // "Scope" : "test" 52 // } 53 // } 54 Authentication::AuthenticationInfo ParseAuthenticationInfo(const web::json::value& dataObject, ParseAuthenticationInfoType parseType, std::optional<Manifest::ManifestVer> manifestVersion) 55 { 56 auto authenticationObject = JSON::GetJsonValueFromNode(dataObject, JSON::GetUtilityString(Authentication)); 57 if (!authenticationObject) 58 { 59 AICLI_LOG(Repo, Info, << "Authentication node not found. Assuming authentication type none."); 60 return {}; 61 } 62 63 const auto& authenticationObjectNode = authenticationObject.value().get(); 64 if (authenticationObjectNode.is_null()) 65 { 66 AICLI_LOG(Repo, Info, << "Authentication node is null. Assuming authentication type none."); 67 return {}; 68 } 69 70 Authentication::AuthenticationInfo result; 71 result.Type = Authentication::AuthenticationType::Unknown; 72 73 auto authenticationTypeString = JSON::GetRawStringValueFromJsonNode(authenticationObjectNode, JSON::GetUtilityString(AuthenticationType)); 74 // AuthenticationType required if Authentication exists and is not null. 75 THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !JSON::IsValidNonEmptyStringValue(authenticationTypeString)); 76 if (parseType == ParseAuthenticationInfoType::Source) 77 { 78 result.Type = ConvertToAuthenticationTypeForSource(authenticationTypeString.value()); 79 } 80 else if (parseType == ParseAuthenticationInfoType::Installer) 81 { 82 THROW_HR_IF(E_INVALIDARG, !manifestVersion); 83 result.Type = ConvertToAuthenticationTypeForInstaller(authenticationTypeString.value(), manifestVersion.value()); 84 } 85 86 // Parse MicrosoftEntraId info 87 auto microsoftEntraIdInfoObject = JSON::GetJsonValueFromNode(authenticationObjectNode, JSON::GetUtilityString(MicrosoftEntraIdAuthenticationInfo)); 88 if (microsoftEntraIdInfoObject) 89 { 90 const auto& microsoftEntraIdInfoNode = microsoftEntraIdInfoObject.value().get(); 91 92 Authentication::MicrosoftEntraIdAuthenticationInfo microsoftEntraIdInfo; 93 94 auto resourceString = JSON::GetRawStringValueFromJsonNode(microsoftEntraIdInfoNode, JSON::GetUtilityString(MicrosoftEntraId_Resource)); 95 // Resource required if MicrosoftEntraIdAuthenticationInfo exists and is not null. 96 THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !JSON::IsValidNonEmptyStringValue(resourceString)); 97 microsoftEntraIdInfo.Resource = std::move(resourceString.value()); 98 99 auto scopeString = JSON::GetRawStringValueFromJsonNode(microsoftEntraIdInfoNode, JSON::GetUtilityString(MicrosoftEntraId_Scope)); 100 if (JSON::IsValidNonEmptyStringValue(scopeString)) 101 { 102 microsoftEntraIdInfo.Scope = std::move(scopeString.value()); 103 } 104 105 result.MicrosoftEntraIdInfo = std::move(microsoftEntraIdInfo); 106 } 107 108 result.UpdateRequiredFieldsIfNecessary(); 109 THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !result.ValidateIntegrity()); 110 111 return result; 112 } 113 }