mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 23:12:56 +08:00
Add APIAccess
flow for 2fa
This commit is contained in:
parent
c4e461ba44
commit
0e4244a692
@ -48,6 +48,8 @@ namespace osu.Game.Online.API
|
||||
|
||||
public string ProvidedUsername { get; private set; }
|
||||
|
||||
public string SecondFactorCode { get; private set; }
|
||||
|
||||
private string password;
|
||||
|
||||
public IBindable<APIUser> LocalUser => localUser;
|
||||
@ -183,6 +185,7 @@ namespace osu.Game.Online.API
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method takes control of <see cref="state"/> and transitions from <see cref="APIState.Connecting"/> to either
|
||||
/// - <see cref="APIState.RequiresSecondFactorAuth"/> (pending 2fa)
|
||||
/// - <see cref="APIState.Online"/> (successful connection)
|
||||
/// - <see cref="APIState.Failing"/> (failed connection but retrying)
|
||||
/// - <see cref="APIState.Offline"/> (failed and can't retry, clear credentials and require user interaction)
|
||||
@ -190,8 +193,6 @@ namespace osu.Game.Online.API
|
||||
/// <returns>Whether the connection attempt was successful.</returns>
|
||||
private void attemptConnect()
|
||||
{
|
||||
state.Value = APIState.Connecting;
|
||||
|
||||
if (localUser.IsDefault)
|
||||
{
|
||||
// Show a placeholder user if saved credentials are available.
|
||||
@ -208,11 +209,14 @@ namespace osu.Game.Online.API
|
||||
|
||||
if (!authentication.HasValidAccessToken)
|
||||
{
|
||||
state.Value = APIState.Connecting;
|
||||
LastLoginError = null;
|
||||
|
||||
try
|
||||
{
|
||||
authentication.AuthenticateWithLogin(ProvidedUsername, password);
|
||||
state.Value = APIState.RequiresSecondFactorAuth;
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -225,6 +229,28 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
}
|
||||
|
||||
if (state.Value == APIState.RequiresSecondFactorAuth)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SecondFactorCode))
|
||||
return;
|
||||
|
||||
state.Value = APIState.Connecting;
|
||||
LastLoginError = null;
|
||||
|
||||
// TODO: use code to ensure second factor authentication completed.
|
||||
Thread.Sleep(1000);
|
||||
bool success = SecondFactorCode == "00000000";
|
||||
SecondFactorCode = null;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
state.Value = APIState.RequiresSecondFactorAuth;
|
||||
LastLoginError = new InvalidOperationException("Second factor auth failed");
|
||||
SecondFactorCode = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var userReq = new GetUserRequest();
|
||||
userReq.Failure += ex =>
|
||||
{
|
||||
@ -307,6 +333,13 @@ namespace osu.Game.Online.API
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void AuthenticateSecondFactor(string code)
|
||||
{
|
||||
Debug.Assert(State.Value == APIState.RequiresSecondFactorAuth);
|
||||
|
||||
SecondFactorCode = code;
|
||||
}
|
||||
|
||||
public IHubClientConnector GetHubConnector(string clientName, string endpoint, bool preferMessagePack) =>
|
||||
new HubClientConnector(clientName, endpoint, this, versionHash, preferMessagePack);
|
||||
|
||||
@ -493,6 +526,7 @@ namespace osu.Game.Online.API
|
||||
public void Logout()
|
||||
{
|
||||
password = null;
|
||||
SecondFactorCode = null;
|
||||
authentication.Clear();
|
||||
|
||||
// Scheduled prior to state change such that the state changed event is invoked with the correct user and their friends present
|
||||
@ -543,7 +577,7 @@ namespace osu.Game.Online.API
|
||||
/// <summary>
|
||||
/// Waiting on second factor authentication.
|
||||
/// </summary>
|
||||
RequiresAuthentication,
|
||||
RequiresSecondFactorAuth,
|
||||
|
||||
/// <summary>
|
||||
/// We are in the process of (re-)connecting.
|
||||
|
@ -118,13 +118,18 @@ namespace osu.Game.Online.API
|
||||
|
||||
if (requiresTwoFactor)
|
||||
{
|
||||
state.Value = APIState.RequiresAuthentication;
|
||||
state.Value = APIState.RequiresSecondFactorAuth;
|
||||
requiresTwoFactor = false;
|
||||
}
|
||||
else
|
||||
state.Value = APIState.Online;
|
||||
}
|
||||
|
||||
public void AuthenticateSecondFactor(string code)
|
||||
{
|
||||
state.Value = APIState.Online;
|
||||
}
|
||||
|
||||
public void Logout()
|
||||
{
|
||||
state.Value = APIState.Offline;
|
||||
|
@ -106,6 +106,12 @@ namespace osu.Game.Online.API
|
||||
/// <param name="password">The user's password.</param>
|
||||
void Login(string username, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Provide a second-factor authentication code for authentication.
|
||||
/// </summary>
|
||||
/// <param name="code">The 2FA code.</param>
|
||||
void AuthenticateSecondFactor(string code);
|
||||
|
||||
/// <summary>
|
||||
/// Log out the current user.
|
||||
/// </summary>
|
||||
|
@ -81,7 +81,7 @@ namespace osu.Game.Overlays.Login
|
||||
};
|
||||
break;
|
||||
|
||||
case APIState.RequiresAuthentication:
|
||||
case APIState.RequiresSecondFactorAuth:
|
||||
Child = form = new AccountVerificationForm();
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user