< Summary

Information
Class: OzonOrdersWeb.Extensions.IdentityExtensions
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Extensions/IdentityExtensions.cs
Line coverage
86%
Covered lines: 40
Uncovered lines: 6
Coverable lines: 46
Total lines: 80
Line coverage: 86.9%
Branch coverage
100%
Covered branches: 10
Total branches: 10
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddIdentityServices(...)100%101086.95%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Extensions/IdentityExtensions.cs

#LineLine coverage
 1using System.IO;
 2using Microsoft.AspNetCore.DataProtection;
 3using Microsoft.AspNetCore.Hosting;
 4using Microsoft.AspNetCore.Identity;
 5using Microsoft.Extensions.Hosting;
 6using OzonRepositories.Context.Identity;
 7
 8namespace OzonOrdersWeb.Extensions;
 9
 10public static class IdentityExtensions
 11{
 12    public static void AddIdentityServices(this IServiceCollection services, IWebHostEnvironment environment, IConfigura
 13    {
 14        // DataProtection keys must persist across restarts/deploys,
 15        // otherwise auth/session cookies cannot be decrypted ("key was not found in the key ring").
 416        IDataProtectionBuilder dataProtectionBuilder = services
 417            .AddDataProtection()
 418            .SetApplicationName("Studio2Prod");
 19
 420        var keysPath = Environment.GetEnvironmentVariable("ASPNETCORE_DATA_PROTECTION_KEYS_PATH");
 421        if (string.IsNullOrWhiteSpace(keysPath))
 22        {
 423            keysPath = Path.Combine(environment.ContentRootPath, "DataProtection-Keys");
 24        }
 25
 426        var directory = new DirectoryInfo(keysPath);
 427        if (!directory.Exists)
 28        {
 429            directory.Create();
 30        }
 31
 432        dataProtectionBuilder.PersistKeysToFileSystem(directory);
 33
 434        if (environment.IsDevelopment())
 35        {
 436            Console.WriteLine($"[DataProtection] Keys directory: {directory.FullName}");
 37        }
 38
 439        services.AddDefaultIdentity<CustomIdentityUser>()
 440            .AddDefaultTokenProviders()
 441            .AddRoles<IdentityRole>()
 442            .AddEntityFrameworkStores<OzonIdentityOrderContext>();
 43
 44        // Настройка блокировки аккаунта после неудачных попыток входа
 445        services.Configure<IdentityOptions>(options =>
 446        {
 447            // Блокировка аккаунта: максимум 5 попыток, блокировка на 15 минут
 148            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
 149            options.Lockout.MaxFailedAccessAttempts = 5;
 150            options.Lockout.AllowedForNewUsers = true;
 451
 452            // Для внутренних пользователей не требуем спецсимвол в пароле.
 153            options.Password.RequireNonAlphanumeric = false;
 154            options.SignIn.RequireConfirmedEmail = true;
 555        });
 56
 57        // Базовые настройки Cookie (детальные настройки безопасности в SecurityExtensions)
 458        services.ConfigureApplicationCookie(options =>
 459        {
 060            options.Cookie.Name = ".AspNetCore.Identity.Application";
 061            options.LoginPath = "/Identity/Account/Login";
 062            options.LogoutPath = "/Identity/Account/Logout";
 063            options.AccessDeniedPath = "/Identity/Account/AccessDenied";
 464            // Детальные настройки безопасности (HttpOnly, Secure, SameSite) настраиваются в SecurityExtensions
 465        });
 66
 467        var googleClientId = configuration["Authentication:Google:ClientId"];
 468        var googleClientSecret = configuration["Authentication:Google:ClientSecret"];
 469        if (!string.IsNullOrWhiteSpace(googleClientId) && !string.IsNullOrWhiteSpace(googleClientSecret))
 70        {
 171            services
 172                .AddAuthentication()
 173                .AddGoogle(options =>
 174                {
 075                    options.ClientId = googleClientId;
 076                    options.ClientSecret = googleClientSecret;
 177                });
 78        }
 479    }
 80}