/* * Copyright (c) 2022 Vaughn Nugent * * Library: VNLib * Package: VNLib.Data.Caching.Extensions * File: ClientCacheConfiguration.cs * * ClientCacheConfiguration.cs is part of VNLib.Data.Caching.Extensions which is part of the larger * VNLib collection of libraries and utilities. * * VNLib.Data.Caching.Extensions is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * VNLib.Data.Caching.Extensions is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ using System.Security.Cryptography; using VNLib.Hashing; using VNLib.Hashing.IdentityUtility; using VNLib.Net.Messaging.FBM.Client; namespace VNLib.Data.Caching.Extensions { /// /// A fluent api configuration object for configuring a /// to connect to cache servers. /// public sealed class ClientCacheConfiguration { internal ReadOnlyJsonWebKey? SigningKey { get; private set; } internal ReadOnlyJsonWebKey? VerificationKey { get; private set; } internal ReadOnlyJsonWebKey? BrokerVerificationKey { get; private set; } internal string ServerChallenge { get; } = RandomHash.GetRandomBase32(24); internal string? NodeId { get; set; } internal Uri? BrokerAddress { get; set; } internal bool UseTls { get; set; } internal ActiveServer[]? CacheServers { get; set; } internal IReadOnlyDictionary JwtHeader => SigningKey!.JwtHeader; /// /// Imports the private key used to sign messages /// /// The with a private key loaded /// Chainable fluent object /// /// public ClientCacheConfiguration WithSigningCertificate(ReadOnlyJsonWebKey jwk) { SigningKey = jwk ?? throw new ArgumentNullException(nameof(jwk)); return this; } /// /// Imports the public key used to verify messages from the remote server /// /// The public key only used for message verification /// Chainable fluent object /// /// public ClientCacheConfiguration WithVerificationKey(ReadOnlyJsonWebKey jwk) { VerificationKey = jwk ?? throw new ArgumentNullException(nameof(jwk)); return this; } public ClientCacheConfiguration WithBrokerVerificationKey(ReadOnlyJsonWebKey jwk) { BrokerVerificationKey = jwk ?? throw new ArgumentNullException(nameof(jwk)); return this; } /// /// Specifies if all connections should be using TLS /// /// A value that indicates if connections should use TLS /// Chainable fluent object public ClientCacheConfiguration WithTls(bool useTls) { UseTls = useTls; return this; } /// /// Specifies the broker address to discover cache nodes from /// /// The address of the server broker /// Chainable fluent object /// public ClientCacheConfiguration WithBroker(Uri brokerAddress) { this.BrokerAddress = brokerAddress ?? throw new ArgumentNullException(nameof(brokerAddress)); return this; } /// /// Specifies the current server's cluster node id. If this /// is a server connection attempting to listen for changes on the /// remote server, this id must be set and unique /// /// The cluster node id of the current server /// Chainable fluent object /// public ClientCacheConfiguration WithNodeId(string nodeId) { this.NodeId = nodeId ?? throw new ArgumentNullException(nameof(nodeId)); return this; } internal void SignJwt(JsonWebToken jwt) { jwt.SignFromJwk(SigningKey); } internal bool VerifyCache(JsonWebToken jwt) { return jwt.VerifyFromJwk(VerificationKey); } internal bool VerifyBroker(JsonWebToken jwt) { return jwt.VerifyFromJwk(BrokerVerificationKey); } } }