From 19b3b5ee94ea4fbb04691e7e45935fcbfb1b17b1 Mon Sep 17 00:00:00 2001 From: Ryan <69221034+ryfu-msft@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:05:45 -0400 Subject: [PATCH] Add pwsh support for trust level and explicit (#4750) Adds support for `-TrustLevel` and `-Explicit`. The pwsh tests can now use the Add-winGetsource cmdlet to modify the trust level. Updated Get-WinGetsource to report the TrustLevel and Explicit flag. Updated tests and docs to reflect these changes. --- .../Shared/Strings/en-us/winget.resw | 2 +- .../PackageCatalogInfo.cpp | 4 ++ .../PackageCatalogInfo.h | 1 + .../PackageManager.idl | 8 +++- .../Add-WinGetSource.md | 38 ++++++++++++++++++- .../Cmdlets/AddSourceCmdlet.cs | 24 +++++++++++- .../Cmdlets/PSObjects/PSSourceTrustLevel.cs | 29 ++++++++++++++ .../Commands/CliCommand.cs | 30 ++++++++++----- .../PSObjects/PSSourceResult.cs | 16 ++++++-- .../ModuleFiles/Format.ps1xml | 12 ++++++ .../tests/Microsoft.WinGet.Client.Tests.ps1 | 9 ++--- 11 files changed, 151 insertions(+), 22 deletions(-) create mode 100644 src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSSourceTrustLevel.cs diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw index d4af72d952..c1d8771680 100644 --- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw +++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -2874,7 +2874,7 @@ Please specify one of them using the --source option to proceed. Sets the value of an admin setting. - + Excludes a source from discovery unless specified diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp b/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp index 1ecdb03f5e..bd35b7c047 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp +++ b/src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp @@ -59,4 +59,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation return PackageCatalogTrustLevel::None; } } + bool PackageCatalogInfo::Explicit() + { + return m_sourceDetails.Explicit; + } } diff --git a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h index 1f720463f0..efee699c3a 100644 --- a/src/Microsoft.Management.Deployment/PackageCatalogInfo.h +++ b/src/Microsoft.Management.Deployment/PackageCatalogInfo.h @@ -22,6 +22,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Windows::Foundation::DateTime LastUpdateTime(); winrt::Microsoft::Management::Deployment::PackageCatalogOrigin Origin(); winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel TrustLevel(); + bool Explicit(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index bab9af2985..43ade7aa71 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -2,7 +2,7 @@ // Licensed under the MIT License. namespace Microsoft.Management.Deployment { - [contractversion(10)] + [contractversion(11)] // For version 1.9 apicontract WindowsPackageManagerContract{}; /// State of the install @@ -262,6 +262,12 @@ namespace Microsoft.Management.Deployment PackageCatalogOrigin Origin { get; }; /// The trust level of the package catalog PackageCatalogTrustLevel TrustLevel { get; }; + + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)] + { + /// Excludes a source from discovery unless specified. + Boolean Explicit{ get; }; + } } /// A metadata item of a package version. diff --git a/src/PowerShell/Help/Microsoft.WinGet.Client/Add-WinGetSource.md b/src/PowerShell/Help/Microsoft.WinGet.Client/Add-WinGetSource.md index ca1c4c9c71..3d15824d30 100644 --- a/src/PowerShell/Help/Microsoft.WinGet.Client/Add-WinGetSource.md +++ b/src/PowerShell/Help/Microsoft.WinGet.Client/Add-WinGetSource.md @@ -15,7 +15,7 @@ Adds a new source. ## SYNTAX ``` -Add-WinGetSource -Name -Argument [-Type ] [] +Add-WinGetSource -Name -Argument [-Type ] [-TrustLevel {Default | None | Trusted}] [-Explicit] [] ``` ## DESCRIPTION @@ -68,6 +68,42 @@ Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` +### -Explicit + +Excludes a source from discovery unless specified. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -TrustLevel + +Specify the trust level of the WinGet source. The parameter accepts the following values: + +- `None` +- `Trusted` + +```yaml +Type: Microsoft.WinGet.Client.PSObjects.PSSourceTrustLevel +Parameter Sets: (All) +Aliases: +Accepted values: None, Trusted + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + ### -Type The type of the WinGet source. Most sources are `Microsoft.Rest`. The WinGet community repository diff --git a/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/AddSourceCmdlet.cs b/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/AddSourceCmdlet.cs index fc7abd2da8..03a5e75793 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/AddSourceCmdlet.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/AddSourceCmdlet.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -7,6 +7,7 @@ namespace Microsoft.WinGet.Client.Cmdlets.Cmdlets { using System.Management.Automation; + using Microsoft.WinGet.Client.Cmdlets.PSObjects; using Microsoft.WinGet.Client.Common; using Microsoft.WinGet.Client.Engine.Commands; @@ -42,13 +43,32 @@ public sealed class AddSourceCmdlet : PSCmdlet ValueFromPipelineByPropertyName = true)] public string Type { get; set; } + /// + /// Gets or sets the trust level of the source to add. + /// + [Parameter(ValueFromPipelineByPropertyName = true)] + public PSSourceTrustLevel TrustLevel { get; set; } = PSSourceTrustLevel.Default; + + /// + /// Gets or sets a value indicating whether the source to add is explicit. + /// + /// + [Parameter(ValueFromPipelineByPropertyName = true)] + public SwitchParameter Explicit { get; set; } + /// /// Adds source. /// protected override void ProcessRecord() { var command = new CliCommand(this); - command.AddSource(this.Name, this.Argument, this.Type); + command.AddSource(this.Name, this.Argument, this.Type, this.ConvertPSSourceTrustLevelToString(this.TrustLevel), this.Explicit.ToBool()); } + + private string ConvertPSSourceTrustLevelToString(PSSourceTrustLevel trustLevel) => trustLevel switch + { + PSSourceTrustLevel.Default => string.Empty, + _ => trustLevel.ToString(), + }; } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSSourceTrustLevel.cs b/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSSourceTrustLevel.cs new file mode 100644 index 0000000000..02a32f6ac2 --- /dev/null +++ b/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSSourceTrustLevel.cs @@ -0,0 +1,29 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Cmdlets.PSObjects +{ + /// + /// This is the powershell argument equivalent of AppInstaller::Repository::SourceTrustLevel. + /// + public enum PSSourceTrustLevel + { + /// + /// Let winget decide. + /// + Default, + + /// + /// None. + /// + None, + + /// + /// Trusted. + /// + Trusted, + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/CliCommand.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/CliCommand.cs index 5a1390e020..b089e14531 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/CliCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/CliCommand.cs @@ -33,7 +33,7 @@ public CliCommand(PSCmdlet psCmdlet) public void EnableSetting(string name) { Utilities.VerifyAdmin(); - _ = this.Run("settings", $"--enable {name}"); + _ = this.Run("settings", $"--enable \"{name}\""); } /// @@ -43,7 +43,7 @@ public void EnableSetting(string name) public void DisableSetting(string name) { Utilities.VerifyAdmin(); - _ = this.Run("settings", $"--disable {name}"); + _ = this.Run("settings", $"--disable \"{name}\""); } /// @@ -70,17 +70,29 @@ public void GetSettings(bool asPlainText) /// Name of source. /// Arg of source. /// Type of source. - public void AddSource(string name, string arg, string type) + /// Trust level of source. + /// Make source explicit. + public void AddSource(string name, string arg, string type, string trustLevel, bool isExplicit) { Utilities.VerifyAdmin(); - if (string.IsNullOrEmpty(type)) + string parameters = $"add --name \"{name}\" --arg \"{arg}\""; + + if (!string.IsNullOrEmpty(type)) { - _ = this.Run("source", $"add --name {name} --arg {arg}", 300000); + parameters += $" --type \"{type}\""; } - else + + if (!string.IsNullOrEmpty(trustLevel)) { - _ = this.Run("source", $"add --name {name} --arg {arg} --type {type}", 300000); + parameters += $" --trust-level \"{trustLevel}\""; } + + if (isExplicit) + { + parameters += " --explicit"; + } + + _ = this.Run("source", parameters, 300000); } /// @@ -90,7 +102,7 @@ public void AddSource(string name, string arg, string type) public void RemoveSource(string name) { Utilities.VerifyAdmin(); - _ = this.Run("source", $"remove --name {name}"); + _ = this.Run("source", $"remove --name \"{name}\""); } /// @@ -100,7 +112,7 @@ public void RemoveSource(string name) public void ResetSourceByName(string name) { Utilities.VerifyAdmin(); - _ = this.Run("source", $"reset --name {name} --force"); + _ = this.Run("source", $"reset --name \"{name}\" --force"); } /// diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSSourceResult.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSSourceResult.cs index cdaeda9f47..bdea04a132 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSSourceResult.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSSourceResult.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -6,8 +6,6 @@ namespace Microsoft.WinGet.Client.Engine.PSObjects { - using System.Management.Automation; - /// /// SourceResult wrapper object for displaying to PowerShell. /// @@ -23,6 +21,8 @@ internal PSSourceResult(Management.Deployment.PackageCatalogReference catalogRef this.Name = info.Name; this.Argument = info.Argument; this.Type = info.Type; + this.TrustLevel = info.TrustLevel.ToString(); + this.Explicit = info.Explicit; } /// @@ -39,5 +39,15 @@ internal PSSourceResult(Management.Deployment.PackageCatalogReference catalogRef /// Gets the type of the source. /// public string Type { get; private set; } + + /// + /// Gets the trust level of the source. + /// + public string TrustLevel { get; private set; } + + /// + /// Gets a value indicating whether the source must be explicitly specified for discovery. + /// + public bool Explicit { get; private set; } } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/ModuleFiles/Format.ps1xml b/src/PowerShell/Microsoft.WinGet.Client/ModuleFiles/Format.ps1xml index 0578d18083..24f140d6ac 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/ModuleFiles/Format.ps1xml +++ b/src/PowerShell/Microsoft.WinGet.Client/ModuleFiles/Format.ps1xml @@ -283,6 +283,12 @@ + + + + + + @@ -296,6 +302,12 @@ $_.Type + + $_.TrustLevel + + + $_.Explicit + diff --git a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 index 37cc959b45..b48f9b31c6 100644 --- a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 +++ b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 @@ -42,10 +42,7 @@ BeforeAll { Get-WinGetSource -Name 'TestSource' } catch { - # TODO: Add-WinGetSource does not support setting trust level yet. - # Add-WinGetSource -Name 'TestSource' -Arg 'https://localhost:5001/TestKit/' - $sourceAddCommand = "${wingetExeName} source add TestSource https://localhost:5001/TestKit/ --trust-level trusted" - Invoke-Expression -Command $sourceAddCommand + Add-WinGetSource -Name 'TestSource' -Arg 'https://localhost:5001/TestKit/' -TrustLevel 'Trusted' } } @@ -154,7 +151,7 @@ Describe 'Reset-WinGetSource' { Describe 'Get|Add|Reset-WinGetSource' { BeforeAll { - AddTestSource + Add-WinGetSource -Name 'TestSource' -Arg 'https://localhost:5001/TestKit/' -TrustLevel 'Trusted' -Explicit } It 'Get Test source' { @@ -164,6 +161,8 @@ Describe 'Get|Add|Reset-WinGetSource' { $source.Name | Should -Be 'TestSource' $source.Argument | Should -Be 'https://localhost:5001/TestKit/' $source.Type | Should -Be 'Microsoft.PreIndexed.Package' + $source.TrustLevel | Should -Be 'Trusted' + $source.Explicit | Should -Be $true } It 'Get fake source' {