winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

Runtime.cpp (4518B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "TestCommon.h"
      5 #include "TestHooks.h"
      6 #include <AppInstallerRuntime.h>
      7 #include <winget/Filesystem.h>
      8 
      9 using namespace AppInstaller;
     10 using namespace AppInstaller::Filesystem;
     11 using namespace AppInstaller::Runtime;
     12 using namespace TestCommon;
     13 
     14 bool CanWriteToPath(const std::filesystem::path& directory, const std::filesystem::path& file = "test.txt")
     15 {
     16     std::ofstream out{ directory / file };
     17     out << "Test";
     18     return out.good();
     19 }
     20 
     21 void RequireAdminOwner(const std::filesystem::path& directory)
     22 {
     23     wil::unique_hlocal_security_descriptor securityDescriptor;
     24     PSID ownerSID = nullptr;
     25     THROW_IF_WIN32_ERROR(GetNamedSecurityInfoW(directory.c_str(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &ownerSID, nullptr, nullptr, nullptr, &securityDescriptor));
     26 
     27     auto adminSID = wil::make_static_sid(SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS);
     28     REQUIRE(EqualSid(adminSID.get(), ownerSID));
     29 }
     30 
     31 TEST_CASE("ApplyACL_CurrentUserOwner", "[runtime]")
     32 {
     33     TempDirectory directory("CurrentUserOwner");
     34     PathDetails details;
     35     details.Path = directory;
     36     details.SetOwner(ACEPrincipal::CurrentUser);
     37 
     38     details.ApplyACL();
     39 
     40     REQUIRE(CanWriteToPath(directory));
     41 }
     42 
     43 TEST_CASE("ApplyACL_RemoveWriteForUser", "[runtime]")
     44 {
     45     TempDirectory directory("CurrentUserCantWrite");
     46     PathDetails details;
     47     details.Path = directory;
     48     details.ACL[ACEPrincipal::CurrentUser] = ACEPermissions::ReadExecute;
     49 
     50     details.ApplyACL();
     51 
     52     REQUIRE(!CanWriteToPath(directory));
     53 }
     54 
     55 TEST_CASE("ApplyACL_AdminOwner", "[runtime]")
     56 {
     57     TempDirectory directory("AdminOwner");
     58     PathDetails details;
     59     details.Path = directory;
     60     details.SetOwner(ACEPrincipal::Admins);
     61 
     62     if (IsRunningAsAdmin())
     63     {
     64         details.ApplyACL();
     65         RequireAdminOwner(directory);
     66         REQUIRE(CanWriteToPath(directory));
     67     }
     68     else
     69     {
     70         // A non-admin token cannot set the owner to be the Admins group
     71         REQUIRE_THROWS_HR(details.ApplyACL(), HRESULT_FROM_WIN32(ERROR_INVALID_OWNER));
     72     }
     73 }
     74 
     75 TEST_CASE("ApplyACL_BothOwners", "[runtime]")
     76 {
     77     TempDirectory directory("AdminOwner");
     78     PathDetails details;
     79     details.Path = directory;
     80     details.ACL[ACEPrincipal::CurrentUser] = ACEPermissions::ReadExecute;
     81     details.ACL[ACEPrincipal::System] = ACEPermissions::All;
     82 
     83     if (IsRunningAsSystem())
     84     {
     85         // Both cannot be owners
     86         REQUIRE_THROWS_HR(details.ApplyACL(), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
     87     }
     88     else
     89     {
     90         REQUIRE_NOTHROW(details.ApplyACL());
     91     }
     92 }
     93 
     94 TEST_CASE("ApplyACL_CurrentUserOwner_SystemAll", "[runtime]")
     95 {
     96     TempDirectory directory("UserAndSystem");
     97     PathDetails details;
     98     details.Path = directory;
     99     details.SetOwner(ACEPrincipal::CurrentUser);
    100     details.ACL[ACEPrincipal::System] = ACEPermissions::All;
    101 
    102     details.ApplyACL();
    103 
    104     REQUIRE(CanWriteToPath(directory));
    105 }
    106 
    107 TEST_CASE("VerifyDevModeEnabledCheck", "[runtime]")
    108 {
    109     if (!Runtime::IsRunningAsAdmin())
    110     {
    111         WARN("Test requires admin privilege. Skipped.");
    112         return;
    113     }
    114 
    115     bool initialState = IsDevModeEnabled();
    116 
    117     EnableDevMode(!initialState);
    118     bool modifiedState = IsDevModeEnabled();
    119     
    120     // Revert to original state.
    121     EnableDevMode(initialState);
    122     bool revertedState = IsDevModeEnabled();
    123 
    124     REQUIRE(modifiedState != initialState);
    125     REQUIRE(revertedState == initialState);
    126 }
    127 
    128 TEST_CASE("EnsureUserProfileNotPresentInDisplayPaths", "[runtime]")
    129 {
    130     // Clear the overrides that we use when testing as they don't consider display purposes
    131     Runtime::TestHook_ClearPathOverrides();
    132     auto restorePaths = wil::scope_exit([]() { TestCommon::SetTestPathOverrides(); });
    133 
    134     std::filesystem::path userProfilePath = Filesystem::GetKnownFolderPath(FOLDERID_Profile);
    135     std::string userProfileString = userProfilePath.u8string();
    136 
    137     for (auto i = ToIntegral(ToEnum<Runtime::PathName>(0)); i < ToIntegral(Runtime::PathName::Max); ++i)
    138     {
    139         std::filesystem::path displayPath = GetPathTo(ToEnum<Runtime::PathName>(i), true);
    140         std::string displayPathString = displayPath.u8string();
    141         INFO(i << " = " << displayPathString);
    142         REQUIRE(displayPathString.find(userProfileString) == std::string::npos);
    143     }
    144 }