[AdvancedPaste]Check "Paste with AI" enabled state for enabling custom actions (#35026)

* [AdvancedPaste] Check OpenAI enabled state for custom actions

* Add some more explanations to the expected exception

* Add description saying that it requires Paste with AI to be enabled

* Check openAI enabled only if we have custom actions

---------

Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
Ani 2024-09-24 19:16:20 +02:00 committed by GitHub
parent 734b0f8a54
commit 499dc9bb7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 54 additions and 11 deletions

View File

@ -94,6 +94,7 @@ namespace AdvancedPaste.ViewModels
ClipboardHistoryEnabled = IsClipboardHistoryEnabled();
ReadClipboard();
UpdateAllowedByGPO();
_clipboardTimer = new() { Interval = TimeSpan.FromSeconds(1) };
_clipboardTimer.Tick += ClipboardTimer_Tick;
_clipboardTimer.Start();
@ -462,7 +463,7 @@ namespace AdvancedPaste.ViewModels
{
Logger.LogTrace();
if (string.IsNullOrWhiteSpace(inputInstructions))
if (string.IsNullOrWhiteSpace(inputInstructions) || !IsCustomAIEnabled)
{
return string.Empty;
}

View File

@ -13,7 +13,9 @@
#include <common/interop/shared_constants.h>
#include <common/utils/logger_helper.h>
#include <common/utils/winapi_error.h>
#include <common/utils/gpo.h>
#include <winrt/Windows.Security.Credentials.h>
#include <atlfile.h>
#include <atlstr.h>
#include <vector>
@ -54,6 +56,9 @@ namespace
const wchar_t JSON_KEY_PASTE_AS_JSON_HOTKEY[] = L"paste-as-json-hotkey";
const wchar_t JSON_KEY_SHOW_CUSTOM_PREVIEW[] = L"ShowCustomPreview";
const wchar_t JSON_KEY_VALUE[] = L"value";
const wchar_t OPENAI_VAULT_RESOURCE[] = L"https://platform.openai.com/api-keys";
const wchar_t OPENAI_VAULT_USERNAME[] = L"PowerToys_AdvancedPaste_OpenAIKey";
}
class AdvancedPaste : public PowertoyModuleIface
@ -133,6 +138,34 @@ private:
return jsonObject;
}
static bool open_ai_key_exists()
{
try
{
winrt::Windows::Security::Credentials::PasswordVault vault;
return vault.Retrieve(OPENAI_VAULT_RESOURCE, OPENAI_VAULT_USERNAME) != nullptr;
}
catch (const winrt::hresult_error& ex)
{
// Looks like the only way to access the PasswordVault is through the an API that throws an exception in case the resource doesn't exist.
// If the compiler breaks here when you're debugging, just continue.
// If you want to disable breaking here in a more permanent way, just add a condition in Visual Studio's Exception Settings to not break on win::hresult_error, but that might make you not hit other exceptions you might want to catch.
if (ex.code() == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
{
return false; // Credential doesn't exist.
}
Logger::error("Unexpected error while retrieving OpenAI key from vault: {}", winrt::to_string(ex.message()));
return false;
}
}
bool is_open_ai_enabled()
{
return gpo_policy_enabled_configuration() != powertoys_gpo::gpo_rule_configured_disabled &&
powertoys_gpo::getAllowedAdvancedPasteOnlineAIModelsValue() != powertoys_gpo::gpo_rule_configured_disabled &&
open_ai_key_exists();
}
bool migrate_data_and_remove_data_file(Hotkey& old_paste_as_plain_hotkey)
{
const wchar_t OLD_JSON_KEY_ACTIVATION_SHORTCUT[] = L"ActivationShortcut";
@ -216,7 +249,8 @@ private:
if (propertiesObject.HasKey(JSON_KEY_CUSTOM_ACTIONS))
{
const auto customActions = propertiesObject.GetNamedObject(JSON_KEY_CUSTOM_ACTIONS).GetNamedArray(JSON_KEY_VALUE);
if (customActions.Size() > 0 && is_open_ai_enabled())
{
for (const auto& customAction : customActions)
{
const auto object = customAction.GetObjectW();
@ -232,6 +266,7 @@ private:
}
}
}
}
bool is_process_running() const
{

View File

@ -102,7 +102,10 @@
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="AdvancedPaste_Direct_Access_Hotkeys_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsCard x:Uid="AdvancedPasteUI_Actions" HeaderIcon="{ui:FontIcon Glyph=&#xE792;}">
<tkcontrols:SettingsCard
x:Uid="AdvancedPasteUI_Actions"
HeaderIcon="{ui:FontIcon Glyph=&#xE792;}"
IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}">
<Button
x:Uid="AdvancedPasteUI_AddCustomActionButton"
Click="AddCustomActionButton_Click"
@ -130,6 +133,7 @@
x:Name="CustomActions"
x:Uid="CustomActions"
HorizontalAlignment="Stretch"
IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}"
IsTabStop="False"
ItemsSource="{x:Bind ViewModel.CustomActions, Mode=OneWay}">
<ItemsControl.ItemTemplate>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@ -2000,7 +2000,8 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
<value>Actions</value>
</data>
<data name="AdvancedPasteUI_Actions.Description" xml:space="preserve">
<value>Create and manage advanced paste custom actions</value>
<value>Create and manage advanced paste custom actions.
(Requires Paste with AI to be enabled)</value>
</data>
<data name="AdvancedPasteUI_AddCustomActionButton.Content" xml:space="preserve">
<value>Add custom action</value>

View File

@ -397,6 +397,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
PasswordCredential cred = vault.Retrieve("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey");
vault.Remove(cred);
OnPropertyChanged(nameof(IsOpenAIEnabled));
NotifySettingsChanged();
}
catch (Exception)
{
@ -411,6 +412,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
PasswordCredential cred = new PasswordCredential("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey", password);
vault.Add(cred);
OnPropertyChanged(nameof(IsOpenAIEnabled));
NotifySettingsChanged();
}
catch (Exception)
{