Beispiel #1
0
        protected override void ProcessInternal(IFlowData data)
        {
            // Create a new IStarSignData, and cast to StarSignData so the 'setter' is available.
            StarSignData starSignData = (StarSignData)data.GetOrAdd(ElementDataKey, CreateElementData);

            if (data.TryGetEvidence("date-of-birth", out DateTime dateOfBirth))
            {
                // "date-of-birth" is there, so set the star sign.
                var monthAndDay = new DateTime(1, dateOfBirth.Month, dateOfBirth.Day);
                foreach (var starSign in _starSigns)
                {
                    if (monthAndDay > starSign.Start &&
                        monthAndDay < starSign.End)
                    {
                        // The star sign has been found, so set it in the
                        // results.
                        starSignData.StarSign = starSign.Name;
                        break;
                    }
                }
            }
            else
            {
                // "date-of-birth" is not there, so set the star sign to unknown.
                starSignData.StarSign = "Unknown";
            }
        }
        protected override void ProcessEngine(IFlowData data, IStarSignData aspectData)
        {
            // Cast aspectData to AgeData so the 'setter' is available.
            StarSignData starSignData = (StarSignData)aspectData;

            if (data.TryGetEvidence("date-of-birth", out DateTime dateOfBirth))
            {
                // "date-of-birth" is there, so set the star sign.
                var monthAndDay = new DateTime(1, dateOfBirth.Month, dateOfBirth.Day);
                foreach (var starSign in _starSigns)
                {
                    if (monthAndDay > starSign.Start &&
                        monthAndDay < starSign.End)
                    {
                        // The star sign has been found, so set it in the
                        // results.
                        starSignData.StarSign = starSign.Name;
                        break;
                    }
                }
            }
            else
            {
                // "date-of-birth" is not there, so set the star sign to unknown.
                starSignData.StarSign = "Unknown";
            }
        }
Beispiel #3
0
        protected override void ProcessInternal(IFlowData data)
        {
            var monthAndDay = new DateTime(1, 1, 1);

            // Create a new IStarSignData, and cast to StarSignData so the 'setter' is available.
            StarSignData starSignData = (StarSignData)data.GetOrAdd(ElementDataKey, CreateElementData);

            bool validDateOfBirth = false;

            if (data.TryGetEvidence("cookie.date-of-birth", out string dateString))
            {
                // "date-of-birth" is there, so parse it.
                string[] dateSections = dateString.Split('/');
                try
                {
                    monthAndDay = new DateTime(
                        1,
                        int.Parse(dateSections[1]),
                        int.Parse(dateSections[0]));
                    validDateOfBirth = true;
                }
                catch (Exception)
                {
                }
            }
            if (validDateOfBirth)
            {
                // "date-of-birth" is valid, so set the star sign.
                foreach (var starSign in _starSigns)
                {
                    if (monthAndDay > starSign.Start &&
                        monthAndDay < starSign.End)
                    {
                        // The star sign has been found, so set it in the
                        // results.
                        starSignData.StarSign = starSign.Name;
                        break;
                    }
                }
                // No need to run the client side code again.
                starSignData.DobJavaScript = new JavaScript("");
            }
            else
            {
                // "date-of-birth" is not there, so set the star sign to unknown.
                starSignData.StarSign = "Unknown";
                // Set the client side JavaScript to get the date of birth.
                starSignData.DobJavaScript = new JavaScript(
                    "var dob = window.prompt('Enter your date of birth.','dd/mm/yyyy');" +
                    "if (dob != null) {" +
                    "document.cookie='date-of-birth='+dob;" +
                    "location.reload();" +
                    "}");
            }
        }
        /// <summary>
        /// Get the sequence number from the evidence.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the supplied flow data is null.
        /// </exception>
        /// <exception cref="PipelineException">
        /// Thrown if sequence number is not present in the evidence.
        /// </exception>
        protected static int GetSequenceNumber(IFlowData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (data.TryGetEvidence(Engines.FiftyOne.Constants.EVIDENCE_SEQUENCE, out int sequence) == false)
            {
                throw new PipelineException(Messages.ExceptionSequenceNumberNotPresent);
            }
            return(sequence);
        }
Beispiel #5
0
        /// <summary>
        /// Get the session-id evidence if it exists.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected virtual string GetSessionId(IFlowData data)
        {
            if (data == null)
            {
                throw new ArgumentException(Messages.ExceptionFlowDataIsNull);
            }

            string sessionId = string.Empty;

            // Get the session-id evidence if it exists.
            if (data.TryGetEvidence(Engines.FiftyOne.Constants.EVIDENCE_SESSIONID,
                                    out object objSessionId))
            {
                sessionId = objSessionId?.ToString() ?? string.Empty;
            }
            return(sessionId);
        }
Beispiel #6
0
        /// <summary>
        /// Called for this engine to perform its processing.
        /// </summary>
        /// <param name="data">
        /// The <see cref="IFlowData"/> that contains the input and output data.
        /// </param>
        /// <param name="aspectData">
        /// The data instance to use to output results.
        /// </param>
        protected override void ProcessEngine(IFlowData data, IPrimeCheckerData aspectData)
        {
            int value;

            // Try to get the evidence this engine requires.
            if (data.TryGetEvidence(Constants.PRIMECHECKER_EVIDENCE_KEY, out value))
            {
                // Determine if the number is prime and set the output
                // data accordingly.
                aspectData.IsPrime = IsPrime(value);
                // Wait for a short time.
                // This is done to help illustrate the impact of
                // features such as caching and lazy loading.
                Task.Delay(Constants.PRIMECHECKER_ENGINE_DELAY).Wait();
            }
            else
            {
                // If the evidence is not present then throw an exception.
                throw new Exception($"No evidence for key '{Constants.PRIMECHECKER_EVIDENCE_KEY}'");
            }
        }
Beispiel #7
0
        /// <summary>
        /// Get the sequence evidence if it exists.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected virtual int GetSequence(IFlowData data)
        {
            if (data == null)
            {
                throw new ArgumentException(Messages.ExceptionFlowDataIsNull);
            }

            // Get the sequence evidence if it exists.
            int sequence = 1;

            if (data.TryGetEvidence(Engines.FiftyOne.Constants.EVIDENCE_SEQUENCE,
                                    out object sequenceObject))
            {
                if (sequenceObject is int sequenceValue ||
                    (sequenceObject is string seq && int.TryParse(seq, out sequenceValue)))
                {
                    sequence = sequenceValue;
                }
            }
            return(sequence);
        }
Beispiel #8
0
        /// <summary>
        /// Build the JavaScript content and add it to the supplied
        /// <see cref="IFlowData"/> instance.
        /// </summary>
        /// <param name="data">
        /// The <see cref="IFlowData"/> instance to populate with the
        /// resulting <see cref="JavaScriptBuilderElementData"/>
        /// </param>
        /// <param name="jsonObject">
        /// The JSON data object to include in the JavaScript.
        /// </param>
        /// <param name="supportsPromises">
        /// True to build JavaScript that uses promises. False to
        /// build JavaScript that does not use promises.
        /// </param>
        /// <param name="url">
        /// The callback URL for the JavaScript to send a request to
        /// when it has new evidence values to supply.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the supplied flow data is null.
        /// </exception>
        protected void BuildJavaScript(IFlowData data, string jsonObject, bool supportsPromises, Uri url)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            JavaScriptBuilderElementData elementData = (JavaScriptBuilderElementData)
                                                       data.GetOrAdd(
                ElementDataKeyTyped,
                CreateElementData);

            // Try and get the requested object name from evidence.
            if (data.TryGetEvidence(Constants.EVIDENCE_OBJECT_NAME, out string objectName) == false ||
                string.IsNullOrWhiteSpace(objectName))
            {
                objectName = ObjName;
            }

            var ubdateEnabled = url != null &&
                                url.AbsoluteUri.Length > 0;

            JavaScriptResource javaScriptObj = new JavaScriptResource(
                objectName,
                jsonObject,
                supportsPromises,
                url,
                EnableCookies,
                ubdateEnabled);

            string content = _stubble.Render(_template, javaScriptObj.AsDictionary() /*, _renderSettings*/);

            string minifiedContent = content;

            if (_minify)
            {
                // Minimize the script.
                var ugly = Uglify.Js(content);

                if (ugly.HasErrors)
                {
                    // If there were are errors then log them and
                    // return the non-minified response.

                    minifiedContent = content;

                    if (_lastRequestWasError == false)
                    {
                        StringBuilder errorText = new StringBuilder();
                        errorText.AppendLine("Errors occurred when minifying JavaScript.");
                        foreach (var error in ugly.Errors)
                        {
                            errorText.AppendLine($"{error.ErrorCode}: {error.Message}. " +
                                                 $"Line(s) {error.StartLine}-{error.EndLine}. " +
                                                 $"Column(s) {error.StartColumn}-{error.EndColumn}");
                        }
                        errorText.AppendLine(content);
                        Logger.LogError(errorText.ToString());
                        _lastRequestWasError = true;
#pragma warning disable CS0618 // Type or member is obsolete
                        // This usage should be replaced with the
                        // CancellationToken implementation once it
                        // is available.
                        data.Stop = true;
#pragma warning restore CS0618 // Type or member is obsolete
                    }
                }
                else
                {
                    minifiedContent = ugly.Code;
                }
            }

            elementData.JavaScript = minifiedContent;
        }
Beispiel #9
0
        private void SetUp(IFlowData data)
        {
            var  host     = Host;
            var  protocol = Protocol;
            bool supportsPromises;

            if (string.IsNullOrEmpty(host))
            {
                // Try and get the request host name so it can be used to request
                // the Json refresh in the JavaScript code.
                data.TryGetEvidence(Constants.EVIDENCE_HOST_KEY, out host);
            }
            if (string.IsNullOrEmpty(protocol))
            {
                // Try and get the request protocol so it can be used to request
                // the JSON refresh in the JavaScript code.
                data.TryGetEvidence(Constants.EVIDENCE_PROTOCOL, out protocol);
            }
            // Couldn't get protocol from anywhere
            if (string.IsNullOrEmpty(protocol))
            {
                protocol = Constants.DEFAULT_PROTOCOL;
            }

            // If device detection is in the Pipeline then we can check
            // if the client's browser supports promises.
            // This can be used to customize the JavaScript response.
            try
            {
                var promise = data.GetAs <IAspectPropertyValue <string> >("Promise");
                supportsPromises = promise != null && promise.HasValue && promise.Value == "Full";
            }
            catch (PipelineDataException) { supportsPromises = false; }
            catch (InvalidCastException) { supportsPromises = false; }
            catch (KeyNotFoundException) { supportsPromises = false; }

            // Get the JSON include to embed into the JavaScript include.
            string jsonObject = string.Empty;

            try
            {
                jsonObject = data.Get <IJsonBuilderElementData>().Json;
            }
            catch (KeyNotFoundException ex)
            {
                throw new PipelineConfigurationException(
                          Messages.ExceptionJsonBuilderNotRun, ex);
            }

            // Generate any required parameters for the JSON request.
            List <string> parameters = new List <string>();

            // Any query parameters from this request that were ingested by
            // the Pipeline are added to the request URL that will appear
            // in the JavaScript.
            var queryEvidence = data
                                .GetEvidence()
                                .AsDictionary()
                                .Where(e => e.Key.StartsWith(Core.Constants.EVIDENCE_QUERY_PREFIX,
                                                             StringComparison.OrdinalIgnoreCase))
                                .Select(k =>
            {
                var dotPos = k.Key.IndexOf(Core.Constants.EVIDENCE_SEPERATOR,
                                           StringComparison.OrdinalIgnoreCase);
                return($"{WebUtility.UrlEncode(k.Key.Remove(0, dotPos + 1))}" +
                       $"={WebUtility.UrlEncode(k.Value.ToString())}");
            });

            parameters.AddRange(queryEvidence);

            string queryParams = string.Join("&", parameters);
            string endpoint    = Endpoint;

            Uri url = null;

            if (string.IsNullOrWhiteSpace(protocol) == false &&
                string.IsNullOrWhiteSpace(host) == false &&
                string.IsNullOrWhiteSpace(endpoint) == false)
            {
                var endpointHasSlash = endpoint[0] == '/';
                var hostHasSlash     = host[host.Length - 1] == '/';
                // if there is no slash between host and endpoint then add one.
                if (endpointHasSlash == false && hostHasSlash == false)
                {
                    endpoint = $"/{endpoint}";
                }
                // if there are two slashes between host and endpoint then remove one.
                else if (endpointHasSlash == true && hostHasSlash == true)
                {
                    endpoint = endpoint.Substring(1);
                }

                url = new Uri($"{protocol}://{host}{endpoint}" +
                              (String.IsNullOrEmpty(queryParams) ? "" : $"?{queryParams}"));
            }

            // With the gathered resources, build a new JavaScriptResource.
            BuildJavaScript(data, jsonObject, supportsPromises, url);
        }
Beispiel #10
0
 private bool EvidenceContainsUserAgent(IFlowData data)
 {
     return(data.TryGetEvidence("header.user-agent", out object _));
 }
Beispiel #11
0
        /// <summary>
        /// Build the JavaScript content and add it to the supplied
        /// <see cref="IFlowData"/> instance.
        /// </summary>
        /// <param name="data">
        /// The <see cref="IFlowData"/> instance to populate with the
        /// resulting <see cref="JavaScriptBuilderElementData"/>
        /// </param>
        /// <param name="jsonObject">
        /// The JSON data object to include in the JavaScript.
        /// </param>
        /// <param name="sessionId">
        /// The session Id to use in the JavaScript response.
        /// </param>
        /// <param name="sequence">
        /// The sequence value to use in the JavaScript response.
        /// </param>
        /// <param name="supportsPromises">
        /// True to build JavaScript that uses promises. False to
        /// build JavaScript that does not use promises.
        /// </param>
        /// <param name="supportsFetch">
        /// True to build JavaScript that makes use of the
        /// fetch API. Otherwise, the template will fall back to using
        /// XMLHttpRequest.
        /// </param>
        /// <param name="url">
        /// The callback URL for the JavaScript to send a request to
        /// when it has new evidence values to supply.
        /// </param>
        /// <param name="parameters">The parameters to append to the URL</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the supplied flow data is null.
        /// </exception>
        protected void BuildJavaScript(
            IFlowData data,
            string jsonObject,
            string sessionId,
            int sequence,
            bool supportsPromises,
            bool supportsFetch,
            Uri url,
            string parameters)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            JavaScriptBuilderElementData elementData = (JavaScriptBuilderElementData)
                                                       data.GetOrAdd(
                ElementDataKeyTyped,
                CreateElementData);

            string objectName = ObjName;

            // Try and get the requested object name from evidence.
            if (data.TryGetEvidence(Constants.EVIDENCE_OBJECT_NAME,
                                    out object objObjectName))
            {
                objectName = objObjectName?.ToString() ?? ObjName;
            }

            var ubdateEnabled = url != null &&
                                url.AbsoluteUri.Length > 0;

            // This check won't be 100% fool-proof but it only needs to be
            // reasonably accurate and not take too long.
            var hasDelayedProperties = jsonObject != null &&
                                       jsonObject.Contains("delayexecution");

            JavaScriptResource javaScriptObj = new JavaScriptResource(
                objectName,
                jsonObject,
                sessionId,
                sequence,
                supportsPromises,
                supportsFetch,
                url,
                parameters,
                EnableCookies,
                ubdateEnabled,
                hasDelayedProperties);

            string content = _stubble.Render(_template, javaScriptObj.AsDictionary());

            string minifiedContent = content;

            if (_minify)
            {
                // Minimize the script.
                var ugly = Uglify.Js(content);

                if (ugly.HasErrors)
                {
                    // If there were are errors then log them and
                    // return the non-minified response.

                    minifiedContent = content;

                    if (_lastRequestWasError == false)
                    {
                        StringBuilder errorText = new StringBuilder();
                        errorText.AppendLine("Errors occurred when minifying JavaScript.");
                        foreach (var error in ugly.Errors)
                        {
                            errorText.AppendLine($"{error.ErrorCode}: {error.Message}. " +
                                                 $"Line(s) {error.StartLine}-{error.EndLine}. " +
                                                 $"Column(s) {error.StartColumn}-{error.EndColumn}");
                        }
                        errorText.AppendLine(content);
                        Logger.LogError(errorText.ToString());
                        _lastRequestWasError = true;
#pragma warning disable CS0618 // Type or member is obsolete
                        // This usage should be replaced with the
                        // CancellationToken implementation once it
                        // is available.
                        data.Stop = true;
#pragma warning restore CS0618 // Type or member is obsolete
                    }
                }
                else
                {
                    minifiedContent = ugly.Code;
                }
            }

            elementData.JavaScript = minifiedContent;
        }
Beispiel #12
0
        private void SetUp(IFlowData data)
        {
            var  host             = Host;
            var  protocol         = Protocol;
            bool supportsPromises = false;
            bool supportsFetch    = false;

            if (string.IsNullOrEmpty(host) &&
                // Try and get the request host name so it can be used to request
                // the Json refresh in the JavaScript code.
                data.TryGetEvidence(Constants.EVIDENCE_HOST_KEY, out object hostObj))
            {
                host = hostObj?.ToString() ?? String.Empty;
            }
            if (string.IsNullOrEmpty(protocol) &&
                // Try and get the request protocol so it can be used to request
                // the JSON refresh in the JavaScript code.
                data.TryGetEvidence(Core.Constants.EVIDENCE_PROTOCOL, out object protocolObj))
            {
                protocol = protocolObj?.ToString() ?? String.Empty;
            }
            // Couldn't get protocol from anywhere
            if (string.IsNullOrEmpty(protocol))
            {
                protocol = Constants.DEFAULT_PROTOCOL;
            }

            // If device detection is in the Pipeline then we can check
            // if the client's browser supports promises.
            // This can be used to customize the JavaScript response.
            if (_promisePropertyAvailable)
            {
                // Execute this action if one of our expected
                // exceptions occurs.
                Action promisesNotAvailable = () => {
                    // Short-circuit future calls, so we don't keep checking
                    // for this property.
                    _promisePropertyAvailable = false;
                    supportsPromises          = false;
                };

                try
                {
                    var promise = data.GetAs <IAspectPropertyValue <string> >("Promise");
                    supportsPromises = promise != null && promise.HasValue && promise.Value == "Full";
                }
                catch (PropertyMissingException) { promisesNotAvailable(); }
                catch (PipelineDataException) { promisesNotAvailable(); }
                catch (InvalidCastException) { promisesNotAvailable(); }
                catch (KeyNotFoundException) { promisesNotAvailable(); }
            }

            // If device detection is in the Pipeline then we can check
            // if the client's browser supports fetch.
            // This can be used to customize the JavaScript response.
            if (_fetchPropertyAvailable)
            {
                // Execute this action if one of our expected
                // exceptions occurs.
                Action fetchNotAvailable = () => {
                    // Short-circuit future calls, so we don't keep checking
                    // for this property.
                    _fetchPropertyAvailable = false;
                    supportsFetch           = false;
                };

                try
                {
                    var fetch = data.GetAs <IAspectPropertyValue <bool> >("Fetch");
                    supportsFetch = fetch != null && fetch.HasValue && fetch.Value;
                }
                catch (PropertyMissingException) { fetchNotAvailable(); }
                catch (PipelineDataException) { fetchNotAvailable(); }
                catch (InvalidCastException) { fetchNotAvailable(); }
                catch (KeyNotFoundException) { fetchNotAvailable(); }
            }

            // Get the JSON include to embed into the JavaScript include.
            string jsonObject = string.Empty;

            try
            {
                jsonObject = data.Get <IJsonBuilderElementData>().Json;
            }
            catch (KeyNotFoundException ex)
            {
                throw new PipelineConfigurationException(
                          Messages.ExceptionJsonBuilderNotRun, ex);
            }

            var parameters   = GetParameters(data);
            var paramsObject = JsonConvert.SerializeObject(parameters);
            var sessionId    = GetSessionId(data);
            var sequence     = GetSequence(data);

            string endpoint = Endpoint;
            Uri    url      = null;

            // Check the call-back URL is formatted correctly.
            if (string.IsNullOrWhiteSpace(protocol) == false &&
                string.IsNullOrWhiteSpace(host) == false &&
                string.IsNullOrWhiteSpace(endpoint) == false)
            {
                var endpointHasSlash = endpoint[0] == '/';
                var hostHasSlash     = host[host.Length - 1] == '/';
                // if there is no slash between host and endpoint then add one.
                if (endpointHasSlash == false && hostHasSlash == false)
                {
                    endpoint = $"/{endpoint}";
                }
                // if there are two slashes between host and endpoint then remove one.
                else if (endpointHasSlash == true && hostHasSlash == true)
                {
                    endpoint = endpoint.Substring(1);
                }

                url = new Uri($"{protocol}://{host}{endpoint}");
            }

            // With the gathered resources, build a new JavaScriptResource.
            BuildJavaScript(data, jsonObject, sessionId, sequence, supportsPromises, supportsFetch, url, paramsObject);
        }