1 // Copyright (c) .NET Foundation. All rights reserved. 2 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 4 using System; 5 using System.Linq; 6 using System.Threading.Tasks; 7 using Identity.DefaultUI.WebSite; 8 using Microsoft.EntityFrameworkCore; 9 using Microsoft.Extensions.DependencyInjection; 10 using Xunit; 11 using Xunit.Sdk; 12 13 namespace Microsoft.AspNetCore.Identity.FunctionalTests 14 { 15 public abstract class LoginTests<TStartup, TContext> : IClassFixture<ServerFactory<TStartup, TContext>> 16 where TStartup : class 17 where TContext : DbContext 18 { LoginTests(ServerFactory<TStartup, TContext> serverFactory)19 public LoginTests(ServerFactory<TStartup, TContext> serverFactory) 20 { 21 ServerFactory = serverFactory; 22 } 23 24 public ServerFactory<TStartup, TContext> ServerFactory { get; } 25 26 [Fact] CanLogInWithAPreviouslyRegisteredUser()27 public async Task CanLogInWithAPreviouslyRegisteredUser() 28 { 29 // Arrange 30 var client = ServerFactory.CreateClient(); 31 var newClient = ServerFactory.CreateClient(); 32 33 var userName = $"{Guid.NewGuid()}@example.com"; 34 var password = $"!Test.Password1$"; 35 36 // Act & Assert 37 await UserStories.RegisterNewUserAsync(client, userName, password); 38 39 // Use a new client to simulate a new browser session. 40 await UserStories.LoginExistingUserAsync(newClient, userName, password); 41 } 42 43 [Fact] CanLogInWithAPreviouslyRegisteredUser_WithGlobalAuthorizeFilter()44 public async Task CanLogInWithAPreviouslyRegisteredUser_WithGlobalAuthorizeFilter() 45 { 46 // Arrange 47 void ConfigureTestServices(IServiceCollection services) => 48 services.SetupGlobalAuthorizeFilter(); 49 50 var server = ServerFactory 51 .WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 52 53 var client = server.CreateClient(); 54 var newClient = server.CreateClient(); 55 56 var userName = $"{Guid.NewGuid()}@example.com"; 57 var password = $"!Test.Password1$"; 58 59 // Act & Assert 60 await UserStories.RegisterNewUserAsync(client, userName, password); 61 62 // Use a new client to simulate a new browser session. 63 await UserStories.LoginExistingUserAsync(newClient, userName, password); 64 } 65 66 [Fact] CanLogInWithTwoFactorAuthentication()67 public async Task CanLogInWithTwoFactorAuthentication() 68 { 69 // Arrange 70 var client = ServerFactory.CreateClient(); 71 var newClient = ServerFactory.CreateClient(); 72 73 var userName = $"{Guid.NewGuid()}@example.com"; 74 var password = $"!Test.Password1$"; 75 76 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 77 var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn); 78 79 var twoFactorKey = showRecoveryCodes.Context.AuthenticatorKey; 80 81 // Act & Assert 82 // Use a new client to simulate a new browser session. 83 await UserStories.LoginExistingUser2FaAsync(newClient, userName, password, twoFactorKey); 84 } 85 86 [Fact] CanLogInWithTwoFactorAuthentication_WithGlobalAuthorizeFilter()87 public async Task CanLogInWithTwoFactorAuthentication_WithGlobalAuthorizeFilter() 88 { 89 // Arrange 90 void ConfigureTestServices(IServiceCollection services) => 91 services.SetupGlobalAuthorizeFilter(); 92 93 var server = ServerFactory 94 .WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 95 96 var client = server.CreateClient(); 97 var newClient = server.CreateClient(); 98 99 var userName = $"{Guid.NewGuid()}@example.com"; 100 var password = $"!Test.Password1$"; 101 102 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 103 var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn); 104 105 var twoFactorKey = showRecoveryCodes.Context.AuthenticatorKey; 106 107 // Act & Assert 108 // Use a new client to simulate a new browser session. 109 await UserStories.LoginExistingUser2FaAsync(newClient, userName, password, twoFactorKey); 110 } 111 112 [Fact] CanLogInWithRecoveryCode()113 public async Task CanLogInWithRecoveryCode() 114 { 115 // Arrange 116 var client = ServerFactory.CreateClient(); 117 var newClient = ServerFactory.CreateClient(); 118 119 var userName = $"{Guid.NewGuid()}@example.com"; 120 var password = $"!Test.Password1$"; 121 122 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 123 var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn); 124 125 var recoveryCode = showRecoveryCodes.Context.RecoveryCodes.First(); 126 127 // Act & Assert 128 // Use a new client to simulate a new browser session. 129 await UserStories.LoginExistingUserRecoveryCodeAsync(newClient, userName, password, recoveryCode); 130 } 131 132 [Fact] CanLogInWithRecoveryCode_WithGlobalAuthorizeFilter()133 public async Task CanLogInWithRecoveryCode_WithGlobalAuthorizeFilter() 134 { 135 // Arrange 136 void ConfigureTestServices(IServiceCollection services) => 137 services.SetupGlobalAuthorizeFilter(); 138 139 var server = ServerFactory 140 .WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 141 var client = server.CreateClient(); 142 var newClient = server.CreateClient(); 143 144 var userName = $"{Guid.NewGuid()}@example.com"; 145 var password = $"!Test.Password1$"; 146 147 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 148 var showRecoveryCodes = await UserStories.EnableTwoFactorAuthentication(loggedIn); 149 150 var recoveryCode = showRecoveryCodes.Context.RecoveryCodes.First(); 151 152 // Act & Assert 153 // Use a new client to simulate a new browser session. 154 await UserStories.LoginExistingUserRecoveryCodeAsync(newClient, userName, password, recoveryCode); 155 } 156 157 [Fact] CannotLogInWithoutRequiredEmailConfirmation()158 public async Task CannotLogInWithoutRequiredEmailConfirmation() 159 { 160 // Arrange 161 var emailSender = new ContosoEmailSender(); 162 void ConfigureTestServices(IServiceCollection services) => services 163 .SetupTestEmailSender(emailSender) 164 .SetupEmailRequired(); 165 166 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 167 168 var client = server.CreateClient(); 169 var newClient = server.CreateClient(); 170 171 var userName = $"{Guid.NewGuid()}@example.com"; 172 var password = $"!Test.Password1$"; 173 174 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 175 176 // Act & Assert 177 // Use a new client to simulate a new browser session. 178 await Assert.ThrowsAnyAsync<XunitException>(() => UserStories.LoginExistingUserAsync(newClient, userName, password)); 179 } 180 181 [Fact] CannotLogInWithoutRequiredEmailConfirmation_WithGlobalAuthorizeFilter()182 public async Task CannotLogInWithoutRequiredEmailConfirmation_WithGlobalAuthorizeFilter() 183 { 184 // Arrange 185 var emailSender = new ContosoEmailSender(); 186 void ConfigureTestServices(IServiceCollection services) => services 187 .SetupTestEmailSender(emailSender) 188 .SetupEmailRequired() 189 .SetupGlobalAuthorizeFilter(); 190 191 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 192 193 var client = server.CreateClient(); 194 var newClient = server.CreateClient(); 195 196 var userName = $"{Guid.NewGuid()}@example.com"; 197 var password = $"!Test.Password1$"; 198 199 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 200 201 // Act & Assert 202 // Use a new client to simulate a new browser session. 203 await Assert.ThrowsAnyAsync<XunitException>(() => UserStories.LoginExistingUserAsync(newClient, userName, password)); 204 } 205 206 [Fact] CanLogInAfterConfirmingEmail()207 public async Task CanLogInAfterConfirmingEmail() 208 { 209 // Arrange 210 var emailSender = new ContosoEmailSender(); 211 void ConfigureTestServices(IServiceCollection services) => services 212 .SetupTestEmailSender(emailSender) 213 .SetupEmailRequired(); 214 215 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 216 217 var client = server.CreateClient(); 218 var newClient = server.CreateClient(); 219 220 var userName = $"{Guid.NewGuid()}@example.com"; 221 var password = $"!Test.Password1$"; 222 223 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 224 225 // Act & Assert 226 // Use a new client to simulate a new browser session. 227 var email = Assert.Single(emailSender.SentEmails); 228 await UserStories.ConfirmEmailAsync(email, newClient); 229 230 await UserStories.LoginExistingUserAsync(newClient, userName, password); 231 } 232 233 [Fact] CanLogInAfterConfirmingEmail_WithGlobalAuthorizeFilter()234 public async Task CanLogInAfterConfirmingEmail_WithGlobalAuthorizeFilter() 235 { 236 // Arrange 237 var emailSender = new ContosoEmailSender(); 238 void ConfigureTestServices(IServiceCollection services) => services 239 .SetupTestEmailSender(emailSender) 240 .SetupEmailRequired() 241 .SetupGlobalAuthorizeFilter(); 242 243 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 244 245 var client = server.CreateClient(); 246 var newClient = server.CreateClient(); 247 248 var userName = $"{Guid.NewGuid()}@example.com"; 249 var password = $"!Test.Password1$"; 250 251 var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); 252 253 // Act & Assert 254 // Use a new client to simulate a new browser session. 255 var email = Assert.Single(emailSender.SentEmails); 256 await UserStories.ConfirmEmailAsync(email, newClient); 257 258 await UserStories.LoginExistingUserAsync(newClient, userName, password); 259 } 260 261 [Fact] CanLoginWithASocialLoginProvider()262 public async Task CanLoginWithASocialLoginProvider() 263 { 264 // Arrange 265 void ConfigureTestServices(IServiceCollection services) => 266 services.SetupTestThirdPartyLogin(); 267 268 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 269 270 var client = server.CreateClient(); 271 var newClient = server.CreateClient(); 272 273 var guid = Guid.NewGuid(); 274 var userName = $"{guid}"; 275 var email = $"{guid}@example.com"; 276 277 // Act & Assert 278 await UserStories.RegisterNewUserWithSocialLoginAsync(client, userName, email); 279 await UserStories.LoginWithSocialLoginAsync(newClient, userName); 280 } 281 282 [Fact] CanLoginWithASocialLoginProvider_WithGlobalAuthorizeFilter()283 public async Task CanLoginWithASocialLoginProvider_WithGlobalAuthorizeFilter() 284 { 285 // Arrange 286 void ConfigureTestServices(IServiceCollection services) => services 287 .SetupTestThirdPartyLogin() 288 .SetupGlobalAuthorizeFilter(); 289 290 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 291 292 var client = server.CreateClient(); 293 var newClient = server.CreateClient(); 294 295 var guid = Guid.NewGuid(); 296 var userName = $"{guid}"; 297 var email = $"{guid}@example.com"; 298 299 // Act & Assert 300 await UserStories.RegisterNewUserWithSocialLoginAsync(client, userName, email); 301 await UserStories.LoginWithSocialLoginAsync(newClient, userName); 302 } 303 304 [Fact] CanLogInAfterResettingThePassword()305 public async Task CanLogInAfterResettingThePassword() 306 { 307 // Arrange 308 var emailSender = new ContosoEmailSender(); 309 void ConfigureTestServices(IServiceCollection services) => services 310 .SetupTestEmailSender(emailSender); 311 312 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 313 314 var client = server.CreateClient(); 315 var resetPasswordClient = server.CreateClient(); 316 var newClient = server.CreateClient(); 317 318 var userName = $"{Guid.NewGuid()}@example.com"; 319 var password = $"!Test.Password1$"; 320 var newPassword = $"!New.Password1$"; 321 322 await UserStories.RegisterNewUserAsync(client, userName, password); 323 var registrationEmail = Assert.Single(emailSender.SentEmails); 324 await UserStories.ConfirmEmailAsync(registrationEmail, client); 325 326 // Act & Assert 327 await UserStories.ForgotPasswordAsync(resetPasswordClient, userName); 328 Assert.Equal(2, emailSender.SentEmails.Count); 329 var email = emailSender.SentEmails[1]; 330 await UserStories.ResetPasswordAsync(resetPasswordClient, email, userName, newPassword); 331 await UserStories.LoginExistingUserAsync(newClient, userName, newPassword); 332 } 333 334 [Fact] CanResetPassword_WithGlobalAuthorizeFilter()335 public async Task CanResetPassword_WithGlobalAuthorizeFilter() 336 { 337 // Arrange 338 var emailSender = new ContosoEmailSender(); 339 void ConfigureTestServices(IServiceCollection services) => 340 services.SetupGlobalAuthorizeFilter().SetupTestEmailSender(emailSender); 341 342 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 343 344 var client = server.CreateClient(); 345 var resetPasswordClient = server.CreateClient(); 346 var newClient = server.CreateClient(); 347 348 var userName = $"{Guid.NewGuid()}@example.com"; 349 var password = $"!Test.Password1$"; 350 var newPassword = $"!New.Password1$"; 351 352 await UserStories.RegisterNewUserAsync(client, userName, password); 353 var registrationEmail = Assert.Single(emailSender.SentEmails); 354 await UserStories.ConfirmEmailAsync(registrationEmail, client); 355 356 // Act & Assert 357 await UserStories.ForgotPasswordAsync(resetPasswordClient, userName); 358 Assert.Equal(2, emailSender.SentEmails.Count); 359 var email = emailSender.SentEmails[1]; 360 await UserStories.ResetPasswordAsync(resetPasswordClient, email, userName, newPassword); 361 await UserStories.LoginExistingUserAsync(newClient, userName, newPassword); 362 } 363 364 [Fact] UserNotLockedOut_AfterMaxFailedAccessAttempts_WithGlobalAuthorizeFilter()365 public async Task UserNotLockedOut_AfterMaxFailedAccessAttempts_WithGlobalAuthorizeFilter() 366 { 367 // Arrange 368 var emailSender = new ContosoEmailSender(); 369 void ConfigureTestServices(IServiceCollection services) => 370 services.SetupGlobalAuthorizeFilter().SetupMaxFailedAccessAttempts().SetupTestEmailSender(emailSender); 371 372 var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); 373 374 var client = server.CreateClient(); 375 var newClient = server.CreateClient(); 376 377 var userName = $"{Guid.NewGuid()}@example.com"; 378 var password = $"!Test.Password1$"; 379 var wrongPassword = $"!Wrong.Password1$"; 380 381 await UserStories.RegisterNewUserAsync(client, userName, password); 382 var registrationEmail = Assert.Single(emailSender.SentEmails); 383 await UserStories.ConfirmEmailAsync(registrationEmail, client); 384 385 // Act & Assert 386 await UserStories.LoginFailsWithWrongPasswordAsync(newClient, userName, wrongPassword); 387 } 388 } 389 } 390