예제 #1
0
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context,
                                                   ResourceExecutionDelegate next)
        {
            Site site = null;
            await context.HttpContext.Session.LoadAsync();

            // if we've already fetched it on this request it's present in Items
            int?siteId = null;

            if (context.HttpContext.User.Identity.IsAuthenticated)
            {
                // if the user is authenticated, that is their site
                try
                {
                    siteId = _userContextProvider.GetId(context.HttpContext.User,
                                                        ClaimType.SiteId);
                }
                catch (Exception ex)
                {
                    _logger.LogError("Unable to get SiteId claim for user {Name}: {Message}",
                                     context.HttpContext.User.Identity.Name,
                                     ex.Message);
                }
            }

            if (siteId == null)
            {
                string sitePath = context.RouteData.Values["sitePath"]?.ToString();
                // first check, did they use a sitePath giving them a specific site
                if (!string.IsNullOrEmpty(sitePath))
                {
                    site = await _siteLookupService.GetSiteByPathAsync(sitePath);

                    if (site != null)
                    {
                        siteId = site.Id;
                    }
                }
                // if not check if they already have one in their session
                if (siteId == null)
                {
                    siteId = context.HttpContext.Session.GetInt32(SessionKey.SiteId);
                }
                // if not then resort to the default
                if (siteId == null)
                {
                    siteId = await _siteLookupService.GetDefaultSiteIdAsync();
                }
            }
            if (site == null)
            {
                site = await _siteLookupService.GetByIdAsync((int)siteId);
            }

            var siteStage = _siteLookupService.GetSiteStage(site);

            // we might need to hide challenges and/or events based on system settings
            // the setting is to hide so the logic is == null rather than != null
            bool showChallenges = true;
            bool showEvents     = true;

            if (siteStage == SiteStage.RegistrationOpen ||
                siteStage == SiteStage.BeforeRegistration)
            {
                showEvents = site.Settings
                             .FirstOrDefault(_ => _.Key == SiteSettingKey
                                             .Events
                                             .HideUntilProgramOpen)?
                             .Value == null;
            }

            if (siteStage == SiteStage.BeforeRegistration)
            {
                showChallenges = site.Settings
                                 .FirstOrDefault(_ => _.Key == SiteSettingKey
                                                 .Challenges
                                                 .HideUntilRegistrationOpen)?
                                 .Value == null;

                if (!showEvents)
                {
                    // they might be hidden above
                    showEvents = site.Settings
                                 .FirstOrDefault(_ => _.Key == SiteSettingKey
                                                 .Events
                                                 .HideUntilRegistrationOpen)?
                                 .Value == null;
                }
            }

            context.HttpContext.Items[ItemKey.GoogleAnalytics] = site.GoogleAnalyticsTrackingId;
            context.HttpContext.Items[ItemKey.RouteId]         = context.RouteData.Values["id"];
            context.HttpContext.Items[ItemKey.SiteName]        = site?.Name
                                                                 ?? _config[ConfigurationKey.DefaultSiteName];
            context.HttpContext.Items[ItemKey.SiteStage] = siteStage;
            context.HttpContext.Session.SetInt32(SessionKey.SiteId, (int)siteId);
            context.HttpContext.Items[ItemKey.SiteId]         = (int)siteId;
            context.HttpContext.Items[ItemKey.ShowChallenges] = showChallenges;
            context.HttpContext.Items[ItemKey.ShowEvents]     = showEvents;
            context.HttpContext.Items[ItemKey.WebScheme]      = site.IsHttpsForced ? "https" : "http";

            // only check if the site.css and site.js have changed periodically by default and
            // cache the last modification time
            string siteCssCacheKey = $"s{siteId}.{CacheKey.SiteCss}";
            string siteJsCacheKey  = $"s{siteId}.{CacheKey.SiteJs}";

            var cssLastModified = await _cache.GetStringAsync(siteCssCacheKey);

            var jsLastModified = await _cache.GetStringAsync(siteJsCacheKey);

            // compute the appropriate cache time in minutes, default to 60 if not provided
            int cacheMinutes = 60;

            var cacheSiteCustomizationsMinutes = site.Settings
                                                 .FirstOrDefault(_ => _.Key == SiteSettingKey.Web.CacheSiteCustomizationsMinutes)?
                                                 .Value;

            if (cacheSiteCustomizationsMinutes != null &&
                !int.TryParse(cacheSiteCustomizationsMinutes, out cacheMinutes))
            {
                _logger.LogError("Could not convert cache site customizations value to a number: {cacheSiteCustomizationsMinutes}", cacheSiteCustomizationsMinutes);
            }

            // kill any cached values if the cache value was set to 0
            if (cacheMinutes == 0)
            {
                if (!string.IsNullOrEmpty(cssLastModified))
                {
                    await _cache.RemoveAsync(siteCssCacheKey);
                }
                if (!string.IsNullOrEmpty(jsLastModified))
                {
                    await _cache.RemoveAsync(siteJsCacheKey);
                }
            }

            // check for a cache miss and compute the appropriate last modification date
            if (string.IsNullOrEmpty(cssLastModified) ||
                string.IsNullOrEmpty(jsLastModified))
            {
                // file path to the site.css file
                string file = _pathResolver.ResolveContentFilePath(
                    Path.Combine($"site{siteId}", "styles", "site.css"));

                cssLastModified
                    = await UpdateCacheAsync(file, cacheMinutes, cssLastModified, siteCssCacheKey);

                // file path to the site.js file
                file = _pathResolver.ResolveContentFilePath(
                    Path.Combine($"site{siteId}", "scripts", "site.js"));

                jsLastModified
                    = await UpdateCacheAsync(file, cacheMinutes, jsLastModified, siteJsCacheKey);
            }

            // if we have values then set appropriate HttpContext.Items
            if (!string.IsNullOrEmpty(cssLastModified) ||
                !string.IsNullOrEmpty(jsLastModified))
            {
                string contentPath = _config[ConfigurationKey.ContentPath].StartsWith("/")
                    ? _config[ConfigurationKey.ContentPath]
                    : $"/{_config[ConfigurationKey.ContentPath]}";

                if (!string.IsNullOrEmpty(cssLastModified))
                {
                    context.HttpContext.Items[ItemKey.SiteCss]
                        = $"{contentPath}/site{siteId}/styles/site.css?v={cssLastModified}";
                }
                if (!string.IsNullOrEmpty(jsLastModified))
                {
                    context.HttpContext.Items[ItemKey.SiteJs]
                        = $"{contentPath}/site{siteId}/scripts/site.js?v={jsLastModified}";
                }
            }

            context.HttpContext.Items[ItemKey.HouseholdTitle]
                = string.IsNullOrEmpty(context
                                       .HttpContext
                                       .Session
                                       .GetString(SessionKey.CallItGroup))
                ? Annotations.Interface.Family
                : Annotations.Interface.Group;

            if (!string.IsNullOrWhiteSpace(site.ExternalEventListUrl))
            {
                context.HttpContext.Items[ItemKey.ExternalEventListUrl]
                    = site.ExternalEventListUrl;
            }

            var currentCulture = _userContextProvider.GetCurrentCulture();

            context.HttpContext.Items[ItemKey.ISOLanguageName]
                = currentCulture.TwoLetterISOLanguageName;

            int?activeUserId = _userContextProvider.GetContext().ActiveUserId;

            if (_l10nOptions.Value?.SupportedCultures.Count > 1)
            {
                var cookieCulture = context
                                    .HttpContext
                                    .Request
                                    .Cookies[CookieRequestCultureProvider.DefaultCookieName];

                if (currentCulture.Name == Culture.DefaultName)
                {
                    if (cookieCulture != null)
                    {
                        context
                        .HttpContext
                        .Response
                        .Cookies
                        .Delete(CookieRequestCultureProvider.DefaultCookieName);
                        if (activeUserId != null)
                        {
                            await _userService.UpdateCulture(null);
                        }
                    }
                }
                else
                {
                    // no cookie or new culture selected, reset cookie
                    context.HttpContext.Response.Cookies.Append(
                        CookieRequestCultureProvider.DefaultCookieName,
                        CookieRequestCultureProvider
                        .MakeCookieValue(new RequestCulture(currentCulture.Name)),
                        new CookieOptions {
                        Expires = DateTimeOffset.UtcNow.AddDays(14)
                    }
                        );
                    if (activeUserId != null)
                    {
                        await _userService.UpdateCulture(currentCulture.Name);
                    }
                }

                // generate list for drop-down
                var cultureList     = new List <SelectListItem>();
                var cultureHrefLang = new Dictionary <string, string>
                {
                    { "x-default", Culture.DefaultName }
                };
                foreach (var culture in _l10nOptions.Value.SupportedCultures)
                {
                    var text = culture.Parent != null
                        ? culture.Parent.NativeName
                        : culture.NativeName;
                    cultureList.Add(new SelectListItem(text, culture.Name));
                    if (!cultureHrefLang.Keys.Contains(culture.Name))
                    {
                        cultureHrefLang.Add(culture.Name, culture.Name);
                        if (culture.Parent != null &&
                            !cultureHrefLang.Keys.Contains(culture.Parent.Name))
                        {
                            cultureHrefLang.Add(culture.Parent.Name, culture.Parent.Name);
                        }
                    }
                }
                context.HttpContext.Items[ItemKey.HrefLang] = cultureHrefLang;
                context.HttpContext.Items[ItemKey.L10n]     = cultureList.OrderBy(_ => _.Text);
            }

            using (LogContext.PushProperty(LoggingEnrichment.ActiveUserId, activeUserId))
                using (LogContext.PushProperty(LoggingEnrichment.LanguageId,
                                               currentCulture?.TwoLetterISOLanguageName))
                    using (LogContext.PushProperty(LoggingEnrichment.RouteAction,
                                                   context.RouteData?.Values["action"]))
                        using (LogContext.PushProperty(LoggingEnrichment.RouteArea,
                                                       context.RouteData?.Values["area"]))
                            using (LogContext.PushProperty(LoggingEnrichment.RouteController,
                                                           context.RouteData?.Values["controller"]))
                                using (LogContext.PushProperty(LoggingEnrichment.RouteId,
                                                               context.RouteData?.Values["id"]))
                                    using (LogContext.PushProperty(LoggingEnrichment.SiteStage, siteStage))
                                    {
                                        await next();
                                    }
        }
예제 #2
0
        private void AddFacebookTags(TagHelperOutput output,
                                     Site site,
                                     string title,
                                     string description)
        {
            var currentCulture = _userContextProvider.GetCurrentCulture();
            var ogLink         = GetSiteLink(site, currentCulture);

            output.Content.AppendHtml(MetaProperty("og:url", ogLink));
            output.Content.AppendHtml(Environment.NewLine);

            output.Content.AppendHtml(MetaProperty("og:type", "website"));
            output.Content.AppendHtml(Environment.NewLine);

            output.Content.AppendHtml(MetaProperty("og:title", title));
            output.Content.AppendHtml(Environment.NewLine);

            if (!string.IsNullOrEmpty(description))
            {
                output.Content.AppendHtml(MetaProperty("og:description", description));
                output.Content.AppendHtml(Environment.NewLine);
            }

            if (currentCulture != null)
            {
                output.Content.AppendHtml(MetaProperty("og:locale",
                                                       currentCulture.Name.Replace('-', '_')));
                output.Content.AppendHtml(Environment.NewLine);

                if (_localizationOptions != null)
                {
                    foreach (var l10n in _localizationOptions.Value.SupportedUICultures)
                    {
                        if (l10n.Name != currentCulture.Name)
                        {
                            output.Content.AppendHtml(MetaProperty("og:locale:alternate",
                                                                   l10n.Name.Replace('-', '_')));
                            output.Content.AppendHtml(Environment.NewLine);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(Data?.ImageLink) && !string.IsNullOrEmpty(Data?.ImageAlt))
            {
                var link     = GetSiteLink(site, null);
                var cardLink = link.EndsWith('/')
                    ? link + Data.ImageLink.TrimStart('/')
                    : link + '/' + Data.ImageLink.TrimStart('/');

                output.Content.AppendHtml(MetaProperty("og:image", cardLink));
                output.Content.AppendHtml(Environment.NewLine);
                if (cardLink.StartsWith(SecureScheme))
                {
                    output.Content.AppendHtml(MetaProperty("og:image:secure_url", cardLink));
                    output.Content.AppendHtml(Environment.NewLine);
                }
                output.Content.AppendHtml(MetaProperty("og:image:alt", Data.ImageAlt));
                output.Content.AppendHtml(Environment.NewLine);
                if (Data.ImageWidth != default && Data.ImageHeight != default)
                {
                    output.Content.AppendHtml(MetaProperty("og:image:width",
                                                           Data.ImageWidth.ToString(CultureInfo.InvariantCulture)));
                    output.Content.AppendHtml(Environment.NewLine);
                    output.Content.AppendHtml(MetaProperty("og:image:height",
                                                           Data.ImageHeight.ToString(CultureInfo.InvariantCulture)));
                    output.Content.AppendHtml(Environment.NewLine);
                }
            }
        }