/// <summary> /// Build an instance of <see cref="NodeEntitlements"/> from the information supplied on the /// command line by the user /// </summary> /// <returns>Either a usable (and completely valid) <see cref="NodeEntitlements"/> or a set /// of errors.</returns> private Errorable <NodeEntitlements> Build() { var entitlement = new NodeEntitlements(); var errors = new List <string>(); ConfigureOptional(VirtualMachineId, url => entitlement.WithVirtualMachineId(url)); Configure(NotBefore, notBefore => entitlement.FromInstant(notBefore)); Configure(NotAfter, notAfter => entitlement.UntilInstant(notAfter)); Configure(Audience, audience => entitlement.WithAudience(audience)); Configure(Issuer, issuer => entitlement.WithIssuer(issuer)); ConfigureAll(Addresses, address => entitlement.AddIpAddress(address)); ConfigureAll(Applications, app => entitlement.AddApplication(app)); if (errors.Any()) { return(Errorable.Failure <NodeEntitlements>(errors)); } return(Errorable.Success(entitlement)); // <param name="readConfiguration">function to read the configuration value.</param> // <param name="applyConfiguration">function to modify our configuration with the value read.</param> void Configure <V>(Func <Errorable <V> > readConfiguration, Func <V, NodeEntitlements> applyConfiguration) { readConfiguration().Match( whenSuccessful: value => entitlement = applyConfiguration(value), whenFailure: e => errors.AddRange(e)); } // <param name="readConfiguration">function to read the configuration value.</param> // <param name="applyConfiguration">function to modify our configuration with the value read.</param> void ConfigureOptional <V>(Func <Errorable <V> > readConfiguration, Func <V, NodeEntitlements> applyConfiguration) where V : class
public void WhenSuccess_CallsActionWithExpectedValue() { var errorable = Errorable.Success(43); errorable.Match( v => v.Should().Be(43), errors => throw new InvalidOperationException("Should not be called")); }
public void WhenSuccess_ReturnsExpectedValueFromFunction() { var errorable = Errorable.Success(43); var result = errorable.Match <int>( v => 128, errors => throw new InvalidOperationException("Should not be called")); result.Should().Be(128); }
public void WhenSuccess_CallsFunctionWithExpectedValue() { var errorable = Errorable.Success(43); var result = errorable.Match <int>( v => { v.Should().Be(43); return(128); // Needs a return value so this is a Func<int,int> }, errors => throw new InvalidOperationException("Should not be called")); }
private static Errorable <X509Certificate2> FindCertificate(string purpose, string thumbprint) { if (string.IsNullOrEmpty(thumbprint)) { // No certificate requested, so we successfully return null return(Errorable.Success <X509Certificate2>(null)); } var t = new CertificateThumbprint(thumbprint); return(CertificateStore.FindByThumbprint(purpose, t)); }
private static Errorable <LogLevel> TryParse(string level, string purpose, LogLevel defaultLevel) { if (string.IsNullOrEmpty(level)) { return(Errorable.Success(defaultLevel)); } if (Enum.TryParse <LogLevel>(level, true, out var result)) { // Successfully parsed the string return(Errorable.Success(result)); } return(Errorable.Failure <LogLevel>( $"Failed to recognize {purpose} log level '{level}'; valid choices are: error, warning, information, and debug.")); }
/// <summary> /// Verify the provided software entitlement token /// </summary> /// <param name="tokenString">A software entitlement token to verify.</param> /// <param name="expectedAudience">The audience for whom the token should be intended.</param> /// <param name="expectedIssuer">The issuer who should have created the token.</param> /// <param name="application">The specific application id of the application </param> /// <param name="ipAddress">Address of the machine requesting token validation.</param> /// <returns>Either a software entitlement describing the approved entitlement, or errors /// explaining why it wasn't approved.</returns> public Errorable <NodeEntitlements> Verify( string tokenString, string expectedAudience, string expectedIssuer, string application, IPAddress ipAddress) { var validationParameters = new TokenValidationParameters { ValidateAudience = true, ValidAudience = expectedAudience, ValidateIssuer = true, ValidIssuer = expectedIssuer, ValidateLifetime = true, RequireExpirationTime = true, RequireSignedTokens = SigningKey != null, ClockSkew = TimeSpan.FromSeconds(60), IssuerSigningKey = SigningKey, ValidateIssuerSigningKey = true, TokenDecryptionKey = EncryptionKey }; try { var handler = new JwtSecurityTokenHandler(); var principal = handler.ValidateToken(tokenString, validationParameters, out var token); if (!VerifyApplication(principal, application)) { return(ApplicationNotEntitledError(application)); } if (!VerifyIpAddress(principal, ipAddress)) { return(MachineNotEntitledError(ipAddress)); } var entitlementIdClaim = principal.FindFirst(Claims.EntitlementId); if (entitlementIdClaim == null) { return(IdentifierNotPresentError()); } var result = new NodeEntitlements() .FromInstant(new DateTimeOffset(token.ValidFrom)) .UntilInstant(new DateTimeOffset(token.ValidTo)) .AddApplication(application) .WithIdentifier(entitlementIdClaim.Value) .AddIpAddress(ipAddress); var virtualMachineIdClaim = principal.FindFirst(Claims.VirtualMachineId); if (virtualMachineIdClaim != null) { result = result.WithVirtualMachineId(virtualMachineIdClaim.Value); } return(Errorable.Success(result)); } catch (SecurityTokenNotYetValidException exception) { return(TokenNotYetValidError(exception.NotBefore)); } catch (SecurityTokenExpiredException exception) { return(TokenExpiredError(exception.Expires)); } catch (SecurityTokenException exception) { return(InvalidTokenError(exception.Message)); } }
public void GivenValue_ReturnsResultWithNoErrors() { var result = Errorable.Success(42); result.Errors.Should().HaveCount(0); }
public void WhenSuccess_ReturnsExpectedValue() { var result = Errorable.Success(42); result.Value.Should().Be(42); }
public void GivenValue_ReturnsResultWithValue() { var result = Errorable.Success(42); result.HasValue.Should().BeTrue(); }