/// <summary>
        ///     Find Full Hashes Asynchronously.
        /// </summary>
        /// <param name="this">
        ///     A <see cref="IBrowsingClient" />.
        /// </param>
        /// <param name="request">
        ///     A <see cref="FullHashRequest" />.
        /// </param>
        /// <returns>
        ///     A <see cref="FullHashResponse" />.
        /// </returns>
        /// <exception cref="Gee.External.Browsing.Clients.BrowsingClientException">
        ///     Thrown if an error communicating with the Google Safe Browsing API occurs.
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        ///     Thrown if <paramref name="this" /> is a null reference, or if <paramref name="request" /> is a null
        ///     reference.
        /// </exception>
        /// <exception cref="System.ObjectDisposedException">
        ///     Thrown if <paramref name="this" /> is disposed.
        /// </exception>
        /// <exception cref="System.TimeoutException">
        ///     Thrown if communication with the Google Safe Browsing API times out.
        /// </exception>
        public static Task <FullHashResponse> FindFullHashesAsync(this IBrowsingClient @this, FullHashRequest request)
        {
            Guard.ThrowIf(nameof(@this), @this).Null();

            // ...
            //
            // Throws an exception if the operation fails.
            var findFullHashesTask = @this.FindFullHashesAsync(request, CancellationToken.None);

            return(findFullHashesTask);
        }
        public static Task <FullHashResponse> FindFullHashesAsync(this IBrowsingClient @this, string sha256HashPrefix, IEnumerable <ThreatList> threatLists, CancellationToken cancellationToken)
        {
            Guard.ThrowIf(nameof(@this), @this).Null();
            Guard.ThrowIf(nameof(threatLists), threatLists).Null();

            // ...
            //
            // Throws an exception if the operation fails.
            var fullHashRequestBuilder = FullHashRequest.Build();

            fullHashRequestBuilder.AddSha256HashPrefix(sha256HashPrefix);
            foreach (var threatList in threatLists)
            {
                fullHashRequestBuilder.AddQuery(threatList.Descriptor, threatList.State);
            }

            // ...
            //
            // Throws an exception if the operation fails.
            var fullHashRequest    = fullHashRequestBuilder.Build();
            var findFullHashesTask = @this.FindFullHashesAsync(fullHashRequest, cancellationToken);

            return(findFullHashesTask);
        }
Exemplo n.º 3
0
        /// <summary>
        ///     Lookup a URL.
        /// </summary>
        /// <param name="cache">
        ///     A <see cref="IBrowsingCache" />.
        /// </param>
        /// <param name="client">
        ///     A <see cref="IBrowsingClient" />.
        /// </param>
        /// <param name="database">
        ///     An <see cref="IUnmanagedBrowsingDatabase" />.
        /// </param>
        /// <param name="url">
        ///     A <see cref="Url" /> to lookup.
        /// </param>
        /// <param name="cancellationToken">
        ///     A cancellation token to cancel the asynchronous operation with.
        /// </param>
        /// <returns>
        ///     A <see cref="UrlLookupResult" /> indicating whether <paramref name="url" /> is
        ///     <see cref="UrlLookupResultCode.Safe" /> or <see cref="UrlLookupResultCode.Unsafe" />.
        /// </returns>
        /// <exception cref="Gee.External.Browsing.Cache.BrowsingCacheException">
        ///     Thrown if a caching error occurs. If you're not interested in handling this exception, catch
        ///     <see cref="BrowsingException" /> instead.
        /// </exception>
        /// <exception cref="Gee.External.Browsing.Clients.BrowsingClientException">
        ///     Thrown if an error communicating with the Google Safe Browsing API occurs. If you're not interested
        ///     in handling this exception, catch <see cref="BrowsingException" /> instead.
        /// </exception>
        /// <exception cref="Gee.External.Browsing.Databases.BrowsingDatabaseException">
        ///     Thrown if a database error occurs. If you're not interested in handling this exception, catch
        ///     <see cref="BrowsingException" /> instead.
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        ///     Thrown if <paramref name="url" /> is a null reference.
        /// </exception>
        /// <exception cref="System.ObjectDisposedException">
        ///     Thrown if <paramref name="cache" /> is disposed, or if <paramref name="client" /> is disposed, or if
        ///     <paramref name="database" /> is disposed.
        /// </exception>
        /// <exception cref="System.OperationCanceledException">
        ///     Thrown if the asynchronous operation is cancelled.
        /// </exception>
        private protected async Task <UrlLookupResult> LookupAsync(IBrowsingCache cache, IBrowsingClient client, IUnmanagedBrowsingDatabase database, Url url, CancellationToken cancellationToken)
        {
            // ...
            //
            // First, lookup the URL in the local database. Throws an exception if the operation fails.
            var             urlLookupDate = DateTime.UtcNow;
            UrlLookupResult urlLookupResult;
            var             databaseLookupTask = database.LookupAsync(url);
            var             databaseLookResult = await databaseLookupTask.ConfigureAwait(false);

            if (databaseLookResult.IsDatabaseMiss)
            {
                // ...
                //
                // If the URL does not exist in the local database, indicate the URL is safe.
                urlLookupResult = UrlLookupResult.Safe(url, urlLookupDate);
            }
            else if (databaseLookResult.IsDatabaseStale)
            {
                // ...
                //
                // If the local database is expired/out-of-date/stale, indicate the nature of the URL cannot
                // be determined as a result.
                urlLookupResult = UrlLookupResult.DatabaseStale(url, urlLookupDate);
            }
            else
            {
                // ...
                //
                // If the URL exists in the local database, look it up in the cache. Throws an exception if
                // the operation fails.
                var sha256Hash        = databaseLookResult.Sha256Hash;
                var sha256HashPrefix  = databaseLookResult.Sha256HashPrefix;
                var cacheLookupTask   = cache.LookupAsync(sha256Hash, sha256HashPrefix, cancellationToken);
                var cacheLookupResult = await cacheLookupTask.ConfigureAwait(false);

                if (cacheLookupResult.IsCacheSafeHit)
                {
                    // ...
                    //
                    // If we get a cache safe hit, indicate the URL is safe.
                    urlLookupResult = UrlLookupResult.Safe(url, urlLookupDate);
                }
                else if (cacheLookupResult.IsCacheUnsafeHit)
                {
                    // ...
                    //
                    // If we get a cache unsafe hit, indicate the URL is unsafe. If we get a cache unsafe hit,
                    // it is guaranteed we find a URL expression for the threat, since it is essentially the
                    // URL expression that is cached.
                    var unsafeThreatListDescriptors = cacheLookupResult.UnsafeThreatListDescriptors;
                    url.TryGetExpressionForSha256Hash(sha256Hash, out var unsafeUrlExpression);
                    urlLookupResult = UrlLookupResult.Unsafe(url, urlLookupDate, unsafeUrlExpression, unsafeThreatListDescriptors);
                }
                else
                {
                    // ...
                    //
                    // If we get a cache miss, verify the URL with the Google Safe Browsing API. Throws an
                    // exception if the operation fails.
                    var threatLists        = databaseLookResult.ThreatLists;
                    var findFullHashesTask = client.FindFullHashesAsync(sha256HashPrefix, threatLists, cancellationToken);
                    var fullHashResponse   = await findFullHashesTask.ConfigureAwait(false);

                    // ...
                    //
                    // Throws an exception if the operation fails.
                    var safeCacheEntryExpirationDate = fullHashResponse.SafeThreatsExpirationDate;
                    var putSafeCacheEntryTask        = cache.PutSafeCacheEntryAsync(sha256HashPrefix, safeCacheEntryExpirationDate, cancellationToken);
                    await putSafeCacheEntryTask.ConfigureAwait(false);

                    var unsafeThreats = fullHashResponse.UnsafeThreats;
                    if (unsafeThreats.Count != 0)
                    {
                        var unsafeThreatGroups = unsafeThreats.GroupBy(ut => ut.Sha256Hash);
                        foreach (var unsafeThreatGroup in unsafeThreatGroups)
                        {
                            // ...
                            //
                            // Throws an exception if the operation fails.
                            var unsafeThreatSha256Hash  = unsafeThreatGroup.Key;
                            var putUnsafeCacheEntryTask = cache.PutUnsafeCacheEntryAsync(unsafeThreatSha256Hash, unsafeThreatGroup, cancellationToken);
                            await putUnsafeCacheEntryTask.ConfigureAwait(false);
                        }
                    }

                    // ...
                    //
                    // Lookup the URL in the cache again. Throws an exception if the operation fails.
                    cacheLookupTask   = cache.LookupAsync(sha256Hash, sha256HashPrefix, cancellationToken);
                    cacheLookupResult = await cacheLookupTask.ConfigureAwait(false);

                    if (cacheLookupResult.IsCacheSafeHit)
                    {
                        // ...
                        //
                        // If we get a cache safe hit, indicate the URL is safe.
                        urlLookupResult = UrlLookupResult.Safe(url, urlLookupDate);
                    }
                    else if (cacheLookupResult.IsCacheUnsafeHit)
                    {
                        // ...
                        //
                        // If we get a cache unsafe hit, indicate the URL is unsafe. If we get a cache unsafe hit,
                        // it is guaranteed we find a URL expression for the threat, since it is essentially the
                        // URL expression that is cached.
                        var unsafeThreatListDescriptors = cacheLookupResult.UnsafeThreatListDescriptors;
                        url.TryGetExpressionForSha256Hash(sha256Hash, out var unsafeUrlExpression);
                        urlLookupResult = UrlLookupResult.Unsafe(url, urlLookupDate, unsafeUrlExpression, unsafeThreatListDescriptors);
                    }
                    else
                    {
                        urlLookupResult = UrlLookupResult.DatabaseStale(url, urlLookupDate);
                    }
                }
            }

            return(urlLookupResult);
        }
 /// <summary>
 ///     Find Full Hashes Asynchronously.
 /// </summary>
 /// <param name="this">
 ///     A <see cref="IBrowsingClient" />.
 /// </param>
 /// <param name="sha256HashPrefix">
 ///     A SHA256 hash prefix, formatted as a hexadecimal encoded string, identifying a threat to query.
 /// </param>
 /// <param name="threatLists">
 ///     A collection of <see cref="ThreatList" /> the threat identified by <paramref name="sha256HashPrefix" />
 ///     is associated with.
 /// </param>
 /// <returns>
 ///     A <see cref="FullHashResponse" />.
 /// </returns>
 /// <exception cref="Gee.External.Browsing.Clients.BrowsingClientException">
 ///     Thrown if an error communicating with the Google Safe Browsing API occurs.
 /// </exception>
 /// <exception cref="System.ArgumentNullException">
 ///     Thrown if <paramref name="this" /> is a null reference, or if <paramref name="sha256HashPrefix" /> is a
 ///     null reference, or if <paramref name="threatLists" /> is a null reference.
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 ///     Thrown if the <paramref name="this" /> is disposed.
 /// </exception>
 /// <exception cref="System.TimeoutException">
 ///     Thrown if communication with the Google Safe Browsing API times out.
 /// </exception>
 public static Task <FullHashResponse> FindFullHashesAsync(this IBrowsingClient @this, string sha256HashPrefix, IEnumerable <ThreatList> threatLists) => @this.FindFullHashesAsync(sha256HashPrefix, threatLists, CancellationToken.None);