Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OAuth token not saving often enough #2387

Merged
merged 2 commits into from Apr 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 6 additions & 11 deletions osu.Game/Online/API/APIAccess.cs
Expand Up @@ -37,13 +37,7 @@ public class APIAccess : Component, IAPIProvider

public Bindable<User> LocalUser { get; } = new Bindable<User>(createGuestUser());

public string Token
{
get { return authentication.Token?.ToString(); }
set { authentication.Token = string.IsNullOrEmpty(value) ? null : OAuthToken.Parse(value); }
}

protected bool HasLogin => Token != null || !string.IsNullOrEmpty(ProvidedUsername) && !string.IsNullOrEmpty(password);
protected bool HasLogin => authentication.Token.Value != null || !string.IsNullOrEmpty(ProvidedUsername) && !string.IsNullOrEmpty(password);

private readonly CancellationTokenSource cancellationToken = new CancellationTokenSource();

Expand All @@ -57,11 +51,15 @@ public APIAccess(OsuConfigManager config)
log = Logger.GetLogger(LoggingTarget.Network);

ProvidedUsername = config.Get<string>(OsuSetting.Username);
Token = config.Get<string>(OsuSetting.Token);

authentication.TokenString = config.Get<string>(OsuSetting.Token);
authentication.Token.ValueChanged += onTokenChanged;

Task.Factory.StartNew(run, cancellationToken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}

private void onTokenChanged(OAuthToken token) => config.Set(OsuSetting.Token, config.Get<bool>(OsuSetting.SavePassword) ? authentication.TokenString : string.Empty);

private readonly List<IOnlineComponent> components = new List<IOnlineComponent>();

internal new void Schedule(Action action) => base.Schedule(action);
Expand Down Expand Up @@ -306,9 +304,6 @@ protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);

config.Set(OsuSetting.Token, config.Get<bool>(OsuSetting.SavePassword) ? Token : string.Empty);
config.Save();

flushQueue();
cancellationToken.Cancel();
}
Expand Down
25 changes: 16 additions & 9 deletions osu.Game/Online/API/OAuth.cs
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using System.Diagnostics;
using osu.Framework.Configuration;
using osu.Framework.IO.Network;

namespace osu.Game.Online.API
Expand All @@ -12,7 +13,13 @@ public class OAuth
private readonly string clientSecret;
private readonly string endpoint;

public OAuthToken Token;
public readonly Bindable<OAuthToken> Token = new Bindable<OAuthToken>();

public string TokenString
{
get => Token.Value?.ToString();
set => Token.Value = string.IsNullOrEmpty(value) ? null : OAuthToken.Parse(value);
}

internal OAuth(string clientId, string clientSecret, string endpoint)
{
Expand Down Expand Up @@ -47,7 +54,7 @@ internal bool AuthenticateWithLogin(string username, string password)
return false;
}

Token = req.ResponseObject;
Token.Value = req.ResponseObject;
return true;
}
}
Expand All @@ -66,14 +73,14 @@ internal bool AuthenticateWithRefresh(string refresh)
{
req.Perform();

Token = req.ResponseObject;
Token.Value = req.ResponseObject;
return true;
}
}
catch
{
//todo: potentially only kill the refresh token on certain exception types.
Token = null;
Token.Value = null;
return false;
}
}
Expand All @@ -95,28 +102,28 @@ private bool ensureAccessToken()
if (accessTokenValid) return true;

// if not, let's try using our refresh token to request a new access token.
if (!string.IsNullOrEmpty(Token?.RefreshToken))
if (!string.IsNullOrEmpty(Token.Value?.RefreshToken))
// ReSharper disable once PossibleNullReferenceException
AuthenticateWithRefresh(Token.RefreshToken);
AuthenticateWithRefresh(Token.Value.RefreshToken);

return accessTokenValid;
}
}

private bool accessTokenValid => Token?.IsValid ?? false;
private bool accessTokenValid => Token.Value?.IsValid ?? false;

internal bool HasValidAccessToken => RequestAccessToken() != null;

internal string RequestAccessToken()
{
if (!ensureAccessToken()) return null;

return Token.AccessToken;
return Token.Value.AccessToken;
}

internal void Clear()
{
Token = null;
Token.Value = null;
}

private class AccessTokenRequestRefresh : AccessTokenRequest
Expand Down