Skip to content

Commit

Permalink
fix: fixing host authentication using Connected event
Browse files Browse the repository at this point in the history
  • Loading branch information
James-Frowen committed Jun 20, 2023
1 parent 4a3cba9 commit 6bb6bed
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
28 changes: 26 additions & 2 deletions Assets/Mirage/Runtime/Authentication/AuthenticatorSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,19 @@ private bool SkipHost(INetworkPlayer player)

private async UniTask<AuthenticationResult> RunServerAuthenticate(INetworkPlayer player)
{
var taskCompletion = new UniTaskCompletionSource<AuthenticationResult>();
_pending.Add(player, taskCompletion);
UniTaskCompletionSource<AuthenticationResult> taskCompletion;
// host player should be added by PreAddHostPlayer, so we just get item
if (player == _server.LocalPlayer)
{
taskCompletion = _pending[player];
}
// remote player should add new token here
else
{
taskCompletion = new UniTaskCompletionSource<AuthenticationResult>();
_pending.Add(player, taskCompletion);
}


try
{
Expand Down Expand Up @@ -127,6 +138,19 @@ internal void AfterAuth(INetworkPlayer player, AuthenticationResult result)
logger.LogError("Received AfterAuth Callback from player that was not in pending authentication");
}
}

internal void PreAddHostPlayer(INetworkPlayer player)
{
// dont add if host dont require auth
if (!RequireHostToAuthenticate)
return;

// host player is a special case, they are added early
// otherwise Client.Connected can't be used to send auth message
// because that is called before RunServerAuthenticate is called.
var taskCompletion = new UniTaskCompletionSource<AuthenticationResult>();
_pending.Add(player, taskCompletion);
}
}
}

5 changes: 5 additions & 0 deletions Assets/Mirage/Runtime/NetworkServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ internal void AddLocalConnection(NetworkClient client, IConnection connection)
if (logger.LogEnabled()) logger.Log($"Server accepted local client connection: {player}");

_connections[player.Connection] = player;

if (Authenticator != null)
// we need to add host player to auth early, so that Client.Connected, can be used to send auth message
// if we want for server to add it then we will be too late
Authenticator.PreAddHostPlayer(player);
}

public void SendToAll<T>(T msg, bool excludeLocalPlayer, Channel channelId = Channel.Reliable)
Expand Down
46 changes: 46 additions & 0 deletions Assets/Tests/Runtime/Authentication/AuthenticatorHostMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,50 @@ public IEnumerator AuthenticatedOnlyAfterMessage()

}
}

public class AuthenticatorHost_HostRequired_ClientConnect : AuthenticatorHostModeBase
{
public AuthenticatorHost_HostRequired_ClientConnect() : base(true, hostRequireAuth: true)
{
}

protected override void ExtraClientSetup(IClientInstance instance)
{
base.ExtraClientSetup(instance);

instance.Client.Connected.AddListener(ClientConnected);
}

private void ClientConnected(INetworkPlayer arg0)
{
// check that we can send auth when client connects
_auth.SendAuthentication(client, new MockAuthenticator.MockMessage { });
}

[UnityTest]
public IEnumerator AuthenticatesFromMessageSentInConnected()
{
yield return null;
yield return null;

Assert.That(_serverAuthCalls, Has.Count.EqualTo(1));
Assert.That(_serverAuthCalls[0], Is.EqualTo(server.LocalPlayer));

Assert.That(server.LocalPlayer.IsAuthenticated, Is.True);
Assert.That(server.LocalPlayer.Authentication, Is.Not.Null);
Assert.That(server.LocalPlayer.Authentication.Authenticator, Is.TypeOf<MockAuthenticator>());
Assert.That(server.LocalPlayer.Authentication.Data, Is.TypeOf<MockAuthenticator.MockData>());

// client needs extra frame to receive message from server
yield return null;

Assert.That(_clientAuthCalls, Has.Count.EqualTo(1));
Assert.That(_clientAuthCalls[0], Is.EqualTo(client.Player));

Assert.That(client.Player.IsAuthenticated, Is.True);
Assert.That(client.Player.Authentication, Is.Not.Null);
Assert.That(client.Player.Authentication.Authenticator, Is.TypeOf<MockAuthenticator>());

}
}
}

0 comments on commit 6bb6bed

Please sign in to comment.