Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename source auto update group policy #1995

Merged
merged 4 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/admx/DesktopAppInstaller.admx
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@
<decimal value="0" />
</disabledValue>
</policy>
<policy name="SourceAutoUpdateIntervalInMinutes" class="Machine" displayName="$(string.SourceAutoUpdateIntervalInMinutes)" explainText="$(string.SourceAutoUpdateIntervalInMinutesExplanation)" presentation="$(presentation.SourceAutoUpdateIntervalInMinutes)" key="Software\Policies\Microsoft\Windows\AppInstaller">
<policy name="SourceAutoUpdateInterval" class="Machine" displayName="$(string.SourceAutoUpdateInterval)" explainText="$(string.SourceAutoUpdateIntervalExplanation)" presentation="$(presentation.SourceAutoUpdateInterval)" key="Software\Policies\Microsoft\Windows\AppInstaller">
<parentCategory ref="AppInstaller" />
<supportedOn ref="windows:SUPPORTED_Windows_10_0_RS5" />
<elements>
<decimal id="SourceAutoUpdateIntervalInMinutes" valueName="SourceAutoUpdateIntervalInMinutes" maxValue="43200" />
<decimal id="SourceAutoUpdateInterval" valueName="SourceAutoUpdateInterval" maxValue="43200" />
</elements>
</policy>
<policy name="EnableAdditionalSources" class="Machine" displayName="$(string.EnableAdditionalSources)" explainText="$(string.EnableAdditionalSourcesExplanation)" presentation="$(presentation.AdditionalSources)" key="Software\Policies\Microsoft\Windows\AppInstaller" valueName="EnableAdditionalSources">
Expand Down
8 changes: 4 additions & 4 deletions doc/admx/en-US/DesktopAppInstaller.adml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ If you do not configure this setting, the Microsoft Store source for the Windows
If you enable this setting, the Microsoft Store source for the Windows Package Manager will be available and cannot be removed.

If you disable this setting the Microsoft Store source for the Windows Package Manager will not be available.</string>
<string id="SourceAutoUpdateIntervalInMinutes">Set App Installer Source Auto Update Interval In Minutes</string>
<string id="SourceAutoUpdateIntervalInMinutesExplanation">This policy controls the auto update interval for package-based sources.
<string id="SourceAutoUpdateInterval">Set App Installer Source Auto Update Interval In Minutes</string>
<string id="SourceAutoUpdateIntervalExplanation">This policy controls the auto update interval for package-based sources.

If you disable or do not configure this setting, the default interval or the value specified in settings will be used by the Windows Package Manager.

Expand All @@ -77,8 +77,8 @@ If you enable this policy, only the sources specified can be added or removed fr
If you disable this policy, no additional sources can be configured for the Windows Package Manager.</string>
</stringTable>
<presentationTable>
<presentation id="SourceAutoUpdateIntervalInMinutes">
<decimalTextBox refId="SourceAutoUpdateIntervalInMinutes" defaultValue="5">Source Auto Update Interval In Minutes</decimalTextBox>
<presentation id="SourceAutoUpdateInterval">
<decimalTextBox refId="SourceAutoUpdateInterval" defaultValue="5">Source Auto Update Interval In Minutes</decimalTextBox>
</presentation>
<presentation id="AdditionalSources">
<listBox refId="AdditionalSources" required="false">Additional Sources: </listBox>
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLIE2ETests/GroupPolicyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static class Attributes
public static GroupPolicyHelper EnableMicrosoftStoreSource = new GroupPolicyHelper("EnableMicrosoftStoreSource");
public static GroupPolicyHelper EnableAdditionalSources = new GroupPolicyHelper("EnableAdditionalSources", "AdditionalSources");
public static GroupPolicyHelper EnableAllowedSources = new GroupPolicyHelper("EnableAllowedSources", "AllowedSources");
public static GroupPolicyHelper SourceAutoUpdateInterval = new GroupPolicyHelper("SourceAutoUpdateIntervalInMinutes", "SourceAutoUpdateIntervalInMinutes");
public static GroupPolicyHelper SourceAutoUpdateInterval = new GroupPolicyHelper("SourceAutoUpdateInterval", "SourceAutoUpdateInterval");

private static GroupPolicyHelper[] AllPolicies = new GroupPolicyHelper[]
{
Expand Down
49 changes: 49 additions & 0 deletions src/AppInstallerCLITests/GroupPolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,55 @@ TEST_CASE("GroupPolicy_UpdateInterval", "[groupPolicy]")
}
}


TEST_CASE("GroupPolicy_UpdateInterval_OldName", "[groupPolicy]")
{
auto policiesKey = RegCreateVolatileTestRoot();

SECTION("New name shadows old")
{
SECTION("When old is valid")
{
SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, 3);
}
SECTION("When old is invalid")
{
SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, L"Invalid type");
}

SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, 1);
GroupPolicy groupPolicy{ policiesKey.get() };

auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();
REQUIRE(policy.has_value());
REQUIRE(*policy == 1);
}

SECTION("Fallback to old name")
{
SECTION("When new name has invalid data")
florelis marked this conversation as resolved.
Show resolved Hide resolved
{
SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L"Wrong type");
SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, 20);
GroupPolicy groupPolicy{ policiesKey.get() };

// We should not fall back on this case
auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();
REQUIRE(!policy.has_value());
}
SECTION("When new name is missing")
{
// Don't add the registry value with the new name
SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, 20);
GroupPolicy groupPolicy{ policiesKey.get() };

auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();
REQUIRE(policy.has_value());
REQUIRE(*policy == 20);
}
}
}

TEST_CASE("GroupPolicy_Sources", "[groupPolicy]")
{
auto policiesKey = RegCreateVolatileTestRoot();
Expand Down
3 changes: 2 additions & 1 deletion src/AppInstallerCLITests/TestSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ namespace TestCommon
const std::wstring AdditionalSourcesPolicyValueName = L"EnableAdditionalSources";
const std::wstring AllowedSourcesPolicyValueName = L"EnableAllowedSources";

const std::wstring SourceUpdateIntervalPolicyValueName = L"SourceAutoUpdateIntervalInMinutes";
const std::wstring SourceUpdateIntervalPolicyValueName = L"SourceAutoUpdateInterval";
const std::wstring SourceUpdateIntervalPolicyOldValueName = L"SourceAutoUpdateIntervalInMinutes";

const std::wstring AdditionalSourcesPolicyKeyName = L"AdditionalSources";
const std::wstring AllowedSourcesPolicyKeyName = L"AllowedSources";
Expand Down
14 changes: 7 additions & 7 deletions src/AppInstallerCLITests/WorkflowGroupPolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ TEST_CASE("GroupPolicy_Info", "[groupPolicy]")
Execution::Context context{ output, std::cin };
context.Args.AddArg(Execution::Args::Type::Info);
RootCommand rootCommand({});

SECTION("Does not list not configured")
{
rootCommand.Execute(context);
Expand All @@ -109,9 +109,9 @@ TEST_CASE("GroupPolicy_Info", "[groupPolicy]")
}
SECTION("Shows enabled policies")
{
policies.SetState(TogglePolicy::Policy::HashOverride, PolicyState::Enabled);
policies.SetState(TogglePolicy::Policy::HashOverride, PolicyState::Enabled);

rootCommand.Execute(context);
rootCommand.Execute(context);
INFO(output.str());

REQUIRE_FALSE(context.IsTerminated());
Expand All @@ -120,7 +120,7 @@ TEST_CASE("GroupPolicy_Info", "[groupPolicy]")
}
SECTION("Shows disabled policies")
{
policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled);
policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled);

rootCommand.Execute(context);
INFO(output.str());
Expand All @@ -131,7 +131,7 @@ TEST_CASE("GroupPolicy_Info", "[groupPolicy]")
}
SECTION("Shows auto update interval")
{
policies.SetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>(60);
policies.SetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>(60);

rootCommand.Execute(context);
INFO(output.str());
Expand All @@ -147,7 +147,7 @@ TEST_CASE("GroupPolicy_Info", "[groupPolicy]")
source.Type = "Test.Type";
source.Arg = "test-arg";
policies.SetState(TogglePolicy::Policy::AdditionalSources, PolicyState::Enabled);
policies.SetValue<ValuePolicy::AdditionalSources>({ source });
policies.SetValue<ValuePolicy::AdditionalSources>({ source });

rootCommand.Execute(context);
INFO(output.str());
Expand All @@ -167,7 +167,7 @@ TEST_CASE("GroupPolicy_Info", "[groupPolicy]")
source.Type = "Test.Type";
source.Arg = "test-arg";
policies.SetState(TogglePolicy::Policy::AllowedSources, PolicyState::Enabled);
policies.SetValue<ValuePolicy::AllowedSources>({ source });
policies.SetValue<ValuePolicy::AllowedSources>({ source });

rootCommand.Execute(context);
INFO(output.str());
Expand Down
50 changes: 37 additions & 13 deletions src/AppInstallerCommonCore/GroupPolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,21 @@ namespace AppInstaller::Settings
return (s_override ? *s_override : s_groupPolicy);
}

template<Registry::Value::Type T>
std::optional<decltype(std::declval<Registry::Value>().GetValue<T>())> GetRegistryValue(const Registry::Key& key, const std::string_view valueName)
std::optional<Registry::Value> GetRegistryValueObject(const Registry::Key& key, const std::string_view valueName)
{
if (!key)
{
// Key does not exist; there's nothing to return
return std::nullopt;
}

auto regValue = key[valueName];
if (!regValue.has_value())
{
// Value does not exist
return std::nullopt;
}
return key[valueName];
}

auto value = regValue->TryGetValue<T>();
template<Registry::Value::Type T>
std::optional<decltype(std::declval<Registry::Value>().GetValue<T>())> GetRegistryValueData(const Registry::Value& regValue, const std::string_view valueName)
{
auto value = regValue.TryGetValue<T>();
if (!value.has_value())
{
AICLI_LOG(Core, Warning, << "Value for policy '" << valueName << "' does not have expected type");
Expand All @@ -49,9 +47,22 @@ namespace AppInstaller::Settings
return std::move(value.value());
}

template<Registry::Value::Type T>
std::optional<decltype(std::declval<Registry::Value>().GetValue<T>())> GetRegistryValueData(const Registry::Key& key, const std::string_view valueName)
{
auto regValue = GetRegistryValueObject(key, valueName);
if (!regValue.has_value())
{
// Value does not exist; there's nothing to return
return std::nullopt;
}

return GetRegistryValueData<T>(regValue.value(), valueName);
}

std::optional<bool> RegistryValueIsTrue(const Registry::Key& key, std::string_view valueName)
{
auto intValue = GetRegistryValue<Registry::Value::Type::DWord>(key, valueName);
auto intValue = GetRegistryValueData<Registry::Value::Type::DWord>(key, valueName);
if (!intValue.has_value())
{
return std::nullopt;
Expand Down Expand Up @@ -207,8 +218,21 @@ namespace AppInstaller::Settings

std::optional<uint32_t> ValuePolicyMapping<ValuePolicy::SourceAutoUpdateIntervalInMinutes>::ReadAndValidate(const Registry::Key& policiesKey)
{
// This policy used to have another name in the registry.
// Try to read first with the current name, and if it's not present
// check if the old name is present.
using Mapping = ValuePolicyMapping<ValuePolicy::SourceAutoUpdateIntervalInMinutes>;
return GetRegistryValue<Mapping::ValueType>(policiesKey, Mapping::ValueName);

auto regValueWithCurrentName = GetRegistryValueObject(policiesKey, Mapping::ValueName);
if (regValueWithCurrentName.has_value())
{
// We use the current name even if it doesn't have valid data.
return GetRegistryValueData<Mapping::ValueType>(regValueWithCurrentName.value(), Mapping::ValueName);
}
else
{
return GetRegistryValueData<Mapping::ValueType>(policiesKey, "SourceAutoUpdateIntervalInMinutes"sv);
}
}

std::optional<SourceFromPolicy> ValuePolicyMapping<ValuePolicy::AdditionalSources>::ReadAndValidateItem(const Registry::Value& item)
Expand All @@ -228,8 +252,8 @@ namespace AppInstaller::Settings
{
case TogglePolicy::Policy::WinGet:
return TogglePolicy(policy, "EnableAppInstaller"sv, String::PolicyEnableWinGet);
case TogglePolicy::Policy::Settings: return
TogglePolicy(policy, "EnableSettings"sv, String::PolicyEnableWingetSettings);
case TogglePolicy::Policy::Settings:
return TogglePolicy(policy, "EnableSettings"sv, String::PolicyEnableWingetSettings);
case TogglePolicy::Policy::ExperimentalFeatures:
return TogglePolicy(policy, "EnableExperimentalFeatures"sv, String::PolicyEnableExperimentalFeatures);
case TogglePolicy::Policy::LocalManifestFiles:
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCommonCore/Public/winget/GroupPolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ namespace AppInstaller::Settings
static std::optional<item_t> ReadAndValidateItem(const Registry::Value& item); \
)

POLICY_MAPPING_VALUE_SPECIALIZATION(ValuePolicy::SourceAutoUpdateIntervalInMinutes, uint32_t, "SourceAutoUpdateIntervalInMinutes"sv, Registry::Value::Type::DWord);
POLICY_MAPPING_VALUE_SPECIALIZATION(ValuePolicy::SourceAutoUpdateIntervalInMinutes, uint32_t, "SourceAutoUpdateInterval"sv, Registry::Value::Type::DWord);

POLICY_MAPPING_LIST_SPECIALIZATION(ValuePolicy::AdditionalSources, SourceFromPolicy, "AdditionalSources"sv);
POLICY_MAPPING_LIST_SPECIALIZATION(ValuePolicy::AllowedSources, SourceFromPolicy, "AllowedSources"sv);
Expand Down