Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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());
        }
Ejemplo n.º 3
0
        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();
        }