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

Handle bad credential exception and block update submissions with no changes #100

Merged
merged 11 commits into from
Jul 3, 2021
8 changes: 7 additions & 1 deletion src/WingetCreateCLI/Commands/BaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public async Task<bool> SetAndCheckGitHubToken(bool cacheToken = false)

return true;
}
catch
catch (Exception e)
{
if (token == cachedToken)
{
Expand All @@ -158,6 +158,12 @@ public async Task<bool> SetAndCheckGitHubToken(bool cacheToken = false)
GitHubOAuth.DeleteTokenCache();
return await this.SetAndCheckGitHubToken();
}
else if (e is AuthorizationException)
{
Logger.ErrorLocalized(nameof(Resources.Error_Prefix), e.Message);
Logger.ErrorLocalized(nameof(Resources.InvalidTokenError_Message));
return false;
}
else
{
throw;
Expand Down
497 changes: 255 additions & 242 deletions src/WingetCreateCLI/Commands/NewCommand.cs

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions src/WingetCreateCLI/Commands/SubmitCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,16 @@ public override async Task<bool> Execute()

private async Task<bool> SubmitManifest()
{
Manifests manifests = new Manifests();

if (File.Exists(this.Path) && ValidateManifest(this.Path))
{
Manifests manifests = new Manifests();
manifests.SingletonManifest = Serialization.DeserializeFromPath<SingletonManifest>(this.Path);
return await this.GitHubSubmitManifests(manifests, this.GitHubToken);
}
else if (Directory.Exists(this.Path) && ValidateManifest(this.Path))
{
List<string> manifestContents = Directory.GetFiles(this.Path).Select(f => File.ReadAllText(f)).ToList();

Serialization.DeserializeManifestContents(manifestContents, manifests);
Manifests manifests = Serialization.DeserializeManifestContents(manifestContents);
return await this.GitHubSubmitManifests(manifests, this.GitHubToken);
}
else
Expand Down
582 changes: 307 additions & 275 deletions src/WingetCreateCLI/Commands/UpdateCommand.cs

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions src/WingetCreateCLI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace Microsoft.WingetCreateCLI
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using CommandLine;
using CommandLine.Text;
Expand Down Expand Up @@ -35,13 +37,15 @@ private static async Task<int> Main(string[] args)
Logger.Trace($"Command line args: {arguments}");

Parser myParser = new Parser(config => config.HelpWriter = null);

var parserResult = myParser.ParseArguments<NewCommand, UpdateCommand, SubmitCommand, TokenCommand, SettingsCommand>(args);
BaseCommand command = parserResult.MapResult(c => c as BaseCommand, err => null);

var types = GetVerbs();
var parserResult = myParser.ParseArguments(args, types);
BaseCommand command = parserResult.MapResult(c => c as BaseCommand, err => null);

if (command == null)
{
DisplayHelp(parserResult as NotParsed<object>);
return 1;
return args.Any() ? 1 : 0;
}

try
Expand All @@ -61,7 +65,13 @@ private static async Task<int> Main(string[] args)
Logger.Error(ex.ToString());
return 1;
}
}
}

private static Type[] GetVerbs()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(types => types.GetCustomAttribute<VerbAttribute>() != null).ToArray();
}

private static void DisplayHelp(NotParsed<object> result)
{
Expand Down
27 changes: 27 additions & 0 deletions src/WingetCreateCLI/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/WingetCreateCLI/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,15 @@
<data name="UnexpectedErrorLoadSettings_Message" xml:space="preserve">
<value>Unexpected error while loading settings. Please verify your settings by running the settings command.</value>
</data>
<data name="CompareUpdatedManifestWithExisting_Message" xml:space="preserve">
<value>Please ensure that the updated manifest you are submitting is different from the existing package.</value>
</data>
<data name="InvalidTokenError_Message" xml:space="preserve">
<value>Invalid token provided, please generate a new GitHub token and try again.</value>
</data>
<data name="NoChangeDetectedInUpdatedManifest_Message" xml:space="preserve">
<value>Submitting a manifest without any updated changes is not allowed. </value>
</data>
<data name="MissingPackageError_Message" xml:space="preserve">
<value>New package found for {0} {1} installer, but not found in existing manifest</value>
<comment>{0} - will be replaced with installer type
Expand Down
8 changes: 6 additions & 2 deletions src/WingetCreateCore/Common/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ public static string ConvertYamlToJson(string yaml)
/// Deserializes a list of manifest strings into their appropriate object models.
/// </summary>
/// <param name="manifestContents">List of manifest string contents.</param>
/// <param name="manifests">Wrapper object for manifest object models.</param>
public static void DeserializeManifestContents(IEnumerable<string> manifestContents, Manifests manifests)
/// <returns>Manifest object model.</returns>
public static Manifests DeserializeManifestContents(IEnumerable<string> manifestContents)
{
Manifests manifests = new Manifests();

foreach (string content in manifestContents)
{
string trimmedContent = RemoveBom(content);
Expand Down Expand Up @@ -171,6 +173,8 @@ public static void DeserializeManifestContents(IEnumerable<string> manifestConte
manifests.InstallerManifest = Serialization.DeserializeFromString<InstallerManifest>(trimmedContent);
}
}

return manifests;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
PackageIdentifier: TestPublisher.NoUpdate
PackageName: ExeTest
PackageVersion: 1.2.3.4
Publisher: TestPublisher
Author: Microsoft
License: MIT
LicenseUrl: https://github.com/microsoft/winget-create
MinimumOSVersion: 10.0.0.0
ShortDescription: Testing WingetCreate with an exe installer using an up-to-date manifest
PackageLocale: en-US
Tags:
- Windows Package Manager
- winget create
- package manager
- utility
- tool
- test
InstallerType: exe
InstallerSwitches:
Silent: --silent
SilentWithProgress: --silent
Installers:
- Architecture: x64
InstallerUrl: https://fakedomain.com/WingetCreateTestExeInstaller.exe
InstallerSha256: 71A2BF371B23C9432F4E0E08AE6F2A754067F0FE09C0141556DE4AF628F6B371
ManifestType: singleton
ManifestVersion: 1.0.0
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ public async Task UpdateCommandGitHubManifestTest()
string manifestDir = Utils.GetAppManifestDirPath(TestConstants.TestPackageIdentifier, version);
var updatedManifestContents = Directory.GetFiles(Path.Combine(this.tempPath, manifestDir)).Select(f => File.ReadAllText(f));
Assert.IsTrue(updatedManifestContents.Any(), "Updated manifests were not created successfully");
var manifestsToValidate = new Manifests();
Serialization.DeserializeManifestContents(updatedManifestContents, manifestsToValidate);
Manifests manifestsToValidate = Serialization.DeserializeManifestContents(updatedManifestContents);
Assert.AreEqual(version, manifestsToValidate.VersionManifest.PackageVersion, $"Failed to update version of {TestConstants.TestPackageIdentifier}");
}

Expand All @@ -90,8 +89,7 @@ public async Task UpdateAndVerifyUpdatedProperties()
string version = "1.2.3.4";
(UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData(TestConstants.TestMsiPackageIdentifier, version, this.tempPath, null);

var initialManifests = new Manifests();
Serialization.DeserializeManifestContents(initialManifestContent, initialManifests);
var initialManifests = Serialization.DeserializeManifestContents(initialManifestContent);
var initialInstaller = initialManifests.SingletonManifest.Installers.First();

var updatedManifests = await command.DeserializeExistingManifestsAndUpdate(initialManifestContent);
Expand All @@ -115,8 +113,7 @@ public async Task UpdateMultipleUrlManifests()
string version = "1.2.3.4";
(UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData(TestConstants.TestMultipleInstallerPackageIdentifier, version, this.tempPath, null);

var initialManifests = new Manifests();
Serialization.DeserializeManifestContents(initialManifestContent, initialManifests);
var initialManifests = Serialization.DeserializeManifestContents(initialManifestContent);
var initialInstaller = initialManifests.SingletonManifest.Installers.First();

var updatedManifests = await command.DeserializeExistingManifestsAndUpdate(initialManifestContent);
Expand Down Expand Up @@ -192,6 +189,22 @@ public async Task UpdateFailsWithUnmatchedPackages()
Assert.That(result, Does.Contain(string.Format(Resources.MissingPackageError_Message, InstallerType.Msix, InstallerArchitecture.X86)), "Missing package error should be thrown");
}

/// <summary>
/// Verifies that the update command blocks the submission of a manifest if no installer hash changes are detected.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Test]
public async Task BlockUpdateSubmissionsWithNoUpdate()
{
TestUtils.InitializeMockDownload();
TestUtils.SetMockHttpResponseContent(TestConstants.TestExeInstaller);
(UpdateCommand command, var manifests) = GetUpdateCommandAndManifestData("TestPublisher.NoUpdate", "1.2.3.4", this.tempPath, null);
command.SubmitToGitHub = true;
await command.ExecuteManifestUpdate(manifests, this.testCommandEvent);
string result = this.sw.ToString();
Assert.That(result, Does.Contain(Resources.NoChangeDetectedInUpdatedManifest_Message), "Failed to block manifests without updates from submitting.");
}

private static List<string> GetInitialManifestContent(string manifestFileName)
{
string testFilePath = TestUtils.GetTestFile(manifestFileName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
<None Update="Resources\Multifile.MsixTest\Multifile.MsixTest.locale.en-US.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\TestPublisher.NoUpdate.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\TestPublisher.MismatchedMsixInExistingBundle.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down Expand Up @@ -65,6 +68,6 @@
</None>
<None Update="Resources\TestPublisher.MultipleInstallerApp.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</None>
</ItemGroup>
</Project>