public override Task ExecuteAsync(string receiver, WebHookHandlerContext context) { SalesforceNotifications updates = context.GetDataOrDefault <SalesforceNotifications>(); string sessionId = updates.SessionId; string company = updates.Notifications.FirstOrDefault()?["Company"]; return(Task.FromResult(true)); }
public IActionResult Salesforce(string id, string @event, SalesforceNotifications data) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } _logger.LogInformation( 0, "{ControllerName} / '{ReceiverId}' received {Count} notifications with ActionId '{ActionId}' (event " + "'{EventName}').", nameof(SalesforceController), id, data.Notifications.Count(), data.ActionId, @event); _logger.LogInformation( 1, "Data contains OrganizationId '{OrganizationId}' and SessionId '{SessionId}'.", data.OrganizationId, data.SessionId); _logger.LogInformation( 2, "Contained URLs include EnterpriseUrl '{EnterpriseUrl}' and PartnerUrl '{PartnerUrl}'.", data.EnterpriseUrl, data.PartnerUrl); var index = 0; foreach (var notification in data.Notifications) { _logger.LogInformation( 3, "Notification #{Number} contained {Count} values.", index, notification.Count); index++; } return(Ok()); }
public async Task <IActionResult> Salesforce(string id, string @event, SalesforceNotifications data) { if (!ModelState.IsValid) { return(await _resultCreator.GetFailedResultAsync("Model binding failed.")); } _logger.LogInformation( 0, $"{nameof(SalesforceController)} / '{{ReceiverId}}' received {{Count}} notifications with ActionId " + "'{ActionId}' (event '{EventName}').", id, data.Notifications.Count(), data.ActionId, @event); _logger.LogInformation( 1, "Data contains OrganizationId '{OrganizationId}' and SessionId '{SessionId}'.", data.OrganizationId, data.SessionId); _logger.LogInformation( 2, "Contained URLs include EnterpriseUrl '{EnterpriseUrl}' and PartnerUrl '{PartnerUrl}'.", data.EnterpriseUrl, data.PartnerUrl); var index = 0; foreach (var notification in data.Notifications) { _logger.LogInformation( 3, "Notification #{Number} contained {Count} values.", index, notification.Count); index++; } return(await _resultCreator.GetSuccessResultAsync()); }
/// <inheritdoc /> public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (next == null) { throw new ArgumentNullException(nameof(next)); } var routeData = context.RouteData; if (!routeData.TryGetReceiverName(out var receiverName) || !IsApplicable(receiverName)) { await next(); return; } // 1. Confirm we were reached using HTTPS. var request = context.HttpContext.Request; var errorResult = EnsureSecureConnection(receiverName, request); if (errorResult != null) { context.Result = errorResult; return; } // 2. Get XElement and SalesforceNotifications from the request body. var data = await ReadAsXmlAsync(context); if (data == null) { var modelState = context.ModelState; if (modelState.IsValid) { // ReadAsXmlAsync returns null when model state is valid only when other filters will log and // return errors about the same conditions. Let those filters run. await next(); } else { context.Result = WebHookResultUtilities.CreateErrorResult(modelState); } return; } // Got a valid XML body. From this point on, all responses should contain XML. var notifications = new SalesforceNotifications(data); // 3. Ensure that the organization ID exists and matches the expected value. var organizationId = GetShortOrganizationId(notifications.OrganizationId); if (string.IsNullOrEmpty(organizationId)) { Logger.LogError( 0, "The HTTP request body did not contain a required '{PropertyName}' property.", nameof(notifications.OrganizationId)); var message = string.Format( CultureInfo.CurrentCulture, Resources.VerifyOrganization_MissingValue, nameof(notifications.OrganizationId)); context.Result = await _resultCreator.GetFailedResultAsync(message); return; } var secret = await GetReceiverConfig( request, routeData, SalesforceConstants.ConfigurationName, SalesforceConstants.SecretKeyMinLength, SalesforceConstants.SecretKeyMaxLength); var secretKey = GetShortOrganizationId(secret); if (!SecretEqual(organizationId, secretKey)) { Logger.LogError( 1, "The '{PropertyName}' value provided in the HTTP request body did not match the expected value.", nameof(notifications.OrganizationId)); var message = string.Format( CultureInfo.CurrentCulture, Resources.VerifyOrganization_BadValue, nameof(notifications.OrganizationId)); context.Result = await _resultCreator.GetFailedResultAsync(message); return; } // 4. Get the event name. var eventName = notifications.ActionId; if (string.IsNullOrEmpty(eventName)) { Logger.LogError( 2, "The HTTP request body did not contain a required '{PropertyName}' property.", nameof(notifications.ActionId)); var message = string.Format( CultureInfo.CurrentCulture, Resources.VerifyOrganization_MissingValue, nameof(notifications.ActionId)); context.Result = await _resultCreator.GetFailedResultAsync(message); return; } // 5. Success. Provide request data and event name for model binding. routeData.Values[WebHookConstants.EventKeyName] = eventName; context.HttpContext.Items[typeof(XElement)] = data; context.HttpContext.Items[typeof(SalesforceNotifications)] = notifications; await next(); }