-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathYouJoinedSessionService.cs
More file actions
161 lines (136 loc) · 7.32 KB
/
YouJoinedSessionService.cs
File metadata and controls
161 lines (136 loc) · 7.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using ByteSync.Business.SessionMembers;
using ByteSync.Business.Sessions;
using ByteSync.Business.Sessions.Connecting;
using ByteSync.Common.Business.Sessions.Cloud.Connections;
using ByteSync.Interfaces.Controls.Applications;
using ByteSync.Interfaces.Controls.Communications;
using ByteSync.Interfaces.Controls.Communications.Http;
using ByteSync.Interfaces.Controls.Encryptions;
using ByteSync.Interfaces.Repositories;
using ByteSync.Interfaces.Services.Sessions;
using ByteSync.Interfaces.Services.Sessions.Connecting;
using ByteSync.Interfaces.Services.Sessions.Connecting.Joining;
using Serilog;
namespace ByteSync.Services.Sessions.Connecting;
public class YouJoinedSessionService : IYouJoinedSessionService
{
private readonly ICloudSessionConnectionRepository _cloudSessionConnectionRepository;
private readonly IEnvironmentService _environmentService;
private readonly IPublicKeysTruster _publicKeysTruster;
private readonly IDigitalSignaturesChecker _digitalSignaturesChecker;
private readonly IDataEncrypter _dataEncrypter;
private readonly ICloudSessionApiClient _cloudSessionApiClient;
private readonly IPublicKeysManager _publicKeysManager;
private readonly ISessionService _sessionService;
private readonly IAfterJoinSessionService _afterJoinSessionService;
private readonly ILogger<YouJoinedSessionService> _logger;
private const string UNKNOWN_RECEIVED_SESSION_ID = "unknown received sessionId {sessionId}";
private const string PUBLIC_KEY_IS_NOT_TRUSTED = "Public key is not trusted";
public YouJoinedSessionService(ICloudSessionConnectionRepository cloudSessionConnectionRepository,
IEnvironmentService environmentService, IPublicKeysTruster publicKeysTruster, IDigitalSignaturesChecker digitalSignaturesChecker,
IDataEncrypter dataEncrypter, ICloudSessionApiClient cloudSessionApiClient, IPublicKeysManager publicKeysManager, ISessionService sessionService,
IAfterJoinSessionService afterJoinSessionService, ILogger<YouJoinedSessionService> logger)
{
_cloudSessionConnectionRepository = cloudSessionConnectionRepository;
_environmentService = environmentService;
_publicKeysTruster = publicKeysTruster;
_digitalSignaturesChecker = digitalSignaturesChecker;
_dataEncrypter = dataEncrypter;
_cloudSessionApiClient = cloudSessionApiClient;
_publicKeysManager = publicKeysManager;
_sessionService = sessionService;
_afterJoinSessionService = afterJoinSessionService;
_logger = logger;
}
public async Task Process(CloudSessionResult cloudSessionResult, ValidateJoinCloudSessionParameters parameters)
{
try
{
if (!await _cloudSessionConnectionRepository.CheckConnectingCloudSession(cloudSessionResult.CloudSession.SessionId))
{
_logger.LogError(UNKNOWN_RECEIVED_SESSION_ID, cloudSessionResult.CloudSession.SessionId);
return;
}
if (!_environmentService.ClientInstanceId.Equals(parameters.JoinerClientInstanceId))
{
_logger.LogWarning("unexpected session event received with JoinerId {joinerId}", parameters.JoinerClientInstanceId);
return;
}
if (_cloudSessionConnectionRepository.CurrentConnectionStatus != SessionConnectionStatus.JoiningSession)
{
_logger.LogWarning("no longer trying to join session");
return;
}
var isAuthOK = false;
var cpt = 0;
while (! isAuthOK)
{
cpt += 1;
if (cpt == 5)
{
_logger.LogWarning($"can not check auth. Too many tries");
return;
}
var sessionMembersClientInstanceIds = await _publicKeysTruster.TrustMissingMembersPublicKeys(cloudSessionResult.CloudSession.SessionId,
_cloudSessionConnectionRepository.CancellationToken);
if (sessionMembersClientInstanceIds == null)
{
_logger.LogWarning($"can not check trust");
return;
}
isAuthOK = await _digitalSignaturesChecker.CheckExistingMembersDigitalSignatures(cloudSessionResult.CloudSession.SessionId,
sessionMembersClientInstanceIds);
if (!isAuthOK)
{
_logger.LogWarning($"can not check auth");
return;
}
var sessionMemberPrivateData = new SessionMemberPrivateData
{
MachineName = _environmentService.MachineName
};
var aesEncryptionKey = _publicKeysManager.DecryptBytes(parameters.EncryptedAesKey);
_cloudSessionConnectionRepository.SetAesEncryptionKey(aesEncryptionKey);
var encryptedSessionMemberPrivateData = _dataEncrypter.EncryptSessionMemberPrivateData(sessionMemberPrivateData);
var finalizeParameters = new FinalizeJoinCloudSessionParameters(parameters, encryptedSessionMemberPrivateData);
var finalizeJoinSessionResult = await _cloudSessionApiClient.FinalizeJoinCloudSession(finalizeParameters,
_cloudSessionConnectionRepository.CancellationToken);
if (finalizeJoinSessionResult.Status == FinalizeJoinSessionStatuses.AuthIsNotChecked)
{
isAuthOK = false;
await Task.Delay(TimeSpan.FromSeconds(1));
}
else if (!finalizeJoinSessionResult.IsOK)
{
_logger.LogWarning($"error during join session finalization");
return;
}
}
try
{
var aesEncryptionKey = _publicKeysManager.DecryptBytes(parameters.EncryptedAesKey);
_cloudSessionConnectionRepository.SetAesEncryptionKey(aesEncryptionKey);
_logger.LogDebug("...EncryptionKey received successfully");
}
catch (Exception ex)
{
_logger.LogError(ex, "...Error during EncryptionKey reception");
throw;
}
var lobbySessionDetails = await _cloudSessionConnectionRepository
.GetTempLobbySessionDetails(cloudSessionResult.CloudSession.SessionId);
await _afterJoinSessionService.Process(
new AfterJoinSessionRequest(cloudSessionResult, lobbySessionDetails, false));
await _cloudSessionConnectionRepository.SetJoinSessionResultReceived(cloudSessionResult.CloudSession.SessionId);
_cloudSessionConnectionRepository.SetConnectionStatus(SessionConnectionStatus.InSession);
// ReSharper disable once PossibleNullReferenceException
Log.Information("JoinSession: {CloudSession}", cloudSessionResult.SessionId);
}
catch (Exception ex)
{
Log.Error(ex, "OnYouJoinedSession");
_sessionService.ClearCloudSession();
_cloudSessionConnectionRepository.SetConnectionStatus(SessionConnectionStatus.NoSession);
}
}
}