-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathPrivateWorldAccessHandler.cs
More file actions
96 lines (85 loc) · 3.91 KB
/
Copy pathPrivateWorldAccessHandler.cs
File metadata and controls
96 lines (85 loc) · 3.91 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
using Cysharp.Threading.Tasks;
using DCL.Diagnostics;
using DCL.PrivateWorlds.UI;
using ECS;
using MVC;
using System;
using System.Threading;
namespace DCL.PrivateWorlds
{
/// <summary>
/// Implements IWorldAccessGate: runs permission check, shows popup when needed,
/// validates password with retry loop.
/// </summary>
public class PrivateWorldAccessHandler : IWorldAccessGate
{
private readonly IWorldPermissionsService worldPermissionsService;
private readonly IMVCManager mvcManager;
private readonly IRealmData realmData;
public PrivateWorldAccessHandler(
IWorldPermissionsService worldPermissionsService,
IMVCManager mvcManager,
IRealmData realmData)
{
this.worldPermissionsService = worldPermissionsService;
this.mvcManager = mvcManager;
this.realmData = realmData;
}
public async UniTask<WorldAccessResult> CheckAccessAsync(string worldName, string? ownerAddress, CancellationToken ct)
{
ReportHub.Log(ReportCategory.REALM, $"[PrivateWorldAccessHandler] Checking access for '{worldName}'");
try
{
var context = await worldPermissionsService.CheckWorldAccessAsync(worldName, ct);
return context.Result switch
{
WorldAccessCheckResult.Allowed => HandleAllowed(),
WorldAccessCheckResult.CheckFailed => WorldAccessResult.CheckFailed,
WorldAccessCheckResult.AccessDenied => await ShowAccessDeniedAsync(worldName, context.AccessInfo?.OwnerAddress ?? ownerAddress, ct),
WorldAccessCheckResult.PasswordRequired => await HandlePasswordRequiredAsync(worldName, context.AccessInfo?.OwnerAddress ?? ownerAddress, ct),
_ => WorldAccessResult.CheckFailed,
};
}
catch (OperationCanceledException)
{
throw; // Let the caller (RealmNavigator) distinguish timeout vs user cancellation
}
catch (Exception ex)
{
ReportHub.LogException(ex, ReportCategory.REALM);
return WorldAccessResult.CheckFailed;
}
}
private async UniTask<WorldAccessResult> ShowAccessDeniedAsync(string worldName, string? ownerAddress, CancellationToken ct)
{
try
{
var popupParams = new PrivateWorldPopupParams(worldName, PrivateWorldPopupMode.AccessDenied, ownerAddress);
await mvcManager.ShowAsync(PrivateWorldPopupController.IssueCommand(popupParams), ct);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
ReportHub.LogException(ex, ReportCategory.REALM);
}
return WorldAccessResult.Denied;
}
private WorldAccessResult HandleAllowed()
{
realmData.WorldCommsSecret = string.Empty;
return WorldAccessResult.Allowed;
}
private async UniTask<WorldAccessResult> HandlePasswordRequiredAsync(string worldName, string? ownerAddress, CancellationToken ct)
{
var popupParams = new PrivateWorldPopupParams(worldName, PrivateWorldPopupMode.PasswordRequired, ownerAddress);
await mvcManager.ShowAsync(PrivateWorldPopupController.IssueCommand(popupParams), ct);
if (popupParams.Result == PrivateWorldPopupResult.PasswordSubmitted)
{
realmData.WorldCommsSecret = popupParams.EnteredPassword ?? string.Empty;
ReportHub.Log(ReportCategory.REALM, $"[PrivateWorldAccessHandler] Password validated for '{worldName}', secret stored (length={popupParams.EnteredPassword?.Length ?? 0})");
return WorldAccessResult.Allowed;
}
return WorldAccessResult.PasswordCancelled;
}
}
}