예제 #1
0
 private static bool DefaultPredicate(WebHook webHook, string user)
 {
     return(true);
 }
예제 #2
0
 /// <inheritdoc />
 public abstract Task <StoreResult> InsertWebHookAsync(string user, WebHook webHook);
 /// <inheritdoc />
 public abstract Task <StoreResult> UpdateWebHookAsync(string user, WebHook webHook);
 /// <summary>
 /// Checks that the given <paramref name="webHook"/> is not paused and matches at least
 /// one of the given <paramref name="actions"/>.
 /// </summary>
 /// <param name="webHook">The <see cref="WebHook"/> instance to operate on.</param>
 /// <param name="actions">The set of actions to match against the <paramref name="webHook"/> filters.</param>
 /// <returns><c>true</c> if the given <paramref name="webHook"/> matches one of the pro</returns>
 protected virtual bool MatchesAnyAction(WebHook webHook, IEnumerable <string> actions)
 {
     return(webHook != null && !webHook.IsPaused && webHook.MatchesAnyAction(actions));
 }
예제 #5
0
 public WebHookPolicyItem GetPolicyFor(WebHook webhook) => _policies.GetOrAdd(webhook.Id, (arg) => new WebHookPolicyItem(arg));
예제 #6
0
 public void RemovePolicyFor(WebHook webhook) => _policies.TryRemove(webhook.Id, out _);
예제 #7
0
        /// <summary>
        /// Verifies the WebHook by submitting a GET request with a query token intended by the echoed back.
        /// </summary>
        /// <param name="webHook">The <see cref="WebHook"/> to verify.</param>
        protected virtual async Task VerifyEchoAsync(WebHook webHook)
        {
            // Create the echo query parameter that we want returned in response body as plain text.
            var echo = Guid.NewGuid().ToString("N");

            HttpResponseMessage response;

            try
            {
                // If WebHook URI contains a "NoEcho" query parameter then we don't verify the URI using a GET request
                var parameters = webHook.WebHookUri.ParseQueryString();
                if (parameters.TryGetValue(NoEchoParameter, out string value))
                {
                    var message = string.Format(CultureInfo.CurrentCulture, CustomResources.Manager_NoEcho);
                    _logger.LogInformation(message);
                    return;
                }

                // Get request URI with echo query parameter
                var webHookUri = new UriBuilder(webHook.WebHookUri)
                {
                    Query = EchoParameter + "=" + echo + "&code=" + webHook.Secret
                };

                // Create request adding any additional request headers (not entity headers) from Web Hook
                var hookRequest = new HttpRequestMessage(HttpMethod.Get, webHookUri.Uri);
                foreach (var kvp in webHook.Headers)
                {
                    hookRequest.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value);
                }

                response = await _httpClient.SendAsync(hookRequest);
            }
            catch (Exception ex)
            {
                var message = string.Format(CultureInfo.CurrentCulture, CustomResources.Manager_VerifyFailure, ex.Message);
                _logger.LogInformation(message, ex);
                throw new InvalidOperationException(message);
            }

            if (!response.IsSuccessStatusCode)
            {
                var message = string.Format(CultureInfo.CurrentCulture, CustomResources.Manager_VerifyFailure, response.StatusCode);
                _logger.LogInformation(message);
                throw new InvalidOperationException(message);
            }

            // Verify response body
            if (response.Content == null)
            {
                var message = CustomResources.Manager_VerifyNoBody;
                _logger.LogInformation(message);
                throw new InvalidOperationException(message);
            }

            var actualEcho = await response.Content.ReadAsStringAsync();

            if (!string.Equals(actualEcho, echo, StringComparison.Ordinal))
            {
                var message = CustomResources.Manager_VerifyBadEcho;
                _logger.LogInformation(message);
                throw new InvalidOperationException(message);
            }
        }
예제 #8
0
        /// <inheritdoc />
        public async Task VerifyWebHookAsync(WebHook webHook)
        {
            if (webHook == null)
            {
                throw new ArgumentNullException("webHook");
            }

            // Check that we have a valid secret
            if (string.IsNullOrEmpty(webHook.Secret) || webHook.Secret.Length < 32 || webHook.Secret.Length > 64)
            {
                throw new InvalidOperationException(CustomResource.WebHook_InvalidSecret);
            }

            // Check that WebHook URI is either 'http' or 'https'
            if ((webHook.WebHookUri == null || !webHook.WebHookUri.IsAbsoluteUri) ||
                !(webHook.WebHookUri.Scheme.Equals("http", StringComparison.CurrentCultureIgnoreCase) || webHook.WebHookUri.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase)))
            {
                string msg = string.Format(CustomResource.Manager_NoHttpUri, webHook.WebHookUri);
                _logger.LogError(msg);
                throw new InvalidOperationException(msg);
            }

            // Create the echo query parameter that we want returned in response body as plain text.
            string echo = Guid.NewGuid().ToString("N");

            HttpResponseMessage response;

            try
            {
                // Get request URI with echo query parameter
                UriBuilder webHookUri = new UriBuilder(webHook.WebHookUri);
                webHookUri.Query = EchoParameter + "=" + echo;

                // Create request adding any additional request headers (not entity headers) from Web Hook
                HttpRequestMessage hookRequest = new HttpRequestMessage(HttpMethod.Get, webHookUri.Uri);
                foreach (var kvp in webHook.Headers)
                {
                    hookRequest.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value);
                }

                response = await _httpClient.SendAsync(hookRequest);
            }
            catch (Exception ex)
            {
                string msg = string.Format(CustomResource.Manager_VerifyFailure, ex.Message);
                _logger.LogError(msg, ex);
                throw new InvalidOperationException(msg);
            }

            if (!response.IsSuccessStatusCode)
            {
                string msg = string.Format(CustomResource.Manager_VerifyFailure, response.StatusCode);
                _logger.LogInformation(msg);
                throw new InvalidOperationException(msg);
            }

            // Verify response body
            if (response.Content == null)
            {
                string msg = CustomResource.Manager_VerifyNoBody;
                _logger.LogError(msg);
                throw new InvalidOperationException(msg);
            }

            string actualEcho = await response.Content.ReadAsStringAsync();

            if (!string.Equals(actualEcho, echo, StringComparison.Ordinal))
            {
                string msg = CustomResource.Manager_VerifyBadEcho;
                _logger.LogError(msg);
                throw new InvalidOperationException(msg);
            }
        }
예제 #9
0
 /// <inheritdoc />
 public abstract Task RegisterAsync(HttpRequest request, WebHook webHook);
예제 #10
0
        private DynamicTableEntity ConvertFromWebHook(string partitionKey, string rowKey, WebHook webHook)
        {
            DynamicTableEntity entity = new DynamicTableEntity(partitionKey, rowKey);

            entity.ETag = "*";

            // Set data column with encrypted serialization of WebHook
            string         content          = JsonConvert.SerializeObject(webHook, _serializerSettings);
            string         encryptedContent = _protector.Protect(content);
            EntityProperty property         = EntityProperty.GeneratePropertyForString(encryptedContent);

            entity.Properties.Add(WebHookDataColumn, property);

            return(entity);
        }
예제 #11
0
 /// <summary>
 /// Determines whether any of the given <paramref name="actions"/> match the filters for a given <see cref="WebHook"/>.
 /// The actions can either match a filter directly or match a wildcard.
 /// </summary>
 /// <param name="webHook">The <see cref="WebHook"/> instance to operate on.</param>
 /// <param name="actions">The set of actions to match against the <paramref name="webHook"/> filters.</param>
 /// <returns><c>true</c> if one or more of the <paramref name="actions"/> match, otherwise <c>false</c>.</returns>
 public static bool MatchesAnyAction(this WebHook webHook, IEnumerable <string> actions)
 {
     return(webHook != null && actions != null &&
            (webHook.Filters.Contains(WildcardWebHookFilterProvider.Name) ||
             actions.FirstOrDefault(f => webHook.Filters.Contains(f)) != null));
 }
예제 #12
0
 /// <summary>
 /// Determines whether a given <paramref name="action"/> matches the filters for a given <see cref="WebHook"/>.
 /// The action can either match a filter directly or match a wildcard.
 /// </summary>
 /// <param name="webHook">The <see cref="WebHook"/> instance to operate on.</param>
 /// <param name="action">The action to match against the <paramref name="webHook"/> filters.</param>
 /// <returns><c>true</c> if the <paramref name="action"/> matches, otherwise <c>false</c>.</returns>
 public static bool MatchesAction(this WebHook webHook, string action)
 {
     return(webHook != null && (webHook.Filters.Contains(WildcardWebHookFilterProvider.Name) || webHook.Filters.Contains(action)));
 }
        /// <summary>
        /// Verifies the WebHook by submitting a GET request with a query token intended by the echoed back.
        /// </summary>
        /// <param name="webHook">The <see cref="WebHook"/> to verify.</param>
        protected virtual async Task VerifyEchoAsync(WebHook webHook)
        {
            // Create the echo query parameter that we want returned in response body as plain text.
            var echo = Guid.NewGuid().ToString("N");

            HttpResponseMessage response;

            try
            {
                // If WebHook URI contains a "NoEcho" query parameter then we don't verify the URI using a GET request
                var parameters = QueryHelpers.ParseQuery(webHook.WebHookUri.Query);
                if (parameters.ContainsKey(NoEchoParameter))
                {
                    var message = "The WebHook registrar requested no verification of WebHook URI.";
                    _logger.LogInformation(message);
                    return;
                }

                // Get request URI with echo query parameter
                var webHookUri = new UriBuilder(webHook.WebHookUri)
                {
                    Query = EchoParameter + "=" + echo
                };

                // Create request adding any additional request headers (not entity headers) from Web Hook
                var hookRequest = new HttpRequestMessage(HttpMethod.Get, webHookUri.Uri);
                foreach (var kvp in webHook.Headers)
                {
                    hookRequest.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value);
                }

                response = await _httpClient.SendAsync(hookRequest);
            }
            catch (Exception ex)
            {
                var message = string.Format($"WebHook verification failed. Please ensure that the WebHook URI is valid and that the endpoint is accessible. Error encountered: {ex.Message}");
                _logger.LogError(message, ex);
                throw new InvalidOperationException(message);
            }

            if (!response.IsSuccessStatusCode)
            {
                var message = $"WebHook verification failed. Please ensure that the WebHook URI is valid and that the endpoint is accessible. Error encountered: {response.StatusCode}";
                _logger.LogInformation(message);
                throw new InvalidOperationException(message);
            }

            // Verify response body
            if (response.Content == null)
            {
                var message = "The WebHook URI did not return the expected echo query parameter value in a plain text response body. This is necessary to ensure that the WebHook is connected correctly.";
                _logger.LogError(message);
                throw new InvalidOperationException(message);
            }

            var actualEcho = await response.Content.ReadAsStringAsync();

            if (!string.Equals(actualEcho, echo, StringComparison.Ordinal))
            {
                var message = "The HTTP request echo query parameter was not returned as plain text in the response. Please return the echo parameter to verify that the WebHook is working as expected.";
                _logger.LogError(message);
                throw new InvalidOperationException(message);
            }
        }