コード例 #1
0
            /// <summary>
            /// Called early in the filter pipeline to confirm request is authorized
            /// </summary>
            /// <param name="context">Authorization filter context</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task CheckAccessPublicStoreAsync(AuthorizationFilterContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //check whether this filter has been overridden for the Action
                var actionFilter = context.ActionDescriptor.FilterDescriptors
                                   .Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                                   .Select(filterDescriptor => filterDescriptor.Filter)
                                   .OfType <CheckAccessPublicStoreAttribute>()
                                   .FirstOrDefault();

                //ignore filter (the action is available even if navigation is not allowed)
                if (actionFilter?.IgnoreFilter ?? _ignoreFilter)
                {
                    return;
                }

                //check whether current customer has access to a public store
                if (await _permissionService.AuthorizeAsync(StandardPermissionProvider.PublicStoreAllowNavigation))
                {
                    return;
                }

                //customer hasn't access to a public store
                context.Result = new ChallengeResult();
            }
コード例 #2
0
        /// <summary>
        /// Add and configure WebMarkupMin service
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        public static void AddNopWebMarkupMin(this IServiceCollection services)
        {
            //check whether database is installed
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            services
            .AddWebMarkupMin(options =>
            {
                options.AllowMinificationInDevelopmentEnvironment = true;
                options.AllowCompressionInDevelopmentEnvironment  = true;
                options.DisableMinification         = !EngineContext.Current.Resolve <CommonSettings>().EnableHtmlMinification;
                options.DisableCompression          = true;
                options.DisablePoweredByHttpHeaders = true;
            })
            .AddHtmlMinification(options =>
            {
                options.CssMinifierFactory = new NUglifyCssMinifierFactory();
                options.JsMinifierFactory  = new NUglifyJsMinifierFactory();
            })
            .AddXmlMinification(options =>
            {
                var settings = options.MinificationSettings;
                settings.RenderEmptyTagsWithSpace   = true;
                settings.CollapseTagsWithoutContent = true;
            });
        }
コード例 #3
0
            /// <summary>
            /// Called early in the filter pipeline to confirm request is authorized
            /// </summary>
            /// <param name="context">Authorization filter context</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task AuthorizeAdminAsync(AuthorizationFilterContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //check whether this filter has been overridden for the action
                var actionFilter = context.ActionDescriptor.FilterDescriptors
                                   .Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                                   .Select(filterDescriptor => filterDescriptor.Filter)
                                   .OfType <AuthorizeAdminAttribute>()
                                   .FirstOrDefault();

                //ignore filter (the action is available even if a customer hasn't access to the admin area)
                if (actionFilter?.IgnoreFilter ?? _ignoreFilter)
                {
                    return;
                }

                //there is AdminAuthorizeFilter, so check access
                if (context.Filters.Any(filter => filter is AuthorizeAdminFilter))
                {
                    //authorize permission of access to the admin area
                    if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel))
                    {
                        context.Result = new ChallengeResult();
                    }
                }
            }
コード例 #4
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task SaveLastActivityAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                //only in GET requests
                if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Get, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //update last activity date
                var customer = await _workContext.GetCurrentCustomerAsync();

                if (customer.LastActivityDateUtc.AddMinutes(_customerSettings.LastActivityMinutes) < DateTime.UtcNow)
                {
                    customer.LastActivityDateUtc = DateTime.UtcNow;

                    //update customer without event notification
                    await _customerRepository.UpdateAsync(customer, false);
                }
            }
コード例 #5
0
        public static void StartEngine(this IApplicationBuilder application)
        {
            var engine = EngineContext.Current;

            //further actions are performed only when the database is installed
            if (DataSettingsManager.IsDatabaseInstalled())
            {
                //initialize and start schedule tasks
                Services.Tasks.TaskManager.Instance.Initialize();
                Services.Tasks.TaskManager.Instance.Start();

                //log application start
                engine.Resolve <ILogger>().InformationAsync("Application started").Wait();

                //install and update plugins
                var pluginService = engine.Resolve <IPluginService>();
                pluginService.InstallPluginsAsync().Wait();
                pluginService.UpdatePluginsAsync().Wait();

                //update nopCommerce core and db
                var migrationManager = engine.Resolve <IMigrationManager>();
                var assembly         = Assembly.GetAssembly(typeof(ApplicationBuilderExtensions));
                migrationManager.ApplyUpMigrations(assembly, true);
                assembly = Assembly.GetAssembly(typeof(IMigrationManager));
                migrationManager.ApplyUpMigrations(assembly, true);

#if DEBUG
                //prevent save the update migrations into the DB during the developing process
                var versions = EngineContext.Current.Resolve <IRepository <MigrationVersionInfo> >();
                versions.DeleteAsync(mvi => mvi.Description.StartsWith(string.Format(NopMigrationDefaults.UpdateMigrationDescriptionPrefix, NopVersion.FULL_VERSION)));
#endif
            }
        }
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task ValidateAuthenticationForceAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //validate only for registered customers
                var customer = await _workContext.GetCurrentCustomerAsync();

                if (!await _customerService.IsRegisteredAsync(customer))
                {
                    return;
                }

                //don't validate on the 'Multi-factor authentication settings' page
                var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                var actionName       = actionDescriptor?.ActionName;
                var controllerName   = actionDescriptor?.ControllerName;

                if (string.IsNullOrEmpty(actionName) || string.IsNullOrEmpty(controllerName))
                {
                    return;
                }

                if (controllerName.Equals("Customer", StringComparison.InvariantCultureIgnoreCase) &&
                    actionName.Equals("MultiFactorAuthentication", StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                //whether the feature is enabled
                if (!_multiFactorAuthenticationSettings.ForceMultifactorAuthentication ||
                    !await _multiFactorAuthenticationPluginManager.HasActivePluginsAsync())
                {
                    return;
                }

                //check selected provider of MFA
                var selectedProvider = await _genericAttributeService
                                       .GetAttributeAsync <string>(customer, NopCustomerDefaults.SelectedMultiFactorAuthenticationProviderAttribute);

                if (!string.IsNullOrEmpty(selectedProvider))
                {
                    return;
                }

                //redirect to MultiFactorAuthenticationSettings page if force is enabled
                context.Result = new RedirectToRouteResult("MultiFactorAuthenticationSettings", null);
            }
コード例 #7
0
        /// <summary>
        /// Configure the request localization feature
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseNopRequestLocalization(this IApplicationBuilder application)
        {
            application.UseRequestLocalization(async options =>
            {
                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //prepare supported cultures
                var cultures = (await EngineContext.Current.Resolve <ILanguageService>().GetAllLanguagesAsync())
                               .OrderBy(language => language.DisplayOrder)
                               .Select(language => new CultureInfo(language.LanguageCulture)).ToList();
                options.SupportedCultures     = cultures;
                options.SupportedUICultures   = cultures;
                options.DefaultRequestCulture = new RequestCulture(cultures.FirstOrDefault());
                options.ApplyCurrentCultureToResponseHeaders = true;

                //configure culture providers
                options.AddInitialRequestCultureProvider(new NopSeoUrlCultureProvider());
                var cookieRequestCultureProvider = options.RequestCultureProviders.OfType <CookieRequestCultureProvider>().FirstOrDefault();
                if (cookieRequestCultureProvider is not null)
                {
                    cookieRequestCultureProvider.CookieName = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.CultureCookie}";
                }
            });
        }
コード例 #8
0
        public static void StartEngine(this IApplicationBuilder application)
        {
            var engine = EngineContext.Current;

            //further actions are performed only when the database is installed
            if (DataSettingsManager.IsDatabaseInstalled())
            {
                //log application start
                engine.Resolve <ILogger>().InformationAsync("Application started").Wait();

                //install and update plugins
                var pluginService = engine.Resolve <IPluginService>();
                pluginService.InstallPluginsAsync().Wait();
                pluginService.UpdatePluginsAsync().Wait();

                //update nopCommerce core and db
                var migrationManager = engine.Resolve <IMigrationManager>();
                var assembly         = Assembly.GetAssembly(typeof(ApplicationBuilderExtensions));
                migrationManager.ApplyUpMigrations(assembly, MigrationProcessType.Update);
                assembly = Assembly.GetAssembly(typeof(IMigrationManager));
                migrationManager.ApplyUpMigrations(assembly, MigrationProcessType.Update);

                var taskScheduler = engine.Resolve <ITaskScheduler>();
                taskScheduler.InitializeAsync().Wait();
                taskScheduler.StartScheduler();
            }
        }
コード例 #9
0
        /// <summary>
        /// Collect the UP migration expressions
        /// </summary>
        public override void Up()
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //locales
            var languages  = _languageService.GetAllLanguagesAsync(true).Result;
            var languageId = languages
                             .FirstOrDefault(lang => lang.UniqueSeoCode == new CultureInfo(NopCommonDefaults.DefaultLanguageCulture).TwoLetterISOLanguageName)
                             ?.Id;

            _localizationService.AddOrUpdateLocaleResourceAsync(new Dictionary <string, string>
            {
                ["Plugins.Payments.PayPalCommerce.Fields.DisplayPayLaterMessages"]      = "Display Pay Later messages",
                ["Plugins.Payments.PayPalCommerce.Fields.DisplayPayLaterMessages.Hint"] = "Determine whether to display Pay Later messages. This message displays how much the customer pays in four payments. The message will be shown next to the PayPal buttons.",
            }, languageId).Wait();


            //settings
            if (!_settingService.SettingExistsAsync(_payPalCommerceSettings, settings => settings.DisplayPayLaterMessages).Result)
            {
                _payPalCommerceSettings.DisplayPayLaterMessages = false;
            }

            _settingService.SaveSettingAsync(_payPalCommerceSettings).Wait();
        }
コード例 #10
0
        /// <summary>Collect the UP migration expressions</summary>
        public override void Up()
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //do not use DI, because it produces exception on the installation process
            var settingRepository = EngineContext.Current.Resolve <IRepository <Setting> >();
            var settingService    = EngineContext.Current.Resolve <ISettingService>();

            //miniprofiler settings are moved to appSettings
            settingRepository
            .DeleteAsync(setting => setting.Name == "storeinformationsettings.displayminiprofilerforadminonly" ||
                         setting.Name == "storeinformationsettings.displayminiprofilerinpublicstore").Wait();

            //#4363
            var commonSettings = settingService.LoadSettingAsync <CommonSettings>().Result;

            if (!settingService.SettingExistsAsync(commonSettings, settings => settings.ClearLogOlderThanDays).Result)
            {
                commonSettings.ClearLogOlderThanDays = 0;
                settingService.SaveSettingAsync(commonSettings).Wait();
            }
        }
コード例 #11
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task ValidateCaptchaAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //whether CAPTCHA is enabled
                if (_captchaSettings.Enabled && context.HttpContext?.Request != null)
                {
                    //push the validation result as an action parameter
                    var isValid = false;

                    //get form values
                    var captchaResponseValue  = context.HttpContext.Request.Form[RESPONSE_FIELD_KEY];
                    var gCaptchaResponseValue = context.HttpContext.Request.Form[G_RESPONSE_FIELD_KEY];

                    if (!StringValues.IsNullOrEmpty(captchaResponseValue) || !StringValues.IsNullOrEmpty(gCaptchaResponseValue))
                    {
                        //validate request
                        try
                        {
                            var value    = !StringValues.IsNullOrEmpty(captchaResponseValue) ? captchaResponseValue : gCaptchaResponseValue;
                            var response = await _captchaHttpClient.ValidateCaptchaAsync(value);

                            switch (_captchaSettings.CaptchaType)
                            {
                            case CaptchaType.CheckBoxReCaptchaV2:
                                isValid = response.IsValid;
                                break;

                            case CaptchaType.ReCaptchaV3:
                                isValid = response.IsValid &&
                                          response.Action == context.RouteData.Values["action"].ToString() &&
                                          response.Score > _captchaSettings.ReCaptchaV3ScoreThreshold;
                                break;

                            default:
                                break;
                            }
                        }
                        catch (Exception exception)
                        {
                            await _logger.ErrorAsync("Error occurred on CAPTCHA validation", exception, await _workContext.GetCurrentCustomerAsync());
                        }
                    }

                    context.ActionArguments[_actionParameterName] = isValid;
                }
                else
                {
                    context.ActionArguments[_actionParameterName] = false;
                }
            }
コード例 #12
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task CheckLanguageSeoCodeAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                //only in GET requests
                if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Get, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //check whether this filter has been overridden for the Action
                var actionFilter = context.ActionDescriptor.FilterDescriptors
                                   .Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                                   .Select(filterDescriptor => filterDescriptor.Filter)
                                   .OfType <CheckLanguageSeoCodeAttribute>()
                                   .FirstOrDefault();

                //ignore filter (an action doesn't need to be checked)
                if (actionFilter?.IgnoreFilter ?? _ignoreFilter)
                {
                    return;
                }

                //whether SEO friendly URLs are enabled
                if (!_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
                {
                    return;
                }

                //check whether current page URL is already localized URL
                var pageUrl = _webHelper.GetRawUrl(context.HttpContext.Request);
                var result  = await pageUrl.IsLocalizedUrlAsync(context.HttpContext.Request.PathBase, true);

                if (result.IsLocalized)
                {
                    return;
                }

                //not localized yet, so redirect to the page with working language SEO code
                var language = await _workContext.GetWorkingLanguageAsync();

                pageUrl = pageUrl.AddLanguageSeoCodeToUrl(context.HttpContext.Request.PathBase, true, language);

                context.Result = new LocalRedirectResult(pageUrl, false);
            }
コード例 #13
0
        /// <summary>
        /// Invoke middleware actions
        /// </summary>
        /// <param name="context">HTTP context</param>
        /// <returns>A task that represents the asynchronous operation</returns>
        public async Task InvokeAsync(HttpContext context)
        {
            context.Features.Set <IAuthenticationFeature>(new AuthenticationFeature
            {
                OriginalPath     = context.Request.Path,
                OriginalPathBase = context.Request.PathBase
            });

            // Give any IAuthenticationRequestHandler schemes a chance to handle the request
            var handlers = EngineContext.Current.Resolve <IAuthenticationHandlerProvider>();

            foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
            {
                try
                {
                    if (await handlers.GetHandlerAsync(context, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync())
                    {
                        return;
                    }
                }
                catch (Exception ex)
                {
                    if (!DataSettingsManager.IsDatabaseInstalled())
                    {
                        continue;
                    }

                    var externalAuthenticationSettings =
                        EngineContext.Current.Resolve <ExternalAuthenticationSettings>();

                    if (!externalAuthenticationSettings.LogErrors)
                    {
                        continue;
                    }

                    var logger =
                        EngineContext.Current.Resolve <ILogger>();

                    await logger.ErrorAsync(ex.Message, ex);
                }
            }

            var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();

            if (defaultAuthenticate != null)
            {
                var result = await context.AuthenticateAsync(defaultAuthenticate.Name);

                if (result?.Principal != null)
                {
                    context.User = result.Principal;
                }
            }

            await _next(context);
        }
コード例 #14
0
        /// <summary>
        /// Adds the authentication middleware, which enables authentication capabilities.
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseNopAuthentication(this IApplicationBuilder application)
        {
            //check whether database is installed
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            application.UseMiddleware <AuthenticationMiddleware>();
        }
コード例 #15
0
        /// <summary>
        /// Configure WebMarkupMin
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseNopWebMarkupMin(this IApplicationBuilder application)
        {
            //check whether database is installed
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            application.UseWebMarkupMin();
        }
コード例 #16
0
        /// <summary>
        /// Register routes
        /// </summary>
        /// <param name="endpointRouteBuilder">Route builder</param>
        public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
        {
            var pattern = GetLanguageRoutePattern();

            pattern += "/";

            //default routes
            //these routes are not generic, they are just default to map requests that don't match other patterns,
            //but we define them here since this route provider is with the lowest priority, to allow to add additional routes before them
            endpointRouteBuilder.MapControllerRoute(name: "Default",
                                                    pattern: $"{pattern}{{controller=Home}}/{{action=Index}}/{{id?}}");

            endpointRouteBuilder.MapControllerRoute(name: "Default",
                                                    pattern: "{controller=Home}/{action=Index}/{id?}");

            //generic routes
            pattern += "{SeName}/";

            if (DataSettingsManager.IsDatabaseInstalled())
            {
                endpointRouteBuilder.MapDynamicControllerRoute <SlugRouteTransformer>(pattern);
            }

            endpointRouteBuilder.MapControllerRoute(name: "GenericUrl",
                                                    pattern: "{genericSeName}",
                                                    new { controller = "Common", action = "GenericUrl" });

            endpointRouteBuilder.MapControllerRoute(name: "GenericUrl",
                                                    pattern: "{genericSeName}/{genericParameter}",
                                                    new { controller = "Common", action = "GenericUrl" });

            endpointRouteBuilder.MapControllerRoute("Product", pattern,
                                                    new { controller = "Product", action = "ProductDetails" });

            endpointRouteBuilder.MapControllerRoute("Category", pattern,
                                                    new { controller = "Catalog", action = "Category" });

            endpointRouteBuilder.MapControllerRoute("Manufacturer", pattern,
                                                    new { controller = "Catalog", action = "Manufacturer" });

            endpointRouteBuilder.MapControllerRoute("Vendor", pattern,
                                                    new { controller = "Catalog", action = "Vendor" });

            endpointRouteBuilder.MapControllerRoute("NewsItem", pattern,
                                                    new { controller = "News", action = "NewsItem" });

            endpointRouteBuilder.MapControllerRoute("BlogPost", pattern,
                                                    new { controller = "Blog", action = "BlogPost" });

            endpointRouteBuilder.MapControllerRoute("Topic", pattern,
                                                    new { controller = "Topic", action = "TopicDetails" });

            endpointRouteBuilder.MapControllerRoute("ProductsByTag", pattern,
                                                    new { controller = "Catalog", action = "ProductsByTag" });
        }
コード例 #17
0
        /// <summary>
        /// Add and configure MVC for the application
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        /// <returns>A builder for configuring MVC services</returns>
        public static IMvcBuilder AddNopMvc(this IServiceCollection services)
        {
            //add basic MVC feature
            var mvcBuilder = services.AddControllersWithViews();

            mvcBuilder.AddRazorRuntimeCompilation();

            var appSettings = Singleton <AppSettings> .Instance;

            if (appSettings.CommonConfig.UseSessionStateTempDataProvider)
            {
                //use session-based temp data provider
                mvcBuilder.AddSessionStateTempDataProvider();
            }
            else
            {
                //use cookie-based temp data provider
                mvcBuilder.AddCookieTempDataProvider(options =>
                {
                    options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.TempDataCookie}";

                    //whether to allow the use of cookies from SSL protected page on the other store pages which are not
                    options.Cookie.SecurePolicy = DataSettingsManager.IsDatabaseInstalled() && EngineContext.Current.Resolve <IStoreContext>().GetCurrentStoreAsync().Result.SslEnabled
                        ? CookieSecurePolicy.SameAsRequest : CookieSecurePolicy.None;
                });
            }

            services.AddRazorPages();

            //MVC now serializes JSON with camel case names by default, use this code to avoid it
            mvcBuilder.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

            //add custom display metadata provider
            mvcBuilder.AddMvcOptions(options => options.ModelMetadataDetailsProviders.Add(new NopMetadataProvider()));

            //add fluent validation
            mvcBuilder.AddFluentValidation(configuration =>
            {
                //register all available validators from Nop assemblies
                var assemblies = mvcBuilder.PartManager.ApplicationParts
                                 .OfType <AssemblyPart>()
                                 .Where(part => part.Name.StartsWith("Nop", StringComparison.InvariantCultureIgnoreCase))
                                 .Select(part => part.Assembly);
                configuration.RegisterValidatorsFromAssemblies(assemblies);

                //implicit/automatic validation of child properties
                configuration.ImplicitlyValidateChildProperties = true;
            });

            //register controllers as services, it'll allow to override them
            mvcBuilder.AddControllersAsServices();

            return(mvcBuilder);
        }
コード例 #18
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            private void ValidateIpAddress(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //get action and controller names
                var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                var actionName       = actionDescriptor?.ActionName;
                var controllerName   = actionDescriptor?.ControllerName;

                if (string.IsNullOrEmpty(actionName) || string.IsNullOrEmpty(controllerName))
                {
                    return;
                }

                //don't validate on the 'Access denied' page
                if (controllerName.Equals("Security", StringComparison.InvariantCultureIgnoreCase) &&
                    actionName.Equals("AccessDenied", StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                //get allowed IP addresses
                var ipAddresses = _securitySettings.AdminAreaAllowedIpAddresses;

                //there are no restrictions
                if (ipAddresses == null || !ipAddresses.Any())
                {
                    return;
                }

                //whether current IP is allowed
                var currentIp = _webHelper.GetCurrentIpAddress();

                if (ipAddresses.Any(ip => ip.Equals(currentIp, StringComparison.InvariantCultureIgnoreCase)))
                {
                    return;
                }

                //redirect to 'Access denied' page
                context.Result = new RedirectToActionResult("AccessDenied", "Security", context.RouteData.Values);
            }
コード例 #19
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task ValidatePasswordAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                //ignore AJAX requests
                if (_webHelper.IsAjaxRequest(context.HttpContext.Request))
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //get action and controller names
                var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                var actionName       = actionDescriptor?.ActionName;
                var controllerName   = actionDescriptor?.ControllerName;

                if (string.IsNullOrEmpty(actionName) || string.IsNullOrEmpty(controllerName))
                {
                    return;
                }

                //don't validate on the 'Change Password' page
                if (controllerName.Equals("Customer", StringComparison.InvariantCultureIgnoreCase) &&
                    actionName.Equals("ChangePassword", StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                //check password expiration
                var customer = await _workContext.GetCurrentCustomerAsync();

                if (!await _customerService.IsPasswordExpiredAsync(customer))
                {
                    return;
                }

                var returnUrl = _webHelper.GetRawUrl(context.HttpContext.Request);

                //redirect to ChangePassword page if expires
                context.Result = new RedirectToRouteResult("CustomerChangePassword", new { returnUrl = returnUrl });
            }
コード例 #20
0
        /// <summary>
        /// Adds services required for anti-forgery support
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        public static void AddAntiForgery(this IServiceCollection services)
        {
            //override cookie name
            services.AddAntiforgery(options =>
            {
                options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.AntiforgeryCookie}";

                //whether to allow the use of anti-forgery cookies from SSL protected page on the other store pages which are not
                options.Cookie.SecurePolicy = DataSettingsManager.IsDatabaseInstalled() && EngineContext.Current.Resolve <IStoreContext>().GetCurrentStoreAsync().Result.SslEnabled
                    ? CookieSecurePolicy.SameAsRequest : CookieSecurePolicy.None;
            });
        }
コード例 #21
0
        /// <summary>
        /// Adds services required for application session state
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        public static void AddHttpSession(this IServiceCollection services)
        {
            services.AddSession(options =>
            {
                options.Cookie.Name     = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.SessionCookie}";
                options.Cookie.HttpOnly = true;

                //whether to allow the use of session values from SSL protected page on the other store pages which are not
                options.Cookie.SecurePolicy = DataSettingsManager.IsDatabaseInstalled() && EngineContext.Current.Resolve <IStoreContext>().GetCurrentStoreAsync().Result.SslEnabled
                    ? CookieSecurePolicy.SameAsRequest : CookieSecurePolicy.None;
            });
        }
コード例 #22
0
        /// <summary>Collect the UP migration expressions</summary>
        public override void Up()
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //do not use DI, because it produces exception on the installation process
            var settingRepository = EngineContext.Current.Resolve <IRepository <Setting> >();
            var settingService    = EngineContext.Current.Resolve <ISettingService>();

            //miniprofiler settings are moved to appSettings
            settingRepository
            .DeleteAsync(setting => setting.Name == "storeinformationsettings.displayminiprofilerforadminonly" ||
                         setting.Name == "storeinformationsettings.displayminiprofilerinpublicstore").Wait();

            //#4363
            var commonSettings = settingService.LoadSettingAsync <CommonSettings>().Result;

            if (!settingService.SettingExistsAsync(commonSettings, settings => settings.ClearLogOlderThanDays).Result)
            {
                commonSettings.ClearLogOlderThanDays = 0;
                settingService.SaveSettingAsync(commonSettings).Wait();
            }

            //#5551
            var catalogSettings = settingService.LoadSettingAsync <CatalogSettings>().Result;

            if (!settingService.SettingExistsAsync(catalogSettings, settings => settings.EnableSpecificationAttributeFiltering).Result)
            {
                catalogSettings.EnableSpecificationAttributeFiltering = true;
                settingService.SaveSettingAsync(catalogSettings).Wait();
            }

            //#5204
            var shippingSettings = settingService.LoadSettingAsync <ShippingSettings>().Result;

            if (!settingService.SettingExistsAsync(shippingSettings, settings => settings.ShippingSorting).Result)
            {
                shippingSettings.ShippingSorting = ShippingSortingEnum.Position;
                settingService.SaveSettingAsync(shippingSettings).Wait();
            }

            //#5698
            var orderSettings = settingService.LoadSettingAsync <OrderSettings>().Result;

            if (!settingService.SettingExistsAsync(orderSettings, settings => settings.DisplayOrderSummary).Result)
            {
                orderSettings.DisplayOrderSummary = true;
                settingService.SaveSettingAsync(orderSettings).Wait();
            }
        }
コード例 #23
0
        /// <summary>
        /// Configure middleware for dynamically compressing HTTP responses
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseNopResponseCompression(this IApplicationBuilder application)
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //whether to use compression (gzip by default)
            if (EngineContext.Current.Resolve <CommonSettings>().UseResponseCompression)
            {
                application.UseResponseCompression();
            }
        }
コード例 #24
0
        /// <summary>
        /// Adds services required for themes support
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        public static void AddThemes(this IServiceCollection services)
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //themes support
            services.Configure <RazorViewEngineOptions>(options =>
            {
                options.ViewLocationExpanders.Add(new ThemeableViewLocationExpander());
            });
        }
コード例 #25
0
        /// <summary>
        /// Get pattern used to detect routes with language code
        /// </summary>
        /// <returns></returns>
        protected string GetLanguageRoutePattern()
        {
            if (DataSettingsManager.IsDatabaseInstalled())
            {
                var localizationSettings = EngineContext.Current.Resolve <LocalizationSettings>();
                if (localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
                {
                    return($"{{{NopPathRouteDefaults.LanguageRouteValue}:maxlength(2):{NopPathRouteDefaults.LanguageParameterTransformer}=en}}");
                }
            }

            return(string.Empty);
        }
コード例 #26
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private void SaveSelectedTab(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                //only in POST requests
                if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Post, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                //ignore AJAX requests
                if (_webHelper.IsAjaxRequest(context.HttpContext.Request))
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //check whether this filter has been overridden for the Action
                var actionFilter = context.ActionDescriptor.FilterDescriptors
                                   .Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                                   .Select(filterDescriptor => filterDescriptor.Filter)
                                   .OfType <SaveSelectedTabAttribute>()
                                   .FirstOrDefault();

                //ignore filter
                if (actionFilter?.IgnoreFilter ?? _ignoreFilter)
                {
                    return;
                }

                var persistForTheNextRequest = actionFilter?.PersistForTheNextRequest ?? _persistForTheNextRequest;

                if (context.Controller is BaseController controller)
                {
                    controller.SaveSelectedTabName(persistForTheNextRequest: persistForTheNextRequest);
                }
            }
コード例 #27
0
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that represents the asynchronous operation</returns>
            private async Task SaveIpAddressAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                //only in GET requests
                if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Get, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                if (!DataSettingsManager.IsDatabaseInstalled())
                {
                    return;
                }

                //check whether we store IP addresses
                if (!_customerSettings.StoreIpAddresses)
                {
                    return;
                }

                //get current IP address
                var currentIpAddress = _webHelper.GetCurrentIpAddress();

                if (string.IsNullOrEmpty(currentIpAddress))
                {
                    return;
                }

                //update customer's IP address
                var customer = await _workContext.GetCurrentCustomerAsync();

                if (_workContext.OriginalCustomerIfImpersonated == null &&
                    !currentIpAddress.Equals(customer.LastIpAddress, StringComparison.InvariantCultureIgnoreCase))
                {
                    customer.LastIpAddress = currentIpAddress;

                    //update customer without event notification
                    await _customerRepository.UpdateAsync(customer, false);
                }
            }
コード例 #28
0
        /// <summary>
        /// Collect the UP migration expressions
        /// </summary>
        public override void Up()
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //settings
            if (!_settingService.SettingExistsAsync(_ecbExchangeRateSettings, settings => settings.EcbLink).Result)
            {
                _ecbExchangeRateSettings.EcbLink = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
            }

            _settingService.SaveSettingAsync(_ecbExchangeRateSettings).Wait();
        }
コード例 #29
0
        /// <summary>
        /// Add exception handling
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseNopExceptionHandler(this IApplicationBuilder application)
        {
            var appSettings              = EngineContext.Current.Resolve <AppSettings>();
            var webHostEnvironment       = EngineContext.Current.Resolve <IWebHostEnvironment>();
            var useDetailedExceptionPage = appSettings.Get <CommonConfig>().DisplayFullErrorStack || webHostEnvironment.IsDevelopment();

            if (useDetailedExceptionPage)
            {
                //get detailed exceptions for developing and testing purposes
                application.UseDeveloperExceptionPage();
            }
            else
            {
                //or use special exception handler
                application.UseExceptionHandler("/Error/Error");
            }

            //log errors
            application.UseExceptionHandler(handler =>
            {
                handler.Run(async context =>
                {
                    var exception = context.Features.Get <IExceptionHandlerFeature>()?.Error;
                    if (exception == null)
                    {
                        return;
                    }

                    try
                    {
                        //check whether database is installed
                        if (DataSettingsManager.IsDatabaseInstalled())
                        {
                            //get current customer
                            var currentCustomer = await EngineContext.Current.Resolve <IWorkContext>().GetCurrentCustomerAsync();

                            //log error
                            await EngineContext.Current.Resolve <ILogger>().ErrorAsync(exception.Message, exception, currentCustomer);
                        }
                    }
                    finally
                    {
                        //rethrow the exception to show the error page
                        ExceptionDispatchInfo.Throw(exception);
                    }
                });
            });
        }
コード例 #30
0
        /// <summary>
        /// Collect the UP migration expressions
        /// </summary>
        public override void Up()
        {
            if (!DataSettingsManager.IsDatabaseInstalled())
            {
                return;
            }

            //locales
            var languages  = _languageService.GetAllLanguagesAsync(true).Result;
            var languageId = languages
                             .FirstOrDefault(lang => lang.UniqueSeoCode == new CultureInfo(NopCommonDefaults.DefaultLanguageCulture).TwoLetterISOLanguageName)
                             ?.Id;

            _localizationService.AddOrUpdateLocaleResourceAsync(new Dictionary <string, string>
            {
                ["Plugins.Tax.Avalara.Fields.UseTaxRateTables"]      = "Use tax rate tables to estimate ",
                ["Plugins.Tax.Avalara.Fields.UseTaxRateTables.Hint"] = "Determine whether to use tax rate tables to estimate. This will be used as a default tax calculation for catalog pages and will be adjusted and reconciled to the final transaction tax during checkout. Tax rates are looked up by zip code (US only) in a file that will be periodically updated from the Avalara (see Schedule tasks).",
            }, languageId).Wait();

            //settings
            if (!_settingService.SettingExistsAsync(_avalaraTaxSettings, settings => settings.UseTaxRateTables).Result)
            {
                _avalaraTaxSettings.UseTaxRateTables = true;
            }
            _settingService.SaveSettingAsync(_avalaraTaxSettings).Wait();

            //in version 4.50 we added the LastEnabledUtc field to the ScheduleTask entity,
            //we need to make sure that these changes are applied before inserting new task into the database
            var scheduleTaskTableName = NameCompatibilityManager.GetTableName(typeof(ScheduleTask));

            //add column if not exists
            if (!Schema.Table(scheduleTaskTableName).Column(nameof(ScheduleTask.LastEnabledUtc)).Exists())
            {
                Alter.Table(scheduleTaskTableName)
                .AddColumn(nameof(ScheduleTask.LastEnabledUtc)).AsDateTime2().Nullable();
            }

            //schedule task
            Insert.IntoTable(scheduleTaskTableName).Row(new
            {
                Enabled        = true,
                LastEnabledUtc = DateTime.UtcNow,
                Seconds        = AvalaraTaxDefaults.DownloadTaxRatesTask.Days * 24 * 60 * 60,
                StopOnError    = false,
                Name           = AvalaraTaxDefaults.DownloadTaxRatesTask.Name,
                Type           = AvalaraTaxDefaults.DownloadTaxRatesTask.Type
            });
        }