protected override string ToJson(object value) { Guard.ArgumentNotNull(value, nameof(value)); return(UmbrellaStatics.SerializeJson(value)); }
public void ContingentMerge(IOwinContext owinContext, string currentSiteName, bool reset, Func <CookieOptions> cookieOptionsBuilder) { owinContext.Request.CallCancelled.ThrowIfCancellationRequested(); Guard.ArgumentNotNull(owinContext, nameof(owinContext)); Guard.ArgumentNotNullOrWhiteSpace(currentSiteName, nameof(currentSiteName)); Guard.ArgumentNotNull(cookieOptionsBuilder, nameof(cookieOptionsBuilder)); try { string currentCookieValue = null; List <string> lstCurrentlyMergedSites = null; if (!reset) { currentCookieValue = owinContext.Request.Cookies[_options.CrossSiteTrackingCookieName]; if (!string.IsNullOrWhiteSpace(currentCookieValue)) { try { lstCurrentlyMergedSites = UmbrellaStatics.DeserializeJson <List <string> >(currentCookieValue); } catch (Exception exc) when(_log.WriteWarning(exc, new { currentCookieValue }, $"The cookie value of the {_options.CrossSiteTrackingCookieName} could not be deserialized to a List<string> instance.", returnValue: true)) { // If the cookie couldn't be deserialized it has probably been tampered with. } } } if (lstCurrentlyMergedSites == null) { lstCurrentlyMergedSites = new List <string>(); } // At this point we should have either a new list to work with if we are resetting the cookie value // or an existing list from the cookie when not resetting. Either way, the next steps are the same. string currentSiteNameCleaned = currentSiteName.TrimToLowerInvariant(); // Even though the cookie may have already been processed, we need to force processing in the event that there isn't a CurrentContact cookie // because it has been deleted manually or its value is invalid. if (!lstCurrentlyMergedSites.Contains(currentSiteNameCleaned) || !CurrentContactExists(owinContext)) { // We haven't merged the contact for this site yet. Merge(owinContext.Request.User.Identity.Name); lstCurrentlyMergedSites.Add(currentSiteNameCleaned); // Update the cookie value on the outgoing response so that on the next request the merge doesn't happen again. // Cleanup the values in case they have been tampered with or mangled somehow. lstCurrentlyMergedSites = lstCurrentlyMergedSites.Select(x => x.TrimToLowerInvariant()).Distinct().ToList(); string updatedCookieValue = UmbrellaStatics.SerializeJson(lstCurrentlyMergedSites); // We only need to update the cookie if its value has actually changed if (!string.Equals(currentCookieValue, updatedCookieValue, StringComparison.OrdinalIgnoreCase)) { owinContext.Response.Cookies.Append(_options.CrossSiteTrackingCookieName, updatedCookieValue, cookieOptionsBuilder()); } } } catch (Exception exc) when(_log.WriteError(exc, new { owinContext.Request.User.Identity.Name, reset }, returnValue: true)) { throw new KenticoContactException("There has been a problem merging the contact data for the specified user for the specified OwinContext.", exc); } }