[PTRun][Enterprise]GPO for plugin enabled state (#27468)

* try code for gpo with pluginID param

* fix typo

* fixes

* update admx

* Add second policy to admx

* spelling fixes

* admx clean up

* add gpo code

* small fixes

* fixes

* fix cast

* update settings code

* bug fixes

* fix plugins disabled warning

* Info bar in settings

* settings ui fixes

* code clean up

* fix spelling

* fix spelling

* code optimization

* changes

* fix code

* switch to char*

* update comments

* validate plugin ID

* spell fixes

* spell fixes

* fix IPlugin interface

* Update Directory.Packages.props

hopefully fixes unit tests

* revert change of nuget pkg

* fixes

* fix spell check

* add todo comment

* improve gpo.h

* improve gpo.h

* update gpo.h

* clean up code in gpo.h

* fix build

* try to fix build

* xaml fix

* Fix getting string value from the registry

* communicate policy state suing settings.json

* various changes and gpo docs

* spell fixes

* PT Run: Policy handling

* spell fix

* fix logging

* fix admx revision

* revision fix 2

* review feedback 1

* review feedback 2

* dev docs update

* fix typo
This commit is contained in:
Heiko
2023-10-11 16:37:15 +02:00
committed by GitHub
parent 19827d0093
commit 602a3ff090
39 changed files with 377 additions and 15 deletions

View File

@@ -21,6 +21,8 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter
public string Description => Properties.Resources.plugin_description;
public static string PluginID => "aa0ee9daff654fb7be452c2d77c471b9";
private PluginInitContext _context;
private static string _icon_path;
private bool _disposed;

View File

@@ -23,6 +23,8 @@ namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces
public string Description => GetTranslatedPluginDescription();
public static string PluginID => "525995402BEF4A8CA860D92F6D108092";
public Main()
{
VSCodeInstances.LoadVSCodeInstances();

View File

@@ -20,6 +20,8 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator
public string Description => Resources.plugin_description;
public static string PluginID => "a26b1bb4dbd911edafa10242ac120002";
private PluginInitContext _context;
private static bool _isLightTheme = true;
private bool _disposed;

View File

@@ -36,6 +36,8 @@ namespace Community.PowerToys.Run.Plugin.WebSearch
public string Description => Properties.Resources.plugin_description;
public static string PluginID => "9F1B49201C3F4BF781CAAD5CD88EA4DC";
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
{
new PluginAdditionalOption()

View File

@@ -44,6 +44,8 @@ namespace Microsoft.Plugin.Folder
public string Description => Properties.Resources.wox_plugin_folder_plugin_description;
public static string PluginID => "B4D3B69656E14D44865C8D818EAE47C4";
public void Save()
{
_storage.Save();

View File

@@ -51,6 +51,8 @@ namespace Microsoft.Plugin.Indexer
public string Description => Properties.Resources.Microsoft_plugin_indexer_plugin_description;
public static string PluginID => "2140FC9819AD43A3A616E2735815C27C";
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
{
new PluginAdditionalOption()

View File

@@ -37,6 +37,8 @@ namespace Microsoft.Plugin.Program
public string Description => Properties.Resources.wox_plugin_program_plugin_description;
public static string PluginID => "791FC278BA414111B8D1886DFE447410";
private static PluginInitContext _context;
private readonly PluginJsonStorage<ProgramPluginSettings> _settingsStorage;
private bool _disposed;

View File

@@ -39,6 +39,8 @@ namespace Microsoft.Plugin.Shell
public string Description => Properties.Resources.wox_plugin_cmd_plugin_description;
public static string PluginID => "D409510CD0D2481F853690A07E6DC426";
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
{
new PluginAdditionalOption()

View File

@@ -37,6 +37,8 @@ namespace Microsoft.Plugin.Uri
public string Description => Properties.Resources.Microsoft_plugin_uri_plugin_description;
public static string PluginID => "03276A39D4E9417C8FFD200B0EE5E871";
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return new List<ContextMenuResult>(0);

View File

@@ -29,6 +29,8 @@ namespace Microsoft.Plugin.WindowWalker
public string Description => Properties.Resources.wox_plugin_windowwalker_plugin_description;
public static string PluginID => "F737A9223560B3C6833B5FFB8CDF78E5";
internal static readonly VirtualDesktopHelper VirtualDesktopHelperInstance = new VirtualDesktopHelper();
public List<Result> Query(Query query)

View File

@@ -30,6 +30,8 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
public string Description => Resources.wox_plugin_calculator_plugin_description;
public static string PluginID => "CEA0FDFC6D3B4085823D60DC76F28855";
private bool _disposed;
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()

View File

@@ -22,6 +22,8 @@ namespace Microsoft.PowerToys.Run.Plugin.History
public string Description => Resources.wox_plugin_history_plugin_description;
public static string PluginID => "C88512156BB74580AADF7252E130BA8D";
private bool _disposed;
public List<Result> Query(Query query)

View File

@@ -59,6 +59,11 @@ namespace Microsoft.PowerToys.Run.Plugin.OneNote
/// </summary>
public string Description => Resources.PluginDescription;
/// <summary>
/// Gets the plugin ID for validation
/// </summary>
public static string PluginID => "0778F0C264114FEC8A3DF59447CF0A74";
/// <summary>
/// Initialize the plugin with the given <see cref="PluginInitContext"/>
/// </summary>

View File

@@ -21,6 +21,8 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys
public string Description => Resources.Plugin_Description;
public static string PluginID => "29DD65DB28C84A37BDEF1D2B43DA368B";
public string GetTranslatedPluginTitle() => Resources.Plugin_Name;
public string GetTranslatedPluginDescription() => Resources.Plugin_Description;

View File

@@ -46,6 +46,8 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry
public string Description => Resources.PluginDescription;
public static string PluginID => "303417D927BF4C97BCFFC78A123BE0C8";
/// <summary>
/// Initializes a new instance of the <see cref="Main"/> class.
/// </summary>

View File

@@ -23,6 +23,8 @@ namespace Microsoft.PowerToys.Run.Plugin.Service
public string Description => Resources.wox_plugin_service_plugin_description;
public static string PluginID => "11A6C36E4E91439CA69F702CBD364EF7";
public void Init(PluginInitContext context)
{
_context = context;

View File

@@ -31,6 +31,8 @@ namespace Microsoft.PowerToys.Run.Plugin.System
public string Description => Resources.Microsoft_plugin_sys_plugin_description;
public static string PluginID => "CEA08895D2544B019B2E9C5009600DF4";
public string IconTheme { get; set; }
public bool IsBootedInUefiMode { get; set; }

View File

@@ -25,6 +25,8 @@ namespace Microsoft.PowerToys.Run.Plugin.TimeDate
public string Description => GetTranslatedPluginDescription();
public static string PluginID => "5D69806A5A474115821C3E4C56B9C793";
public IEnumerable<PluginAdditionalOption> AdditionalOptions
{
get

View File

@@ -72,6 +72,11 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings
/// </summary>
public string Description => Resources.PluginDescription;
/// <summary>
/// Gets the plugin ID for validation
/// </summary>
public static string PluginID => "5043CECEE6A748679CBE02D27D83747A";
/// <summary>
/// Initialize the plugin with the given <see cref="PluginInitContext"/>.
/// </summary>

View File

@@ -34,6 +34,8 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal
public string Description => Resources.plugin_description;
public static string PluginID => "F59BA85006B14389A72A0EA756695F1D";
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
{
new PluginAdditionalOption()

View File

@@ -11,6 +11,8 @@ using System.IO.Abstractions;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using global::PowerToys.GPOWrapper;
using ManagedCommon;
using PowerLauncher.Properties;
using Wox.Infrastructure.Storage;
using Wox.Plugin;
@@ -140,6 +142,25 @@ namespace PowerLauncher.Plugin
var failedPlugins = new ConcurrentQueue<PluginPair>();
Parallel.ForEach(AllPlugins, pair =>
{
// Check policy state for the plugin and update metadata
var enabledPolicyState = GPOWrapper.GetRunPluginEnabledValue(pair.Metadata.ID);
if (enabledPolicyState == GpoRuleConfigured.Enabled)
{
pair.Metadata.Disabled = false;
pair.Metadata.IsEnabledPolicyConfigured = true;
Log.Info($"The plugin <{pair.Metadata.Name}> is enabled by policy.", typeof(PluginManager));
}
else if (enabledPolicyState == GpoRuleConfigured.Disabled)
{
pair.Metadata.Disabled = true;
pair.Metadata.IsEnabledPolicyConfigured = true;
Log.Info($"The plugin <{pair.Metadata.Name}> is disabled by policy.", typeof(PluginManager));
}
else if (enabledPolicyState == GpoRuleConfigured.WrongValue)
{
Log.Warn($"Wrong policy value for enabled policy for plugin <{pair.Metadata.Name}>.", typeof(PluginManager));
}
if (pair.Metadata.Disabled)
{
return;

View File

@@ -9,6 +9,7 @@ using System.Linq;
using System.Threading;
using System.Windows.Input;
using Common.UI;
using global::PowerToys.GPOWrapper;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerLauncher.Helper;
using PowerLauncher.Plugin;
@@ -242,6 +243,7 @@ namespace PowerLauncher
IconPathDark = GetIcon(x.Metadata, x.Metadata.IcoPathDark),
IconPathLight = GetIcon(x.Metadata, x.Metadata.IcoPathLight),
AdditionalOptions = x.Plugin is ISettingProvider ? (x.Plugin as ISettingProvider).AdditionalOptions : new List<PluginAdditionalOption>(),
EnabledPolicyUiState = (int)GpoRuleConfigured.NotConfigured,
});
}
@@ -256,11 +258,13 @@ namespace PowerLauncher
if (defaultPlugins.ContainsKey(plugin.Id))
{
var additionalOptions = CombineAdditionalOptions(defaultPlugins[plugin.Id].AdditionalOptions, plugin.AdditionalOptions);
var enabledPolicyState = GPOWrapper.GetRunPluginEnabledValue(plugin.Id);
plugin.Name = defaultPlugins[plugin.Id].Name;
plugin.Description = defaultPlugins[plugin.Id].Description;
plugin.Author = defaultPlugins[plugin.Id].Author;
plugin.IconPathDark = defaultPlugins[plugin.Id].IconPathDark;
plugin.IconPathLight = defaultPlugins[plugin.Id].IconPathLight;
plugin.EnabledPolicyUiState = (int)enabledPolicyState;
defaultPlugins[plugin.Id] = plugin;
defaultPlugins[plugin.Id].AdditionalOptions = additionalOptions;
}

View File

@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
namespace Wox.Plugin
@@ -17,5 +18,11 @@ namespace Wox.Plugin
// Localized description
string Description { get; }
/* The two property lines are commented because they break the unit tests. (The Moq package used in the unit tests doesn't support the .Net 7 feature 'static abstract' properties yet.) - https://github.com/Moq/Moq/issues/1398
*
* // Plugin ID for validating the plugin.json entry (It must be static for accessing it before loading the plugin.)
* public static abstract string PluginID { get; }
*/
}
}

View File

@@ -32,6 +32,10 @@ namespace Wox.Plugin
public bool Disabled { get; set; }
// This property is used in PT Run only to decide whether to updated the Disabled property or not.
[JsonIgnore]
public bool IsEnabledPolicyConfigured { get; set; }
[JsonInclude]
public string ExecuteFilePath { get; private set; }

View File

@@ -63,20 +63,24 @@ namespace Wox.Plugin
return;
}
if (Metadata.Disabled && !setting.Disabled)
// If the enabled state is policy managed then we skip the update of the disabled state as it must be a manual settings.json manipulation.
if (!Metadata.IsEnabledPolicyConfigured)
{
Metadata.Disabled = false;
InitializePlugin(api);
if (!IsPluginInitialized)
if (Metadata.Disabled && !setting.Disabled)
{
string description = $"{Resources.FailedToLoadPluginDescription} {Metadata.Name}\n\n{Resources.FailedToLoadPluginDescriptionPartTwo}";
api.ShowMsg(Resources.FailedToLoadPluginTitle, description, string.Empty, false);
Metadata.Disabled = false;
InitializePlugin(api);
if (!IsPluginInitialized)
{
string description = $"{Resources.FailedToLoadPluginDescription} {Metadata.Name}\n\n{Resources.FailedToLoadPluginDescriptionPartTwo}";
api.ShowMsg(Resources.FailedToLoadPluginTitle, description, string.Empty, false);
}
}
else
{
Metadata.Disabled = setting.Disabled;
}
}
else
{
Metadata.Disabled = setting.Disabled;
}
Metadata.ActionKeyword = setting.ActionKeyword;
@@ -167,6 +171,19 @@ namespace Wox.Plugin
return false;
}
// Validate plugin ID to prevent bypassing the GPO by changing the ID in the plugin.json file.
string pluginID = (string)type.GetProperty("PluginID", BindingFlags.Public | BindingFlags.Static)?.GetValue(null);
if (pluginID == null)
{
Log.Error($"Can't validate plugin ID of plugin <{Metadata.Name}> in {Metadata.ExecuteFilePath}: The static property <Main.PluginID> was not found.", MethodBase.GetCurrentMethod().DeclaringType);
return false;
}
else if (pluginID != Metadata.ID)
{
Log.Error($"Wrong plugin ID found in plugin.json of plugin <{Metadata.Name}>. ('{Metadata.ID}' != '{pluginID}')", MethodBase.GetCurrentMethod().DeclaringType);
return false;
}
try
{
Plugin = (IPlugin)Activator.CreateInstance(type);