diff --git a/src/BootstrapMate.App/ViewModels/PrefsViewModel.cs b/src/BootstrapMate.App/ViewModels/PrefsViewModel.cs index 52a3086..d40c3e1 100644 --- a/src/BootstrapMate.App/ViewModels/PrefsViewModel.cs +++ b/src/BootstrapMate.App/ViewModels/PrefsViewModel.cs @@ -6,7 +6,7 @@ namespace BootstrapMate.App.ViewModels; /// /// ViewModel for the Prefs tab. Mirrors macOS SettingsViewModel. -/// Loads from ConfigManager, saves non-policy settings via elevated CLI, shows policy lock state. +/// Loads from ConfigManager, saves non-managed settings to the user registry (HKCU), shows management lock state. /// public partial class PrefsViewModel : ObservableObject { @@ -64,11 +64,11 @@ partial void OnSaveStatusChanged(SaveState value) OnPropertyChanged(nameof(IsSaveEnabled)); } - // ── Policy State ───────────────────────────────────────────── + // ── Management State ───────────────────────────────────────────── private HashSet _managedKeys = []; - public bool IsPolicyManaged(string key) => _managedKeys.Contains(key); + public bool IsManaged(string key) => _managedKeys.Contains(key); // ── Binding-Friendly Display Properties ────────────────────── @@ -137,7 +137,7 @@ public void Load() configMgr.ReloadSettings(); var config = configMgr.Config; - _managedKeys = PolicyDetector.Instance.AllManagedKeys(); + _managedKeys = ManagementDetector.Instance.AllManagedKeys(); ManifestUrl = config.ManifestUrl ?? ""; HasExistingAuth = !string.IsNullOrEmpty(config.AuthorizationHeader); @@ -155,7 +155,7 @@ public void Load() CustomInstallPath = config.CustomInstallPath ?? ""; NetworkTimeout = config.NetworkTimeout; - // Notify all bindings (policy locks, computed display properties) + // Notify all bindings (management locks, computed display properties) OnPropertyChanged(string.Empty); _isLoading = false; diff --git a/src/BootstrapMate.Core/ConfigManager.cs b/src/BootstrapMate.Core/ConfigManager.cs index ba48ebb..c7b543c 100644 --- a/src/BootstrapMate.Core/ConfigManager.cs +++ b/src/BootstrapMate.Core/ConfigManager.cs @@ -24,14 +24,14 @@ public sealed class ConfigManager private ConfigManager() { - LoadPolicyAndUserSettings(); + LoadManagementAndUserSettings(); } public enum ConfigSource { Default, UserSettings, - Policy, + Management, CliArgument } @@ -98,7 +98,7 @@ public string GetInstallPath() public bool IsValid() => !string.IsNullOrWhiteSpace(Config.ManifestUrl); /// - /// Reload settings from policy + user registry. Call when waiting for + /// Reload settings from management + user registry. Call when waiting for /// Intune policy to land post-enrollment. /// Returns true if a valid manifest URL was found. /// @@ -106,34 +106,34 @@ public bool ReloadSettings() { Config.ManifestUrl = null; ManifestUrlSource = ConfigSource.Default; - LoadPolicyAndUserSettings(); + LoadManagementAndUserSettings(); return IsValid(); } /// - /// Save user-configured settings to HKLM\SOFTWARE\BootstrapMate\Settings. - /// Skips any key that is already policy-managed. - /// Requires elevation. + /// Save user-configured settings to HKCU\SOFTWARE\BootstrapMate\Settings. + /// Skips any key that is already managed (set via Group Policy / Intune). + /// Writes to the current user's hive, so no elevation is required. /// public static void SaveUserSettings(BootstrapMateConfig settings) { - var policy = PolicyDetector.Instance; + var management = ManagementDetector.Instance; void WriteString(string key, string? value) { - if (policy.IsManagedByPolicy(key)) return; + if (management.IsManaged(key)) return; WriteRegistryValue(key, value ?? string.Empty, RegistryValueKind.String); } void WriteBool(string key, bool value) { - if (policy.IsManagedByPolicy(key)) return; + if (management.IsManaged(key)) return; WriteRegistryValue(key, value ? 1 : 0, RegistryValueKind.DWord); } void WriteInt(string key, int value) { - if (policy.IsManagedByPolicy(key)) return; + if (management.IsManaged(key)) return; WriteRegistryValue(key, value, RegistryValueKind.DWord); } @@ -160,9 +160,9 @@ void WriteInt(string key, int value) // ── Private ────────────────────────────────────────────────────── - private void LoadPolicyAndUserSettings() + private void LoadManagementAndUserSettings() { - var policy = PolicyDetector.Instance; + var management = ManagementDetector.Instance; // Lowest priority first: baked-in default → HKCU user → HKLM machine → CSP policy. // Higher-priority sources overwrite earlier ones; CLI runs last from caller. @@ -175,66 +175,66 @@ private void LoadPolicyAndUserSettings() LoadFromUserRegistry(); LoadFromMachineRegistry(); - LoadFromPolicy(policy); + LoadFromManagement(management); } - private void LoadFromPolicy(PolicyDetector policy) + private void LoadFromManagement(ManagementDetector management) { - if (policy.GetManagedString("ManifestUrl") is { Length: > 0 } url) + if (management.GetManagedString("ManifestUrl") is { Length: > 0 } url) { Config.ManifestUrl = url; - ManifestUrlSource = ConfigSource.Policy; + ManifestUrlSource = ConfigSource.Management; } - if (policy.GetManagedString("AuthorizationHeader") is { Length: > 0 } auth) + if (management.GetManagedString("AuthorizationHeader") is { Length: > 0 } auth) Config.AuthorizationHeader = auth; - if (policy.GetManagedBool("FollowRedirects") is { } followRedirects) + if (management.GetManagedBool("FollowRedirects") is { } followRedirects) Config.FollowRedirects = followRedirects; - if (policy.GetManagedBool("Reboot") is { } reboot) + if (management.GetManagedBool("Reboot") is { } reboot) Config.Reboot = reboot; - if (policy.GetManagedBool("SilentMode") is { } silent) + if (management.GetManagedBool("SilentMode") is { } silent) Config.SilentMode = silent; - if (policy.GetManagedBool("VerboseMode") is { } verbose) + if (management.GetManagedBool("VerboseMode") is { } verbose) Config.VerboseMode = verbose; - if (policy.GetManagedBool("DryRun") is { } dryRun) + if (management.GetManagedBool("DryRun") is { } dryRun) Config.DryRun = dryRun; - if (policy.GetManagedBool("EnableDialog") is { } enableDialog) + if (management.GetManagedBool("EnableDialog") is { } enableDialog) Config.EnableDialog = enableDialog; - if (policy.GetManagedBool("NoDialog") is { } noDialog) + if (management.GetManagedBool("NoDialog") is { } noDialog) Config.NoDialog = noDialog; - if (policy.GetManagedString("DialogTitle") is { Length: > 0 } title) + if (management.GetManagedString("DialogTitle") is { Length: > 0 } title) Config.DialogTitle = title; - if (policy.GetManagedString("DialogMessage") is { Length: > 0 } msg) + if (management.GetManagedString("DialogMessage") is { Length: > 0 } msg) Config.DialogMessage = msg; - if (policy.GetManagedString("DialogIcon") is { Length: > 0 } icon) + if (management.GetManagedString("DialogIcon") is { Length: > 0 } icon) Config.DialogIcon = icon; - if (policy.GetManagedBool("BlurScreen") is { } blur) + if (management.GetManagedBool("BlurScreen") is { } blur) Config.BlurScreen = blur; - if (policy.GetManagedString("CustomInstallPath") is { Length: > 0 } path) + if (management.GetManagedString("CustomInstallPath") is { Length: > 0 } path) Config.CustomInstallPath = path; - if (policy.GetManagedInt("NetworkTimeout") is { } timeout) + if (management.GetManagedInt("NetworkTimeout") is { } timeout) Config.NetworkTimeout = timeout; - if (policy.GetManagedBool("VerifyPackageSignatures") is { } verifySig) + if (management.GetManagedBool("VerifyPackageSignatures") is { } verifySig) Config.VerifyPackageSignatures = verifySig; - if (policy.GetManagedString("ExpectedPublisher") is { Length: > 0 } publisher) + if (management.GetManagedString("ExpectedPublisher") is { Length: > 0 } publisher) Config.ExpectedPublisher = publisher; - if (policy.GetManagedBool("AllowUnsigned") is { } allowUnsigned) + if (management.GetManagedBool("AllowUnsigned") is { } allowUnsigned) Config.AllowUnsigned = allowUnsigned; } diff --git a/src/BootstrapMate.Core/PolicyDetector.cs b/src/BootstrapMate.Core/ManagementDetector.cs similarity index 85% rename from src/BootstrapMate.Core/PolicyDetector.cs rename to src/BootstrapMate.Core/ManagementDetector.cs index b880435..0089ef2 100644 --- a/src/BootstrapMate.Core/PolicyDetector.cs +++ b/src/BootstrapMate.Core/ManagementDetector.cs @@ -4,19 +4,19 @@ namespace BootstrapMate.Core; /// /// Detects which settings are managed by Intune CSP / Group Policy. -/// Windows equivalent of macOS MDMDetector — checks HKLM\SOFTWARE\Policies\BootstrapMate. +/// Windows equivalent of macOS ManagementDetector — checks HKLM\SOFTWARE\Policies\BootstrapMate. /// /// Intune writes here via OMA-URI: /// ./Device/Vendor/MSFT/Policy/Config/BootstrapMate~Policy~BootstrapMate/{KeyName} /// Group Policy writes here via ADMX-backed policies. /// -public sealed class PolicyDetector +public sealed class ManagementDetector { - public static PolicyDetector Instance { get; } = new(); + public static ManagementDetector Instance { get; } = new(); /// /// Known key aliases — maps canonical key to all variant names that may appear in policy. - /// Mirrors macOS MDMDetector.keyAliases for consistent admin experience. + /// Mirrors macOS ManagementDetector.keyAliases for consistent admin experience. /// private static readonly Dictionary KeyAliases = new(StringComparer.OrdinalIgnoreCase) { @@ -40,27 +40,27 @@ public sealed class PolicyDetector ["AllowUnsigned"] = ["AllowUnsigned"], }; - private PolicyDetector() { } + private ManagementDetector() { } /// Returns true if the canonical key is present in the Policies registry hive. - public bool IsManagedByPolicy(string canonicalKey) + public bool IsManaged(string canonicalKey) { var aliases = GetAliases(canonicalKey); return FindRegistryValue(aliases) is not null; } - /// Returns the policy-managed value for a canonical key, or null. + /// Returns the managed value for a canonical key, or null. public object? GetManagedValue(string canonicalKey) { var aliases = GetAliases(canonicalKey); return FindRegistryValue(aliases); } - /// Returns a string policy value, or null. + /// Returns a string value, or null. public string? GetManagedString(string canonicalKey) => GetManagedValue(canonicalKey)?.ToString(); - /// Returns a bool policy value, or null. Reads DWORD 0/1. + /// Returns a bool value, or null. Reads DWORD 0/1. public bool? GetManagedBool(string canonicalKey) { var value = GetManagedValue(canonicalKey); @@ -73,7 +73,7 @@ string s when int.TryParse(s, out var i) => i != 0, }; } - /// Returns an int policy value, or null. + /// Returns an int value, or null. public int? GetManagedInt(string canonicalKey) { var value = GetManagedValue(canonicalKey); @@ -85,7 +85,7 @@ string s when int.TryParse(s, out var i) => i, }; } - /// Returns the set of canonical keys that are currently policy-managed. + /// Returns the set of canonical keys that are currently managed. public HashSet AllManagedKeys() { var result = new HashSet(StringComparer.OrdinalIgnoreCase);