/// <summary> /// Restrict Updates. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying a <see cref="ThreatList" /> to restrict updates to. /// </param> /// <returns> /// This managed service builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> public ManagedBrowsingServiceBuilder RestrictUpdatesTo(ThreatListDescriptor threatListDescriptor) { // ... // // Throws an exception if the operation fails. return(this.RestrictUpdatesTo(threatListDescriptor, ThreatListUpdateConstraints.Default)); }
/// <summary> /// Create a Full Hash Query. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="Browsing.ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> to query. /// </param> /// <param name="threatListState"> /// The state, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference, or if /// <paramref name="threatListState" /> is a null reference. /// </exception> /// <exception cref="System.FormatException"> /// Thrown if <paramref name="threatListState" /> is not hexadecimal encoded. /// </exception> public FullHashQuery(ThreatListDescriptor threatListDescriptor, string threatListState) { Guard.ThrowIf(nameof(threatListDescriptor), threatListDescriptor).Null(); this.ThreatListDescriptor = threatListDescriptor; this.ThreatListState = CreateThreatListState(threatListState); // <summary> // Create Threat List State. // </summary> string CreateThreatListState(string cThreatListState) { // ... // // Throws an exception if the operation fails. var cIsThreatListStateHexadecimalEncoded = cThreatListState.IsHexadecimalEncoded(); if (!cIsThreatListStateHexadecimalEncoded) { var cDetailMessage = $"A threat list state ({cThreatListState}) is not hexadecimal encoded."; throw new FormatException(cDetailMessage); } return(cThreatListState); } }
/// <summary> /// Set Threat List Descriptor. /// </summary> /// <param name="value"> /// A <see cref="Browsing.ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> to retrieve. /// </param> /// <returns> /// This threat list update query builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="value" /> is a null reference. /// </exception> public ThreatListUpdateQueryBuilder SetThreatListDescriptor(ThreatListDescriptor value) { Guard.ThrowIf(nameof(value), value).Null(); this.ThreatListDescriptor = value; return(this); }
/// <summary> /// Get Threats Asynchronously. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> the threats that should /// be retrieved are associated with. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// A collection of SHA256 hash prefixes, formatted as hexadecimal encoded strings, identifying the threats /// that are associated with the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. An empty collection indicates no threats were found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if the object is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> public async Task <IReadOnlyCollection <string> > GetThreatsAsync(ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { this.ThrowIfDisposed(); try { var getThreatsTask = this._database.GetThreatsAsync(threatListDescriptor, cancellationToken); var threats = await getThreatsTask.ConfigureAwait(false); return(threats); } catch (ArgumentNullException) { throw; } catch (BrowsingDatabaseException) { throw; } catch (ObjectDisposedException) { this.Dispose(); throw; } catch (OperationCanceledException) { throw; } catch (Exception ex) { const string detailMessage = "A threat list's associated threats could not be retrieved."; throw new BrowsingDatabaseException(detailMessage, ex); } }
/// <summary> /// Restrict Updates. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying a <see cref="ThreatList" /> to restrict updates to. /// </param> /// <param name="updateConstraints"> /// The <see cref="ThreatListUpdateConstraints" /> to apply when the <see cref="ThreatList" /> identified /// by <paramref name="threatListDescriptor" /> is retrieved. /// </param> /// <returns> /// This managed service builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference, or if /// <paramref name="updateConstraints" /> is a null reference. /// </exception> public ManagedBrowsingServiceBuilder RestrictUpdatesTo(ThreatListDescriptor threatListDescriptor, ThreatListUpdateConstraints updateConstraints) { Guard.ThrowIf(nameof(threatListDescriptor), threatListDescriptor).Null(); Guard.ThrowIf(nameof(updateConstraints), updateConstraints).Null(); this.UpdateConstraints[threatListDescriptor] = updateConstraints; return(this); }
/// <summary> /// Restrict Updates. /// </summary> /// <param name="threatType"> /// A <see cref="ThreatType" /> identifying a <see cref="ThreatList" /> to restrict updates to. /// </param> /// <param name="platformType"> /// A <see cref="PlatformType" /> identifying a <see cref="ThreatList" /> to restrict updates to. /// </param> /// <param name="threatEntryType"> /// A <see cref="ThreatEntryType" /> identifying a <see cref="ThreatList" /> to restrict updates to. /// </param> /// <param name="updateConstraints"> /// The <see cref="ThreatListUpdateConstraints" /> to apply when the <see cref="ThreatList" /> identified /// by <paramref name="threatType" />, <paramref name="platformType" />, and /// <paramref name="threatEntryType" /> is retrieved. /// </param> /// <returns> /// This managed service builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="updateConstraints" /> is a null reference. /// </exception> public ManagedBrowsingServiceBuilder RestrictUpdatesTo(ThreatType threatType, PlatformType platformType, ThreatEntryType threatEntryType, ThreatListUpdateConstraints updateConstraints) { Guard.ThrowIf(nameof(updateConstraints), updateConstraints).Null(); var threatListDescriptor = new ThreatListDescriptor(threatType, platformType, threatEntryType); this.UpdateConstraints[threatListDescriptor] = updateConstraints; return(this); }
public Task <IReadOnlyCollection <string> > GetThreatsAsync(ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { this.ThrowIfDisposed(); Func <Task <IReadOnlyCollection <string> > > resiliencyPolicyAction = () => this._database.GetThreatsAsync(threatListDescriptor, cancellationToken); var executeResiliencyPolicyTask = this.ExecuteResiliencyPolicyAsync(resiliencyPolicyAction); return(executeResiliencyPolicyTask); }
/// <summary> /// Add a Query. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> to query. /// </param> /// <param name="threatListState"> /// The state, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. /// </param> /// <returns> /// This full hash request builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference, or if /// <paramref name="threatListState" /> is a null reference. /// </exception> /// <exception cref="System.FormatException"> /// Thrown if <paramref name="threatListState" /> is not hexadecimal encoded. /// </exception> public FullHashRequestBuilder AddQuery(ThreatListDescriptor threatListDescriptor, string threatListState) { // ... // // Throws an exception if the operation fails. var query = new FullHashQuery(threatListDescriptor, threatListState); this.Queries.Add(query); return(this); }
/// <summary> /// Add an Unsafe Threat. /// </summary> /// <param name="sha256Hash"> /// A full SHA256 hash, formatted as a hexadecimal encoded string, identifying the threat. /// </param> /// <param name="associatedThreatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> the threat is /// associated with. /// </param> /// <param name="expirationDate"> /// The date, in Coordinated Universal Time (UTC), the threat should be considered unsafe to. If the date /// is not in UTC, it is converted to it. /// </param> /// <returns> /// This full hash response builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="sha256Hash" /> is a null reference, or if /// <paramref name="associatedThreatListDescriptor" /> is a null reference. /// </exception> /// <exception cref="System.FormatException"> /// Thrown if <paramref name="sha256Hash" /> is not hexadecimal encoded. /// </exception> public FullHashResponseBuilder AddUnsafeThreat(string sha256Hash, ThreatListDescriptor associatedThreatListDescriptor, DateTime expirationDate) { // ... // // Throws an exception if the operation fails. var unsafeThreat = new UnsafeThreat(sha256Hash, associatedThreatListDescriptor, expirationDate); this.UnsafeThreats.Add(unsafeThreat); return(this); }
/// <summary> /// Get Threats Asynchronously. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> the threats that should /// be retrieved are associated with. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// A collection of SHA256 hash prefixes, formatted as hexadecimal encoded strings, identifying the threats /// that are associated with the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. An empty collection indicates no threats were found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if the object is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> public virtual Task <IReadOnlyCollection <string> > GetThreatsAsync(ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { this.ThrowIfDisposed(); // ... // // Throws an exception if the operation fails. var getThreatsTask = this._database.GetThreatsAsync(threatListDescriptor, cancellationToken); return(getThreatsTask); }
/// <summary> /// Get a Threat List Asynchronously. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> to retrieve. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// The <see cref="ThreatList" /> identified by <paramref name="threatListDescriptor" />. A null reference /// indicates a threat list could not be found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if the object is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> public Task <ThreatList> GetThreatListAsync(ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { this.ThrowIfDisposed(); lock (this._lock) { // ... // // Throws an exception if the operation fails. this._threatLists.TryGetValue(threatListDescriptor, out var threatList); var getThreatListTask = Task.FromResult(threatList); return(getThreatListTask); } }
/// <summary> /// Create a Threat List Descriptor. /// </summary> /// <param name="this"> /// A <see cref="ThreatListDescriptorModel" />. /// </param> /// <returns> /// A <see cref="ThreatListDescriptor" /> if <paramref name="this" /> is not a null reference. A null /// reference otherwise. /// </returns> internal static ThreatListDescriptor AsThreatListDescriptor(this ThreatListDescriptorModel @this) { ThreatListDescriptor threatListDescriptor = null; if (@this != null) { var platformType = @this.PlatformType.AsPlatformType(); var threatEntryType = @this.ThreatEntryType.AsThreatEntryType(); var threatType = @this.ThreatType.AsThreatType(); threatListDescriptor = new ThreatListDescriptor(threatType, platformType, threatEntryType); } return(threatListDescriptor); }
/// <summary> /// Get Threats Asynchronously. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> the threats that should /// be retrieved are associated with. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// A collection of SHA256 hash prefixes, formatted as hexadecimal encoded strings, identifying the threats /// that are associated with the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. An empty collection indicates no threats were found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if the object is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> public Task <IReadOnlyCollection <string> > GetThreatsAsync(ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { this.ThrowIfDisposed(); lock (this._lock) { // ... // // Throws an exception if the operation fails. this._threats.TryGetValue(threatListDescriptor, out var threats); var newThreats = threats ?? (IReadOnlyCollection <string>)Array.Empty <string>(); var getThreatsTask = Task.FromResult(newThreats); return(getThreatsTask); } }
/// <summary> /// Restrict Updates. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying a <see cref="ThreatList" /> to restrict updates to. /// </param> /// <param name="updateConstraintsAction"> /// An action to create the <see cref="ThreatListUpdateConstraints" /> to apply when the /// <see cref="ThreatList" /> identified by <paramref name="threatListDescriptor" /> is retrieved. /// </param> /// <returns> /// This managed service builder. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference, or if /// <paramref name="updateConstraintsAction" /> is a null reference. /// </exception> public ManagedBrowsingServiceBuilder RestrictUpdatesTo(ThreatListDescriptor threatListDescriptor, Func <ThreatListUpdateConstraintsBuilder, ThreatListUpdateConstraints> updateConstraintsAction) { Guard.ThrowIf(nameof(updateConstraintsAction), updateConstraintsAction).Null(); // ... // // Throws an exception if the operation fails. var threatListUpdateConstraintsBuilder = ThreatListUpdateConstraints.Build(); var threatListUpdateConstraints = updateConstraintsAction(threatListUpdateConstraintsBuilder); this.RestrictUpdatesTo(threatListDescriptor, threatListUpdateConstraints); return(this); }
/// <summary> /// Create a Threat List Update Query. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="Browsing.ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> to retrieve. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> public ThreatListUpdateQuery(ThreatListDescriptor threatListDescriptor) : this(threatListDescriptor, null, null) { }
/// <summary> /// Compute a Threat List's Checksum Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> whose checksum should /// be computed. /// </param> /// <param name="cancellationToken"> /// A cancellation token to cancel the asynchronous operation with. /// </param> /// <returns> /// The checksum, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="threatListDescriptor" /> /// is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> /// <exception cref="System.OperationCanceledException"> /// Thrown if the asynchronous operation is cancelled. /// </exception> public static async Task <string> ComputeThreatListChecksumAsync(this IUnmanagedBrowsingDatabase @this, ThreatListDescriptor threatListDescriptor, CancellationToken cancellationToken) { Guard.ThrowIf(nameof(@this), @this).Null(); // ... // // Throws an exception if the operation fails. var getThreatsTask = @this.GetThreatsAsync(threatListDescriptor, cancellationToken); var threats = await getThreatsTask.ConfigureAwait(false); try { string threatListChecksum = null; if (threats.Count != 0) { // ... // // Throws an exception if the decoding, hashing, or encoding operations fail. They will typically // fail if the database is corrupt in anyway. threatListChecksum = threats.OrderBy(t => t) .Join() .HexadecimalDecode() .Sha256Hash() .HexadecimalEncode(); } return(threatListChecksum); } catch (Exception ex) { const string detailMessage = "A threat list's checksum could not be computed."; throw new BrowsingDatabaseException(detailMessage, ex); } }
/// <summary> /// Compute a Threat List's Checksum Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> whose checksum should /// be computed. /// </param> /// <returns> /// The checksum, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="threatListDescriptor" /> /// is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> public static Task <string> ComputeThreatListChecksumAsync(this IUnmanagedBrowsingDatabase @this, ThreatListDescriptor threatListDescriptor) { // ... // // Throws an exception if the operation fails. return(@this.ComputeThreatListChecksumAsync(threatListDescriptor, CancellationToken.None)); }
/// <summary> /// Get Threats Asynchronously. /// </summary> /// <param name="this"> /// An <see cref="IUnmanagedBrowsingDatabase" />. /// </param> /// <param name="threatListDescriptor"> /// A <see cref="ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> the threats that should /// be retrieved are associated with. /// </param> /// <returns> /// A collection of SHA256 hash prefixes, formatted as hexadecimal encoded strings, identifying the threats /// that are associated with the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. An empty collection indicates no threats were found. /// </returns> /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException"> /// Thrown if a database error occurs. /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="this" /> is a null reference, or if <paramref name="threatListDescriptor" /> /// is a null reference. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// Thrown if <paramref name="this" /> is disposed. /// </exception> public static Task <IReadOnlyCollection <string> > GetThreatsAsync(this IUnmanagedBrowsingDatabase @this, ThreatListDescriptor threatListDescriptor) { Guard.ThrowIf(nameof(@this), @this).Null(); // ... // // Throws an exception if the operation fails. var getThreatsTask = @this.GetThreatsAsync(threatListDescriptor, CancellationToken.None); return(getThreatsTask); }
/// <summary> /// Create a Threat List Update Query. /// </summary> /// <param name="threatListDescriptor"> /// A <see cref="Browsing.ThreatListDescriptor" /> identifying the <see cref="ThreatList" /> to retrieve. /// </param> /// <param name="threatListState"> /// The state, formatted as a hexadecimal encoded string, of the <see cref="ThreatList" /> identified by /// <paramref name="threatListDescriptor" />. This should be the value returned by the Google Safe Browsing /// API when the threat list was most recently retrieved. An invalid state will be ignored by the Google /// Safe Browsing API and will force the threat list to be retrieved as a /// <see cref="ThreatListUpdateType.Full" /> update. A null reference indicates the state of the threat /// list is unknown and will force the threat list to be retrieved as a /// <see cref="ThreatListUpdateType.Full" /> update. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="threatListDescriptor" /> is a null reference. /// </exception> /// <exception cref="System.FormatException"> /// Thrown if <paramref name="threatListState" /> is not a null reference and it is not hexadecimal /// encoded. /// </exception> public ThreatListUpdateQuery(ThreatListDescriptor threatListDescriptor, string threatListState) : this(threatListDescriptor, threatListState, null) { }
/// <summary> /// Create an Unsafe Threat. /// </summary> /// <param name="this"> /// An <see cref="UnsafeThreatModel" />. /// </param> /// <returns> /// An <see cref="UnsafeThreat" /> if <paramref name="this" /> is not a null reference. A null reference /// otherwise. /// </returns> internal static UnsafeThreat AsUnsafeThreat(this UnsafeThreatModel @this) { UnsafeThreat unsafeThreat = null; if (@this != null) { var associatedThreatListDescriptor = CreateAssociatedThreatListDescriptor(@this); var expirationDate = CreateExpirationDate(@this); var sha256Hash = @this.Threat.Sha256Hash.Base64Decode().HexadecimalEncode(); unsafeThreat = new UnsafeThreat(sha256Hash, associatedThreatListDescriptor, expirationDate); unsafeThreat.Metadata = CreateMetadata(@this); } return(unsafeThreat); // <summary> // Create Associated Threat List Descriptor. // </summary> ThreatListDescriptor CreateAssociatedThreatListDescriptor(UnsafeThreatModel cThis) { var cPlatformType = cThis.PlatformType.AsPlatformType(); var cThreatEntryType = cThis.ThreatEntryType.AsThreatEntryType(); var cThreatType = cThis.ThreatType.AsThreatType(); var cAssociatedThreatListDescriptor = new ThreatListDescriptor(cThreatType, cPlatformType, cThreatEntryType); return(cAssociatedThreatListDescriptor); } // <summary> // Create Expiration Date. // </summary> DateTime CreateExpirationDate(UnsafeThreatModel cThis) { var cExpirationDate = DateTime.UtcNow; if (cThis.CacheDuration != null) { var cCacheDuration = cThis.CacheDuration.Substring(0, cThis.CacheDuration.Length - 1); var cIsCacheDurationParsed = double.TryParse(cCacheDuration, out var cCacheDurationDouble); if (cIsCacheDurationParsed) { cExpirationDate = DateTime.UtcNow.AddSeconds(cCacheDurationDouble); } } return(cExpirationDate); } Dictionary <string, string> CreateMetadata(UnsafeThreatModel cThis) { var cMetadata = new Dictionary <string, string>(); if (cThis.Metadata?.Entries != null) { foreach (var cMetadataEntry in cThis.Metadata.Entries) { var cKey = cMetadataEntry.Key.Base64Decode().AsciiDecode(); var cValue = cMetadataEntry.Value.Base64Decode().AsciiDecode(); cMetadata[cKey] = cValue; } } return(cMetadata); } }