Skip to content

Commit 8611a10

Browse files
committed
Add SignInManager tests
1 parent e218f3a commit 8611a10

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

src/Identity/test/Identity.Test/SignInManagerTest.cs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Buffers.Text;
45
using System.Security.Claims;
6+
using System.Text.Json;
7+
using System.Text.Json.Nodes;
58
using Microsoft.AspNetCore.Authentication;
69
using Microsoft.AspNetCore.Authentication.Cookies;
710
using Microsoft.AspNetCore.Http;
@@ -1375,6 +1378,114 @@ public async Task TwoFactorSignInLockedOutResultIsDependentOnTheAccessFailedAsyn
13751378
auth.Verify();
13761379
}
13771380

1381+
[Fact]
1382+
public async Task GeneratePasskeyCreationOptionsAsyncReturnsExpectedOptions()
1383+
{
1384+
// Arrange
1385+
var user = new PocoUser { UserName = "Foo" };
1386+
var userManager = SetupUserManager(user);
1387+
var context = new DefaultHttpContext();
1388+
var identityOptions = new IdentityOptions()
1389+
{
1390+
Passkey = new()
1391+
{
1392+
ChallengeSize = 32,
1393+
Timeout = TimeSpan.FromMinutes(10),
1394+
ServerDomain = "example.com",
1395+
},
1396+
};
1397+
var signInManager = SetupSignInManager(userManager.Object, context, identityOptions: identityOptions);
1398+
var userEntity = new PasskeyUserEntity(id: "1234", name: "Foo", displayName: "Foo");
1399+
var creationArgs = new PasskeyCreationArgs(userEntity)
1400+
{
1401+
Attestation = "some-attestation-value",
1402+
AuthenticatorSelection = new AuthenticatorSelectionCriteria
1403+
{
1404+
AuthenticatorAttachment = "cross-platform",
1405+
ResidentKey = "required",
1406+
UserVerification = "preferred"
1407+
},
1408+
Extensions = JsonElement.Parse("""
1409+
{
1410+
"my.bool.extension": true,
1411+
"my.object.extension": {
1412+
"key": "value"
1413+
}
1414+
}
1415+
"""),
1416+
};
1417+
1418+
// Act
1419+
var options = await signInManager.GeneratePasskeyCreationOptionsAsync(creationArgs);
1420+
var optionsJson = JsonNode.Parse(options.AsJson()).AsObject();
1421+
var challenge = Base64Url.DecodeFromChars(optionsJson["challenge"].ToString());
1422+
1423+
// Assert
1424+
Assert.NotNull(options);
1425+
Assert.Same(userEntity, options.UserEntity);
1426+
Assert.Equal(identityOptions.Passkey.ServerDomain, optionsJson["rp"]["id"].ToString());
1427+
Assert.Equal(identityOptions.Passkey.ServerDomain, optionsJson["rp"]["name"].ToString());
1428+
Assert.Equal(identityOptions.Passkey.ChallengeSize, challenge.Length);
1429+
Assert.Equal((uint)identityOptions.Passkey.Timeout.TotalMilliseconds, (uint)optionsJson["timeout"]);
1430+
Assert.Equal(creationArgs.Attestation, optionsJson["attestation"].ToString());
1431+
Assert.Equal(
1432+
creationArgs.AuthenticatorSelection.AuthenticatorAttachment,
1433+
optionsJson["authenticatorSelection"]["authenticatorAttachment"].ToString());
1434+
Assert.Equal(
1435+
creationArgs.AuthenticatorSelection.ResidentKey,
1436+
optionsJson["authenticatorSelection"]["residentKey"].ToString());
1437+
Assert.Equal(
1438+
creationArgs.AuthenticatorSelection.UserVerification,
1439+
optionsJson["authenticatorSelection"]["userVerification"].ToString());
1440+
Assert.True((bool)optionsJson["extensions"]["my.bool.extension"]);
1441+
Assert.Equal("value", optionsJson["extensions"]["my.object.extension"]["key"].ToString());
1442+
}
1443+
1444+
[Fact]
1445+
public async Task GeneratePasskeyRequestOptionsAsyncReturnsExpectedOptions()
1446+
{
1447+
// Arrange
1448+
var user = new PocoUser { UserName = "Foo" };
1449+
var userManager = SetupUserManager(user);
1450+
var context = new DefaultHttpContext();
1451+
var identityOptions = new IdentityOptions()
1452+
{
1453+
Passkey = new()
1454+
{
1455+
ChallengeSize = 32,
1456+
Timeout = TimeSpan.FromMinutes(10),
1457+
ServerDomain = "example.com",
1458+
},
1459+
};
1460+
var signInManager = SetupSignInManager(userManager.Object, context, identityOptions: identityOptions);
1461+
var requestArgs = new PasskeyRequestArgs<PocoUser>
1462+
{
1463+
UserVerification = "preferred",
1464+
Extensions = JsonElement.Parse("""
1465+
{
1466+
"my.bool.extension": true,
1467+
"my.object.extension": {
1468+
"key": "value"
1469+
}
1470+
}
1471+
"""),
1472+
};
1473+
1474+
// Act
1475+
var options = await signInManager.GeneratePasskeyRequestOptionsAsync(requestArgs);
1476+
var optionsJson = JsonNode.Parse(options.AsJson()).AsObject();
1477+
var challenge = Base64Url.DecodeFromChars(optionsJson["challenge"].ToString());
1478+
1479+
// Assert
1480+
Assert.NotNull(options);
1481+
Assert.Equal(identityOptions.Passkey.ServerDomain, optionsJson["rpId"].ToString());
1482+
Assert.Equal(identityOptions.Passkey.ChallengeSize, challenge.Length);
1483+
Assert.Equal((uint)identityOptions.Passkey.Timeout.TotalMilliseconds, (uint)optionsJson["timeout"]);
1484+
Assert.Equal(requestArgs.UserVerification, optionsJson["userVerification"].ToString());
1485+
Assert.True((bool)optionsJson["extensions"]["my.bool.extension"]);
1486+
Assert.Equal("value", optionsJson["extensions"]["my.object.extension"]["key"].ToString());
1487+
}
1488+
13781489
private static SignInManager<PocoUser> SetupSignInManagerType(UserManager<PocoUser> manager, HttpContext context, string typeName)
13791490
{
13801491
var contextAccessor = new Mock<IHttpContextAccessor>();

0 commit comments

Comments
 (0)