Updating NuGet packages to comply with security policy (#91)

This commit is contained in:
Bevan Arps 2018-01-30 16:25:52 +13:00 коммит произвёл Bevan Arps
Родитель 5c61e9b51f
Коммит 0194afcecc
28 изменённых файлов: 153 добавлений и 73 удалений

Просмотреть файл

@ -82,7 +82,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
/// <param name="storeName">Name of the store to search within.</param> /// <param name="storeName">Name of the store to search within.</param>
/// <param name="storeLocation">Location within the store to check.</param> /// <param name="storeLocation">Location within the store to check.</param>
/// <returns>Sequence of certificates (possibly empty).</returns> /// <returns>Sequence of certificates (possibly empty).</returns>
private IList<X509Certificate2> FindAll(StoreName storeName, StoreLocation storeLocation) private static IList<X509Certificate2> FindAll(StoreName storeName, StoreLocation storeLocation)
{ {
using (var store = new X509Store(storeName, storeLocation)) using (var store = new X509Store(storeName, storeLocation))
{ {

Просмотреть файл

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
@ -72,9 +72,9 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
/// Add an error /// Add an error
/// </summary> /// </summary>
/// <remarks>Will abandon any wrapped value if this is the first error encountered.</remarks> /// <remarks>Will abandon any wrapped value if this is the first error encountered.</remarks>
/// <param name="error">Error to record.</param> /// <param name="message">Error to record.</param>
/// <returns>A new instance with the error included.</returns> /// <returns>A new instance with the error included.</returns>
public abstract Errorable<T> AddError(string error); public abstract Errorable<T> AddError(string message);
/// <summary> /// <summary>
/// Add a sequence of errors /// Add a sequence of errors
@ -130,9 +130,9 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
public override ImmutableHashSet<string> Errors => ImmutableHashSet<string>.Empty; public override ImmutableHashSet<string> Errors => ImmutableHashSet<string>.Empty;
public override Errorable<T> AddError(string error) public override Errorable<T> AddError(string message)
{ {
var errors = ImmutableHashSet<string>.Empty.Add(error); var errors = ImmutableHashSet<string>.Empty.Add(message);
return new FailureImplementation(errors); return new FailureImplementation(errors);
} }
@ -176,9 +176,9 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
public override ImmutableHashSet<string> Errors { get; } public override ImmutableHashSet<string> Errors { get; }
public override Errorable<T> AddError(string error) public override Errorable<T> AddError(string message)
{ {
return new FailureImplementation(Errors.Add(error)); return new FailureImplementation(Errors.Add(message));
} }
/// <summary> /// <summary>

Просмотреть файл

@ -294,7 +294,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
} }
return errorable.Match( return errorable.Match(
async t => Errorable.Success(await transform(t.Item1, t.Item2, t.Item3, t.Item4)), async t => Errorable.Success(await transform(t.Item1, t.Item2, t.Item3, t.Item4).ConfigureAwait(false)),
e => Task.FromResult(Errorable.Failure<R>(e))); e => Task.FromResult(Errorable.Failure<R>(e)));
} }

Просмотреть файл

@ -6,15 +6,16 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" /> <PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Roslynator.Analyzers" Version="1.5.0" /> <PackageReference Include="Roslynator.Analyzers" Version="1.6.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" /> <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
<PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" /> <PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.1.4" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.1.5" />
<PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" /> <PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" />
<PackageReference Include="Serilog" Version="2.5.0" /> <PackageReference Include="Serilog" Version="2.6.0" />
<PackageReference Include="Serilog.Sinks.ColoredConsole" Version="3.0.1" /> <PackageReference Include="Serilog.Sinks.ColoredConsole" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Literate" Version="3.0.0" /> <PackageReference Include="Serilog.Sinks.Literate" Version="3.0.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.4.0" />

Просмотреть файл

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
@ -19,6 +20,10 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
/// <param name="name">Name to use for the value if there is an error.</param> /// <param name="name">Name to use for the value if there is an error.</param>
/// <returns>A succesfully parsed <see cref="DateTimeOffset"/> or errors detailing what /// <returns>A succesfully parsed <see cref="DateTimeOffset"/> or errors detailing what
/// went wrong.</returns> /// went wrong.</returns>
[SuppressMessage(
"Performance",
"CA1822:Mark members as static",
Justification = "This method should not be static.")]
public Errorable<DateTimeOffset> TryParse(string value, string name) public Errorable<DateTimeOffset> TryParse(string value, string name)
{ {
if (DateTimeOffset.TryParseExact( if (DateTimeOffset.TryParseExact(

Просмотреть файл

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -8,7 +8,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common
/// A log provider that unpacks all of the diagnostics that may be in an exception /// A log provider that unpacks all of the diagnostics that may be in an exception
/// </summary> /// </summary>
/// <remarks>Works as a wrapper around an existing provider.</remarks> /// <remarks>Works as a wrapper around an existing provider.</remarks>
public class UnpackingExceptionLogProvider : ILoggerProvider public sealed class UnpackingExceptionLogProvider : ILoggerProvider
{ {
// Reference to our wrapped provider // Reference to our wrapped provider
private readonly ILoggerProvider _innerProvider; private readonly ILoggerProvider _innerProvider;

Просмотреть файл

@ -189,12 +189,12 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Server.Controllers
|| apiVersion.Equals(ApiVersion201709, StringComparison.Ordinal); || apiVersion.Equals(ApiVersion201709, StringComparison.Ordinal);
} }
private bool ApiSupportsVirtualMachineId(string apiVersion) private static bool ApiSupportsVirtualMachineId(string apiVersion)
{ {
return string.Equals(apiVersion, ApiVersion201705, StringComparison.Ordinal); return string.Equals(apiVersion, ApiVersion201705, StringComparison.Ordinal);
} }
private bool ApiSupportsExpiryTimestamp(string apiVersion) private static bool ApiSupportsExpiryTimestamp(string apiVersion)
{ {
return string.Equals(apiVersion, ApiVersion201709, StringComparison.Ordinal); return string.Equals(apiVersion, ApiVersion201709, StringComparison.Ordinal);
} }

Просмотреть файл

@ -6,6 +6,11 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage(
"Design",
"CA1034:Nested types should not be visible",
Justification = "This project uses nested public classes for scoping.")]
[assembly: SuppressMessage( [assembly: SuppressMessage(
"Performance", "Performance",
"RCS1096:Use bitwise operation instead of calling 'HasFlag'.", "RCS1096:Use bitwise operation instead of calling 'HasFlag'.",

Просмотреть файл

@ -23,13 +23,14 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" /> <PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" /> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Roslynator.Analyzers" Version="1.5.0" /> <PackageReference Include="Roslynator.Analyzers" Version="1.6.0" />
<PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" /> <PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

Просмотреть файл

@ -26,6 +26,10 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Server
public IConfigurationRoot Configuration { get; } public IConfigurationRoot Configuration { get; }
[SuppressMessage(
"Performance",
"CA1822: Member ConfigureServices does not access instance data and can be marked as static",
Justification = "Must be non-static to be called by the ASP.NET Runtime.")]
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {

Просмотреть файл

@ -6,13 +6,14 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" /> <PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="psake" Version="4.6.0" /> <PackageReference Include="psake" Version="4.7.0" />
<PackageReference Include="Roslynator.Analyzers" Version="1.5.0" /> <PackageReference Include="Roslynator.Analyzers" Version="1.6.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" /> <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.1.4" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.1.5" />
<PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" /> <PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" />
</ItemGroup> </ItemGroup>

Просмотреть файл

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims; using System.Security.Claims;
using Microsoft.Azure.Batch.SoftwareEntitlement.Common; using Microsoft.Azure.Batch.SoftwareEntitlement.Common;
@ -56,10 +57,10 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
_logger.LogDebug( _logger.LogDebug(
"Not Before: {NotBefore}", "Not Before: {NotBefore}",
entitlements.NotBefore.ToString(TimestampParser.ExpectedFormat)); entitlements.NotBefore.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture));
_logger.LogDebug( _logger.LogDebug(
"Not After: {NotAfter}", "Not After: {NotAfter}",
entitlements.NotAfter.ToString(TimestampParser.ExpectedFormat)); entitlements.NotAfter.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture));
if (SigningCredentials != null) if (SigningCredentials != null)
{ {

Просмотреть файл

@ -1,4 +1,5 @@
using System; using System;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
@ -168,7 +169,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
/// <param name="principal">Principal from the decoded token.</param> /// <param name="principal">Principal from the decoded token.</param>
/// <param name="application">Application that desires to use the entitlement.</param> /// <param name="application">Application that desires to use the entitlement.</param>
/// <returns>True if the entitlement specifies the passed application, false otherwise.</returns> /// <returns>True if the entitlement specifies the passed application, false otherwise.</returns>
private bool VerifyApplication(ClaimsPrincipal principal, string application) private static bool VerifyApplication(ClaimsPrincipal principal, string application)
{ {
var applicationsClaim = principal.FindAll(Claims.Application); var applicationsClaim = principal.FindAll(Claims.Application);
if (!applicationsClaim.Any(c => string.Equals(c.Value, application, StringComparison.OrdinalIgnoreCase))) if (!applicationsClaim.Any(c => string.Equals(c.Value, application, StringComparison.OrdinalIgnoreCase)))
@ -187,7 +188,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
/// <param name="address">IpAddress requesting verification of the token.</param> /// <param name="address">IpAddress requesting verification of the token.</param>
/// <returns>True if the entitlement was issued to the specified IP address, false /// <returns>True if the entitlement was issued to the specified IP address, false
/// otherwise.</returns> /// otherwise.</returns>
private bool VerifyIpAddress(ClaimsPrincipal principal, IPAddress address) private static bool VerifyIpAddress(ClaimsPrincipal principal, IPAddress address)
{ {
var ipAddressClaims = principal.FindAll(Claims.IpAddress).ToList(); var ipAddressClaims = principal.FindAll(Claims.IpAddress).ToList();
foreach (var ipClaim in ipAddressClaims) foreach (var ipClaim in ipAddressClaims)
@ -210,13 +211,13 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
private static Errorable<NodeEntitlements> TokenNotYetValidError(DateTime notBefore) private static Errorable<NodeEntitlements> TokenNotYetValidError(DateTime notBefore)
{ {
var timestamp = notBefore.ToString(TimestampParser.ExpectedFormat); var timestamp = notBefore.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture);
return Errorable.Failure<NodeEntitlements>($"Token will not be valid until {timestamp}"); return Errorable.Failure<NodeEntitlements>($"Token will not be valid until {timestamp}");
} }
private static Errorable<NodeEntitlements> TokenExpiredError(DateTime expires) private static Errorable<NodeEntitlements> TokenExpiredError(DateTime expires)
{ {
var timestamp = expires.ToString(TimestampParser.ExpectedFormat); var timestamp = expires.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture);
return Errorable.Failure<NodeEntitlements>($"Token expired at {timestamp}"); return Errorable.Failure<NodeEntitlements>($"Token expired at {timestamp}");
} }
@ -226,19 +227,19 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
$"Invalid token ({reason})"); $"Invalid token ({reason})");
} }
private Errorable<NodeEntitlements> ApplicationNotEntitledError(string application) private static Errorable<NodeEntitlements> ApplicationNotEntitledError(string application)
{ {
return Errorable.Failure<NodeEntitlements>( return Errorable.Failure<NodeEntitlements>(
$"Token does not grant entitlement for {application}"); $"Token does not grant entitlement for {application}");
} }
private Errorable<NodeEntitlements> MachineNotEntitledError(IPAddress address) private static Errorable<NodeEntitlements> MachineNotEntitledError(IPAddress address)
{ {
return Errorable.Failure<NodeEntitlements>( return Errorable.Failure<NodeEntitlements>(
$"Token does not grant entitlement for {address}"); $"Token does not grant entitlement for {address}");
} }
private Errorable<NodeEntitlements> IdentifierNotPresentError() private static Errorable<NodeEntitlements> IdentifierNotPresentError()
{ {
return Errorable.Failure<NodeEntitlements>( return Errorable.Failure<NodeEntitlements>(
"Entitlement identifier missing from entitlement token."); "Entitlement identifier missing from entitlement token.");

Просмотреть файл

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -69,8 +70,8 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
cert.SubjectName.Name, cert.SubjectName.Name,
cert.FriendlyName, cert.FriendlyName,
cert.Thumbprint, cert.Thumbprint,
cert.NotBefore.ToString(dateFormat), cert.NotBefore.ToString(dateFormat, CultureInfo.InvariantCulture),
cert.NotAfter.ToString(dateFormat), cert.NotAfter.ToString(dateFormat, CultureInfo.InvariantCulture),
status status
}; };
} }

Просмотреть файл

@ -38,7 +38,8 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
(ListCertificatesCommandLine commandLine) => RunCommand(ListCertificates, commandLine), (ListCertificatesCommandLine commandLine) => RunCommand(ListCertificates, commandLine),
(FindCertificateCommandLine commandLine) => RunCommand(FindCertificate, commandLine), (FindCertificateCommandLine commandLine) => RunCommand(FindCertificate, commandLine),
(VerifyCommandLine commandLine) => RunCommand(Submit, commandLine), (VerifyCommandLine commandLine) => RunCommand(Submit, commandLine),
errors => Task.FromResult(ResultCodes.Failed)); errors => Task.FromResult(ResultCodes.Failed))
.ConfigureAwait(false);
if (Debugger.IsAttached) if (Debugger.IsAttached)
{ {
@ -76,7 +77,8 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
{ {
_logger.LogErrors(errors); _logger.LogErrors(errors);
return Task.FromResult(ResultCodes.Failed); return Task.FromResult(ResultCodes.Failed);
}); })
.ConfigureAwait(false);
} }
private static Task<int> RunServer(ServerOptions options) private static Task<int> RunServer(ServerOptions options)
@ -177,7 +179,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
{ {
try try
{ {
return await command(commandLine); return await command(commandLine).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {

Просмотреть файл

@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using CommandLine; using CommandLine;
namespace Microsoft.Azure.Batch.SoftwareEntitlement namespace Microsoft.Azure.Batch.SoftwareEntitlement
@ -20,6 +21,10 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
public string ConnectionCertificateThumbprint { get; set; } public string ConnectionCertificateThumbprint { get; set; }
[Option("url", HelpText = "The URL at which the server should process requests (defaults to '" + DefaultServerUrl + "'; must start with 'https:').")] [Option("url", HelpText = "The URL at which the server should process requests (defaults to '" + DefaultServerUrl + "'; must start with 'https:').")]
[SuppressMessage(
"Design",
"CA1056:Uri properties should not be strings",
Justification = "Must be a string to support our commandline.")]
public string ServerUrl { get; set; } public string ServerUrl { get; set; }
[Option("audience", HelpText = "[Internal] Audience to which all tokens must be addressed (optional).")] [Option("audience", HelpText = "[Internal] Audience to which all tokens must be addressed (optional).")]

Просмотреть файл

@ -35,8 +35,11 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
Errorable<string> app = FindApplication(commandLine); Errorable<string> app = FindApplication(commandLine);
Errorable<string> api = FindApiVersion(commandLine); Errorable<string> api = FindApiVersion(commandLine);
Errorable<string> result = await server.With(token).With(app).With(api) Errorable<string> result = await server.With(token)
.MapAsync(SubmitToken); .With(app)
.With(api)
.MapAsync(SubmitToken)
.ConfigureAwait(false);
return result.Match(response => return result.Match(response =>
{ {
Logger.LogJson(response); Logger.LogJson(response);
@ -72,7 +75,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
var result = await client.PostAsync(uri, content).ConfigureAwait(false); var result = await client.PostAsync(uri, content).ConfigureAwait(false);
Logger.LogInformation($"Status Code: {result.StatusCode} ({(int) result.StatusCode})"); Logger.LogInformation($"Status Code: {result.StatusCode} ({(int) result.StatusCode})");
return await result.Content.ReadAsStringAsync(); return await result.Content.ReadAsStringAsync().ConfigureAwait(false);
} }
} }
@ -93,7 +96,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
return Errorable.Success(token); return Errorable.Success(token);
} }
private Errorable<string> FindApplication(VerifyCommandLine commandLine) private static Errorable<string> FindApplication(VerifyCommandLine commandLine)
{ {
var application = commandLine.Application; var application = commandLine.Application;
if (string.IsNullOrEmpty(application)) if (string.IsNullOrEmpty(application))
@ -128,7 +131,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
} }
} }
private Errorable<string> FindApiVersion(VerifyCommandLine commandLine) private static Errorable<string> FindApiVersion(VerifyCommandLine commandLine)
{ {
var version = commandLine.ApiVersion; var version = commandLine.ApiVersion;
if (string.IsNullOrEmpty(version)) if (string.IsNullOrEmpty(version))
@ -150,7 +153,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement
return result; return result;
} }
private string CreateParameters(params (string name, string value)[] parameters) private static string CreateParameters(params (string name, string value)[] parameters)
{ {
var query = HttpUtility.ParseQueryString(string.Empty); var query = HttpUtility.ParseQueryString(string.Empty);
foreach (var p in parameters) foreach (var p in parameters)

Просмотреть файл

@ -8,16 +8,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" /> <PackageReference Include="CommandLineParser" Version="2.2.1" />
<PackageReference Include="Desktop.Analyzers" Version="1.1.0" />
<PackageReference Include="dotnet-test-nunit" Version="3.4.0-beta-3" /> <PackageReference Include="dotnet-test-nunit" Version="3.4.0-beta-3" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="psake" Version="4.6.0" /> <PackageReference Include="psake" Version="4.7.0" />
<PackageReference Include="Roslynator.Analyzers" Version="1.5.0" /> <PackageReference Include="Roslynator.Analyzers" Version="1.6.0" />
<PackageReference Include="Serilog" Version="2.5.0" /> <PackageReference Include="Serilog" Version="2.6.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" /> <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
<PackageReference Include="Serilog.Sinks.ColoredConsole" Version="3.0.1" /> <PackageReference Include="Serilog.Sinks.ColoredConsole" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />

Просмотреть файл

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -56,6 +56,10 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common.Tests.Fakes
} }
} }
[SuppressMessage(
"Performance",
"CA1815: Should override Equals.",
Justification = "This class doesn't need equality.")]
public struct LogEvent public struct LogEvent
{ {
public LogLevel Level { get; } public LogLevel Level { get; }

Просмотреть файл

@ -6,12 +6,34 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage(
"Design",
"CA1034:Nested types should not be visible",
Justification = "This project uses nested public classes to group related tests.")]
[assembly:SuppressMessage( [assembly:SuppressMessage(
"Design", "Design",
"CA1052", "CA1052",
Justification = "Grouping tests in nested private classes for structure.")] Justification = "Grouping tests in nested private classes for structure.")]
[assembly: SuppressMessage(
"Globalization",
"CA1308:Normalize strings to uppercase",
Justification = "We don't round trip values, just transform for display.")]
[assembly:SuppressMessage(
"Naming",
"CA1707: Remove the underscores from member names",
Justification = "This project uses '_' to separate parts of test names.")]
[assembly: SuppressMessage(
"Performance",
"CA1822:Mark members as static",
Justification = "Some tests don't share intiialization but still need to be non-static")]
[assembly: SuppressMessage( [assembly: SuppressMessage(
"Redundancy", "Redundancy",
"RCS1163:Unused parameter.", "RCS1163:Unused parameter.",
Justification = "Empty implementations used for testing.")] Justification = "Empty implementations used for testing.")]

Просмотреть файл

@ -8,14 +8,15 @@
<PackageReference Include="Castle.Core" Version="4.2.1" /> <PackageReference Include="Castle.Core" Version="4.2.1" />
<PackageReference Include="FluentAssertions" Version="4.19.4" /> <PackageReference Include="FluentAssertions" Version="4.19.4" />
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" /> <PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="Microsoft.TestPlatform.TestHost" Version="15.3.0" /> <PackageReference Include="Microsoft.TestPlatform.TestHost" Version="15.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NSubstitute" Version="3.1.0" /> <PackageReference Include="NSubstitute" Version="3.1.0" />
<PackageReference Include="OpenCover" Version="4.6.519" /> <PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="3.0.2" /> <PackageReference Include="ReportGenerator" Version="3.1.2" />
<PackageReference Include="Roslynator.Analyzers" Version="1.5.0" /> <PackageReference Include="Roslynator.Analyzers" Version="1.6.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" /> <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
<PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" /> <PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" />
<PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit" Version="2.3.1" />

Просмотреть файл

@ -9,7 +9,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common.Tests
// Values to specify // Values to specify
private readonly string _thisStringValue = "this"; private readonly string _thisStringValue = "this";
private readonly string _nullStringValue; private readonly string _nullStringValue = null;
public class Construction : SpecifiableTests public class Construction : SpecifiableTests
{ {

Просмотреть файл

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using Xunit; using Xunit;

Просмотреть файл

@ -1,4 +1,5 @@
using System; using System;
using System.Globalization;
using FluentAssertions; using FluentAssertions;
using Xunit; using Xunit;
@ -43,7 +44,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common.Tests
[Fact] [Fact]
public void GivenTimestampInExpectedFormat_ReturnsExpectedValue() public void GivenTimestampInExpectedFormat_ReturnsExpectedValue()
{ {
var valueToParse = _timestamp.ToString(TimestampParser.ExpectedFormat); var valueToParse = _timestamp.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture);
var result = _parser.TryParse(valueToParse, _name); var result = _parser.TryParse(valueToParse, _name);
result.HasValue.Should().BeTrue(); result.HasValue.Should().BeTrue();
result.Value.Should().Be(_timestamp); result.Value.Should().Be(_timestamp);
@ -52,7 +53,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common.Tests
[Fact] [Fact]
public void GivenTimestampInDifferentFormat_ReturnsExpectedValue() public void GivenTimestampInDifferentFormat_ReturnsExpectedValue()
{ {
var valueToParse = _timestamp.ToString("G"); var valueToParse = _timestamp.ToString("G", CultureInfo.InvariantCulture);
var result = _parser.TryParse(valueToParse, _name); var result = _parser.TryParse(valueToParse, _name);
result.HasValue.Should().BeTrue(); result.HasValue.Should().BeTrue();
result.Value.Should().Be(_timestamp); result.Value.Should().Be(_timestamp);

Просмотреть файл

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
@ -85,7 +85,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Common.Tests
yield return new object[] { invalidOperationException, 1 }; yield return new object[] { invalidOperationException, 1 };
// Another single exception, different type // Another single exception, different type
var argumentException = new ArgumentException(); var argumentException = new ArgumentException("arg");
yield return new object[] { argumentException, 1 }; yield return new object[] { argumentException, 1 };
// Parent and child // Parent and child

Просмотреть файл

@ -1,4 +1,4 @@

// This file is used by Code Analysis to maintain SuppressMessage // This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project. // attributes that are applied to this project.
// Project-level suppressions either have no target or are given // Project-level suppressions either have no target or are given
@ -6,6 +6,26 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage(
"Design",
"CA1034:Nested types should not be visible",
Justification = "This project uses nested public classes to group related tests.")]
[assembly: SuppressMessage(
"Design",
"CA1052",
Justification = "Grouping tests in nested private classes for structure.")]
[assembly: SuppressMessage(
"Naming",
"CA1707: Remove the underscores from member names",
Justification = "This project uses '_' to separate parts of test names.")]
[assembly: SuppressMessage(
"Performance",
"CA1822:Mark members as static",
Justification = "Some tests don't share intiialization but still need to be non-static")]
[assembly: SuppressMessage( [assembly: SuppressMessage(
"Performance", "Performance",
"RCS1096:Use bitwise operation instead of calling 'HasFlag'.", "RCS1096:Use bitwise operation instead of calling 'HasFlag'.",

Просмотреть файл

@ -8,12 +8,13 @@
<PackageReference Include="Castle.Core" Version="4.2.1" /> <PackageReference Include="Castle.Core" Version="4.2.1" />
<PackageReference Include="FluentAssertions" Version="4.19.4" /> <PackageReference Include="FluentAssertions" Version="4.19.4" />
<PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" /> <PackageReference Include="Microsoft.AnalyzerPowerPack" Version="1.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" /> <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NSubstitute" Version="3.1.0" /> <PackageReference Include="NSubstitute" Version="3.1.0" />
<PackageReference Include="OpenCover" Version="4.6.519" /> <PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="3.0.2" /> <PackageReference Include="ReportGenerator" Version="3.1.2" />
<PackageReference Include="Roslynator.Analyzers" Version="1.5.0" /> <PackageReference Include="Roslynator.Analyzers" Version="1.6.0" />
<PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" /> <PackageReference Include="System.Runtime.Analyzers" Version="1.1.0" />
<PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />

Просмотреть файл

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Net; using System.Net;
using FluentAssertions; using FluentAssertions;
using Microsoft.Azure.Batch.SoftwareEntitlement.Common; using Microsoft.Azure.Batch.SoftwareEntitlement.Common;
@ -81,7 +82,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Tests
public class NotBeforeProperty : NodeEntitlementsBuilderTests public class NotBeforeProperty : NodeEntitlementsBuilderTests
{ {
private readonly string _validNotBefore = private readonly string _validNotBefore =
DateTimeOffset.Now.ToString(TimestampParser.ExpectedFormat); DateTimeOffset.Now.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture);
[Fact] [Fact]
public void WhenMissing_BuildStillReturnsValue() public void WhenMissing_BuildStillReturnsValue()
@ -113,7 +114,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Tests
_commandLine.NotBefore = _validNotBefore; _commandLine.NotBefore = _validNotBefore;
var entitlement = NodeEntitlementsBuilder.Build(_commandLine); var entitlement = NodeEntitlementsBuilder.Build(_commandLine);
// Compare as formatted strings to avoid issues with extra seconds we don't care about // Compare as formatted strings to avoid issues with extra seconds we don't care about
entitlement.Value.NotBefore.ToString(TimestampParser.ExpectedFormat) entitlement.Value.NotBefore.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture)
.Should().Be(_validNotBefore); .Should().Be(_validNotBefore);
} }
} }
@ -121,7 +122,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Tests
public class NotAfterProperty : NodeEntitlementsBuilderTests public class NotAfterProperty : NodeEntitlementsBuilderTests
{ {
private readonly string _validNotAfter = private readonly string _validNotAfter =
DateTimeOffset.Now.AddDays(7).ToString(TimestampParser.ExpectedFormat); DateTimeOffset.Now.AddDays(7).ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture);
[Fact] [Fact]
public void WhenMissing_BuildStillReturnsValue() public void WhenMissing_BuildStillReturnsValue()
@ -153,7 +154,7 @@ namespace Microsoft.Azure.Batch.SoftwareEntitlement.Tests
_commandLine.NotAfter = _validNotAfter; _commandLine.NotAfter = _validNotAfter;
var entitlement = NodeEntitlementsBuilder.Build(_commandLine); var entitlement = NodeEntitlementsBuilder.Build(_commandLine);
// Compare as formatted strings to avoid issues with extra seconds we don't care about // Compare as formatted strings to avoid issues with extra seconds we don't care about
entitlement.Value.NotAfter.ToString(TimestampParser.ExpectedFormat) entitlement.Value.NotAfter.ToString(TimestampParser.ExpectedFormat, CultureInfo.InvariantCulture)
.Should().Be(_validNotAfter); .Should().Be(_validNotAfter);
} }
} }