Skip to content

Commit b65a12d

Browse files
[fix] Align trust check with session protocol version (#254)
1 parent 0d9ff01 commit b65a12d

File tree

5 files changed

+55
-56
lines changed

5 files changed

+55
-56
lines changed

src/ByteSync.ServerCommon/Business/Sessions/CloudSessionData.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public CloudSessionData(string? lobbyId, EncryptedSessionSettings sessionSetting
2929

3030
public EncryptedSessionSettings SessionSettings { get; set; } = null!;
3131

32+
public int ProtocolVersion { get; set; }
33+
3234
public bool IsSessionActivated { get; set; }
3335

3436
public List<SessionMemberData> SessionMembers { get; set; }
@@ -77,4 +79,4 @@ public CloudSession GetCloudSession()
7779
{
7880
return SessionMembers.Concat(PreSessionMembers).Distinct().SingleOrDefault(m => m.ClientInstanceId == clientInstanceId);
7981
}
80-
}
82+
}

src/ByteSync.ServerCommon/Commands/CloudSessions/CreateSessionCommandHandler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public async Task<CloudSessionResult> Handle(CreateSessionRequest request, Cance
3939
SessionMemberData creatorData;
4040

4141
cloudSessionData = new CloudSessionData(createCloudSessionParameters.LobbyId, createCloudSessionParameters.SessionSettings, client);
42+
cloudSessionData.ProtocolVersion = createCloudSessionParameters.CreatorPublicKeyInfo.ProtocolVersion;
4243
creatorData = new SessionMemberData(client, createCloudSessionParameters.CreatorPublicKeyInfo,
4344
createCloudSessionParameters.CreatorProfileClientId, cloudSessionData,
4445
createCloudSessionParameters.CreatorPrivateData);
@@ -67,4 +68,4 @@ private string GenerateRandomSessionId()
6768

6869
return sessionId;
6970
}
70-
}
71+
}

src/ByteSync.ServerCommon/Commands/Trusts/StartTrustCheckCommandHandler.cs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using ByteSync.Common.Business.Sessions.Cloud.Connections;
2-
using ByteSync.Common.Business.Versions;
32
using ByteSync.ServerCommon.Interfaces.Repositories;
43
using ByteSync.ServerCommon.Interfaces.Services.Clients;
54
using MediatR;
@@ -12,8 +11,8 @@ public class StartTrustCheckCommandHandler : IRequestHandler<StartTrustCheckRequ
1211
private readonly ICloudSessionsRepository _cloudSessionsRepository;
1312
private readonly IInvokeClientsService _invokeClientsService;
1413
private readonly ILogger<StartTrustCheckCommandHandler> _logger;
15-
16-
public StartTrustCheckCommandHandler(ICloudSessionsRepository cloudSessionsRepository, IInvokeClientsService invokeClientsService,
14+
15+
public StartTrustCheckCommandHandler(ICloudSessionsRepository cloudSessionsRepository, IInvokeClientsService invokeClientsService,
1716
ILogger<StartTrustCheckCommandHandler> logger)
1817
{
1918
_cloudSessionsRepository = cloudSessionsRepository;
@@ -31,37 +30,20 @@ public async Task<StartTrustCheckResult> Handle(StartTrustCheckRequest request,
3130
{
3231
return new StartTrustCheckResult { IsOK = false };
3332
}
34-
33+
3534
var joinerProtocolVersion = trustCheckParameters.ProtocolVersion;
35+
var sessionProtocolVersion = cloudSession.ProtocolVersion;
3636

37-
if (!ProtocolVersion.IsCompatible(joinerProtocolVersion))
37+
if (joinerProtocolVersion != sessionProtocolVersion)
3838
{
3939
_logger.LogWarning(
40-
"StartTrustCheck: Joiner {JoinerId} has incompatible protocol version {JoinerVersion}",
41-
joiner.ClientInstanceId, joinerProtocolVersion);
40+
"StartTrustCheck: Joiner {JoinerId} has incompatible protocol version {JoinerVersion} for session {SessionId} (version {SessionVersion})",
41+
joiner.ClientInstanceId, joinerProtocolVersion, trustCheckParameters.SessionId, sessionProtocolVersion);
4242

4343
return new StartTrustCheckResult { IsOK = false, IsProtocolVersionIncompatible = true };
4444
}
4545

46-
var membersToCheck = cloudSession.SessionMembers
47-
.Where(m => trustCheckParameters.MembersInstanceIdsToCheck.Contains(m.ClientInstanceId));
48-
49-
foreach (var member in membersToCheck)
50-
{
51-
var memberProtocolVersion = member.PublicKeyInfo.ProtocolVersion;
52-
53-
if (!ProtocolVersion.IsCompatible(memberProtocolVersion) ||
54-
memberProtocolVersion != joinerProtocolVersion)
55-
{
56-
_logger.LogWarning(
57-
"StartTrustCheck: Protocol version mismatch between joiner {JoinerId} (version {JoinerVersion}) and member {MemberId} (version {MemberVersion})",
58-
joiner.ClientInstanceId, joinerProtocolVersion, member.ClientInstanceId, memberProtocolVersion);
59-
60-
return new StartTrustCheckResult { IsOK = false, IsProtocolVersionIncompatible = true };
61-
}
62-
}
63-
64-
_logger.LogInformation("StartTrustCheck: {Joiner} starts trust check for session {SessionId}. {Count} members to check",
46+
_logger.LogInformation("StartTrustCheck: {Joiner} starts trust check for session {SessionId}. {Count} members to check",
6547
joiner.ClientInstanceId, trustCheckParameters.SessionId, trustCheckParameters.MembersInstanceIdsToCheck.Count);
6648

6749
var validMemberIds = trustCheckParameters.MembersInstanceIdsToCheck
@@ -70,10 +52,11 @@ public async Task<StartTrustCheckResult> Handle(StartTrustCheckRequest request,
7052

7153
foreach (var clientInstanceId in validMemberIds)
7254
{
73-
_logger.LogInformation("StartTrustCheck: {Member} must be trusted by {Joiner}",
55+
_logger.LogInformation("StartTrustCheck: {Member} must be trusted by {Joiner}",
7456
clientInstanceId, joiner.ClientInstanceId);
7557

76-
await _invokeClientsService.Client(clientInstanceId).AskPublicKeyCheckData(trustCheckParameters.SessionId, joiner.ClientInstanceId,
58+
await _invokeClientsService.Client(clientInstanceId).AskPublicKeyCheckData(trustCheckParameters.SessionId,
59+
joiner.ClientInstanceId,
7760
trustCheckParameters.PublicKeyInfo).ConfigureAwait(false);
7861
}
7962

tests/ByteSync.ServerCommon.Tests/Commands/CloudSessions/CreateSessionCommandHandlerTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public async Task Handle_ValidRequest_CreatesSession()
5454
var lobbyId = "lobbyId";
5555
var sessionSettings = new EncryptedSessionSettings();
5656
var client = new Client { ClientInstanceId = "clientInstance1" };
57-
var creatorPublicKeyInfo = new PublicKeyInfo();
57+
var creatorPublicKeyInfo = new PublicKeyInfo { ProtocolVersion = 2 };
5858
var creatorProfileClientId = "creatorProfile";
5959
var creatorPrivateData = new EncryptedSessionMemberPrivateData();
6060
var sessionId = "123ABC456";
@@ -108,6 +108,7 @@ public async Task Handle_ValidRequest_CreatesSession()
108108
addedCloudSession.Should().NotBeNull();
109109
addedCloudSession.LobbyId.Should().Be(lobbyId);
110110
addedCloudSession.SessionSettings.Should().BeSameAs(sessionSettings);
111+
addedCloudSession.ProtocolVersion.Should().Be(creatorPublicKeyInfo.ProtocolVersion);
111112
addedCloudSession.SessionMembers.Should().HaveCount(1);
112113

113114
// Verify session member creation
@@ -136,4 +137,4 @@ public async Task Handle_ValidRequest_CreatesSession()
136137
A<SessionMemberData>.That.Matches(m => m == creatorMemberData)))
137138
.MustHaveHappenedOnceExactly();
138139
}
139-
}
140+
}

tests/ByteSync.ServerCommon.Tests/Commands/Trusts/StartTrustCheckCommandHandlerTests.cs

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class StartTrustCheckCommandHandlerTests
2323
private readonly IHubByteSyncPush _mockHubByteSyncPush;
2424

2525
private readonly StartTrustCheckCommandHandler _startTrustCheckCommandHandler;
26-
26+
2727
public StartTrustCheckCommandHandlerTests()
2828
{
2929
_mockCloudSessionsRepository = A.Fake<ICloudSessionsRepository>();
@@ -32,7 +32,7 @@ public StartTrustCheckCommandHandlerTests()
3232
_mockHubByteSyncPush = A.Fake<IHubByteSyncPush>();
3333

3434
_startTrustCheckCommandHandler = new StartTrustCheckCommandHandler(
35-
_mockCloudSessionsRepository,
35+
_mockCloudSessionsRepository,
3636
_mockInvokeClientsService,
3737
_mockLogger);
3838
}
@@ -57,13 +57,14 @@ public async Task Handle_SessionExists_WithMembers_ReturnsSuccessResult()
5757
};
5858

5959
var cloudSession = new CloudSessionData(sessionId, new EncryptedSessionSettings(), new Client { ClientInstanceId = "member1" });
60-
cloudSession.SessionMembers.Add(new SessionMemberData
61-
{
60+
cloudSession.ProtocolVersion = ProtocolVersion.CURRENT;
61+
cloudSession.SessionMembers.Add(new SessionMemberData
62+
{
6263
ClientInstanceId = member1,
6364
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = ProtocolVersion.CURRENT }
6465
});
65-
cloudSession.SessionMembers.Add(new SessionMemberData
66-
{
66+
cloudSession.SessionMembers.Add(new SessionMemberData
67+
{
6768
ClientInstanceId = member2,
6869
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = ProtocolVersion.CURRENT }
6970
});
@@ -75,7 +76,7 @@ public async Task Handle_SessionExists_WithMembers_ReturnsSuccessResult()
7576
.Returns(_mockHubByteSyncPush);
7677
A.CallTo(() => _mockInvokeClientsService.Client(member2))
7778
.Returns(_mockHubByteSyncPush);
78-
79+
7980
A.CallTo(() => _mockHubByteSyncPush.AskPublicKeyCheckData(sessionId, joinerClient.ClientInstanceId, publicKeyInfo))
8081
.Returns(Task.CompletedTask);
8182

@@ -149,8 +150,9 @@ public async Task Handle_SessionExistsButNoValidMembers_ReturnsEmptySuccessResul
149150
};
150151

151152
var cloudSession = new CloudSessionData(sessionId, new EncryptedSessionSettings(), new Client { ClientInstanceId = "creator" });
152-
cloudSession.SessionMembers.Add(new SessionMemberData
153-
{
153+
cloudSession.ProtocolVersion = ProtocolVersion.CURRENT;
154+
cloudSession.SessionMembers.Add(new SessionMemberData
155+
{
154156
ClientInstanceId = "otherMember",
155157
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = ProtocolVersion.CURRENT }
156158
});
@@ -173,7 +175,7 @@ public async Task Handle_SessionExistsButNoValidMembers_ReturnsEmptySuccessResul
173175
}
174176

175177
[Test]
176-
public async Task Handle_WhenMemberHasIncompatibleProtocolVersion_ReturnsProtocolVersionIncompatible()
178+
public async Task Handle_WhenMemberHasDifferentProtocolVersion_ReturnsSuccess()
177179
{
178180
var sessionId = "testSession";
179181
var joinerClient = new Client { ClientId = "joinerClient", ClientInstanceId = "joinerClientInstance" };
@@ -189,49 +191,58 @@ public async Task Handle_WhenMemberHasIncompatibleProtocolVersion_ReturnsProtoco
189191
};
190192

191193
var cloudSession = new CloudSessionData(sessionId, new EncryptedSessionSettings(), new Client { ClientInstanceId = "creator" });
192-
cloudSession.SessionMembers.Add(new SessionMemberData
193-
{
194+
cloudSession.ProtocolVersion = ProtocolVersion.CURRENT;
195+
cloudSession.SessionMembers.Add(new SessionMemberData
196+
{
194197
ClientInstanceId = member1,
195198
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = 0 }
196199
});
197200

198201
A.CallTo(() => _mockCloudSessionsRepository.Get(sessionId))
199202
.Returns(cloudSession);
200203

204+
A.CallTo(() => _mockInvokeClientsService.Client(member1))
205+
.Returns(_mockHubByteSyncPush);
206+
A.CallTo(() => _mockHubByteSyncPush.AskPublicKeyCheckData(sessionId, joinerClient.ClientInstanceId, publicKeyInfo))
207+
.Returns(Task.CompletedTask);
208+
201209
var request = new StartTrustCheckRequest(parameters, joinerClient);
202210

203211
var result = await _startTrustCheckCommandHandler.Handle(request, CancellationToken.None);
204212

205213
result.Should().NotBeNull();
206-
result.IsOK.Should().BeFalse();
207-
result.IsProtocolVersionIncompatible.Should().BeTrue();
208-
result.MembersInstanceIds.Should().BeEmpty();
214+
result.IsOK.Should().BeTrue();
215+
result.IsProtocolVersionIncompatible.Should().BeFalse();
216+
result.MembersInstanceIds.Should().ContainSingle().Which.Should().Be(member1);
209217

210218
A.CallTo(() => _mockCloudSessionsRepository.Get(sessionId)).MustHaveHappenedOnceExactly();
211-
A.CallTo(() => _mockInvokeClientsService.Client(A<string>.Ignored)).MustNotHaveHappened();
219+
A.CallTo(() => _mockInvokeClientsService.Client(member1)).MustHaveHappenedOnceExactly();
220+
A.CallTo(() => _mockHubByteSyncPush.AskPublicKeyCheckData(sessionId, joinerClient.ClientInstanceId, publicKeyInfo))
221+
.MustHaveHappenedOnceExactly();
212222
}
213223

214224
[Test]
215-
public async Task Handle_WhenJoinerHasIncompatibleProtocolVersion_ReturnsProtocolVersionIncompatible()
225+
public async Task Handle_WhenJoinerProtocolVersionDoesNotMatchSessionProtocolVersion_ReturnsProtocolVersionIncompatible()
216226
{
217227
var sessionId = "testSession";
218228
var joinerClient = new Client { ClientId = "joinerClient", ClientInstanceId = "joinerClientInstance" };
219229
var member1 = "memberInstance1";
220230

221-
var publicKeyInfo = new PublicKeyInfo { ProtocolVersion = 0 };
231+
var publicKeyInfo = new PublicKeyInfo { ProtocolVersion = ProtocolVersion.CURRENT };
222232
var parameters = new TrustCheckParameters
223233
{
224234
SessionId = sessionId,
225235
MembersInstanceIdsToCheck = new List<string> { member1 },
226236
PublicKeyInfo = publicKeyInfo,
227-
ProtocolVersion = 0
237+
ProtocolVersion = ProtocolVersion.CURRENT
228238
};
229239

230240
var cloudSession = new CloudSessionData(sessionId, new EncryptedSessionSettings(), new Client { ClientInstanceId = "creator" });
231-
cloudSession.SessionMembers.Add(new SessionMemberData
232-
{
241+
cloudSession.ProtocolVersion = 0;
242+
cloudSession.SessionMembers.Add(new SessionMemberData
243+
{
233244
ClientInstanceId = member1,
234-
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = ProtocolVersion.CURRENT }
245+
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = 0 }
235246
});
236247

237248
A.CallTo(() => _mockCloudSessionsRepository.Get(sessionId))
@@ -267,8 +278,9 @@ public async Task Handle_WhenJoinerAndMemberHaveCompatibleVersions_ReturnsSucces
267278
};
268279

269280
var cloudSession = new CloudSessionData(sessionId, new EncryptedSessionSettings(), new Client { ClientInstanceId = "creator" });
270-
cloudSession.SessionMembers.Add(new SessionMemberData
271-
{
281+
cloudSession.ProtocolVersion = ProtocolVersion.CURRENT;
282+
cloudSession.SessionMembers.Add(new SessionMemberData
283+
{
272284
ClientInstanceId = member1,
273285
PublicKeyInfo = new PublicKeyInfo { ProtocolVersion = ProtocolVersion.CURRENT }
274286
});

0 commit comments

Comments
 (0)