public void EnsureAuthUriIncludesVersion() { var flow = new OAuthUserFlow("id", "secret", MusicClientCommand.DefaultSecureBaseApiUri + MusicClientCommand.DefaultApiVersion, null); var uri = flow.ConstructAuthorizeUri(Scope.ReadUserPlayHistory); Assert.AreEqual("https://sapi.mixrad.io/1.x/authorize/?response_type=code&client_id=id&scope=read_userplayhistory", uri.ToString(), "Expected a matching uri"); }
public async Task EnsureBasicCreationInOrder() { var flow = new OAuthUserFlow("id", "secret", null); Assert.AreEqual(false, flow.IsBusy, "Expected a false result"); Assert.AreEqual(false, flow.TokenCallInProgress, "Expected a false result"); flow.TokenCallInProgress = true; Assert.AreEqual(true, flow.TokenCallInProgress, "Expected a true result"); }
public void EnsureBasicCreationInOrder() { var flow = new OAuthUserFlow("id", "secret", MusicClientCommand.DefaultSecureBaseApiUri + MusicClientCommand.DefaultApiVersion, null); Assert.AreEqual(false, flow.IsBusy, "Expected a false result"); Assert.AreEqual(false, flow.TokenCallInProgress, "Expected a false result"); flow.TokenCallInProgress = true; Assert.AreEqual(true, flow.TokenCallInProgress, "Expected a true result"); Assert.IsNull(flow.TokenResponse, "Expected null token"); }
/// <summary> /// Authenticates a user to enable the user data APIs. /// </summary> /// <param name="clientSecret">The client secret obtained during app registration</param> /// <param name="scopes">The scopes requested.</param> /// <param name="oauthRedirectUri">The OAuth completed URI.</param> /// <returns> /// An AuthResultCode value indicating the result /// </returns> /// <remarks> /// Sorry, this method is messy due to the platform differences! /// </remarks> public async Task <AuthResultCode> AuthenticateUserAsync(string clientSecret, Scope scopes, string oauthRedirectUri = MusicClient.DefaultOAuthRedirectUri) { if (string.IsNullOrEmpty(oauthRedirectUri)) { throw new ArgumentNullException("oauthRedirectUri", "You must supply your OAuth Redirect URI to allow user interaction"); } #endif if (string.IsNullOrEmpty(clientSecret)) { throw new ArgumentNullException("clientSecret", "You must supply your app client secret obtained during app registration"); } if (this._oauthFlowController != null && this._oauthFlowController.IsBusy) { throw new InvalidOperationException("An authentication call is in progress already"); } // See if we have a cached token... AuthResultCode cachedResult = await this.AuthenticateUserAsync(clientSecret); if (cachedResult == AuthResultCode.Success) { return(cachedResult); } var cmd = this.CreateCommand <GetAuthTokenCommand>(); this.SetupSecureCommand(cmd); this._oauthFlowController = new OAuthUserFlow(this.ClientId, clientSecret, cmd); #if WINDOWS_PHONE Response <AuthResultCode> response = await this._oauthFlowController.AuthenticateUserAsync(this.SecureBaseApiUri, scopes, browser, cancellationToken); #elif NETFX_CORE Response <AuthResultCode> response = await this._oauthFlowController.AuthenticateUserAsync(new Uri(oauthRedirectUri), this.SecureBaseApiUri, scopes); #endif await this.StoreOAuthToken(this._oauthFlowController.TokenResponse, clientSecret); this._oauthFlowController = null; if (response.Error != null) { throw response.Error; } else { return(response.Result); } }
/// <summary> /// Attempts a silent authentication a user to enable the user data APIs using a cached access token. /// </summary> /// <param name="clientSecret">The client secret obtained during app registration</param> /// <returns> /// An AuthResultCode indicating the result /// </returns> /// <remarks> /// This overload of AuthenticateUserAsync can only be used once the user has gone through the OAuth flow and given permission to access their data. /// </remarks> public async Task <AuthResultCode> AuthenticateUserAsync(string clientSecret) { if (this.IsUserAuthenticated) { return(AuthResultCode.Success); } var cmd = this.CreateCommand <GetAuthTokenCommand>(); this.SetupSecureCommand(cmd); // Attempt to load a cached token... string cachedToken = await StorageHelper.ReadTextAsync(TokenCacheFile); if (!string.IsNullOrEmpty(cachedToken)) { #if NETFX_CORE // Encrypt to stop prying eyes on Win8 string decodedJson = EncryptionHelper.Decrypt(cachedToken, clientSecret, this.ClientId); #else string decodedJson = cachedToken; #endif this._oauthToken = TokenResponse.FromJToken(JToken.Parse(decodedJson)); this.ExtractTokenProperties(); // Check expiry... if (!this.IsUserTokenActive) { if (this._oauthFlowController != null && this._oauthFlowController.IsBusy) { throw new InvalidOperationException("An authentication call is in progress already"); } // expired -> need to Refresh and cache this._oauthFlowController = new OAuthUserFlow(this.ClientId, clientSecret, cmd); Response <AuthResultCode> response = await this._oauthFlowController.ObtainToken(null, this._oauthToken.RefreshToken, AuthResultCode.Unknown); if (response.Result == AuthResultCode.Success && this._oauthFlowController.TokenResponse != null) { await this.StoreOAuthToken(this._oauthFlowController.TokenResponse, clientSecret); } else { // Failed to refresh the token - remove the cached token in case it's causing problems... await StorageHelper.DeleteFileAsync(TokenCacheFile); response = new Response <AuthResultCode>(null, AuthResultCode.FailedToRefresh, Guid.Empty); } this._oauthFlowController = null; if (response.Error != null) { throw response.Error; } else { return(response.Result); } } else { return(AuthResultCode.Success); } } return(AuthResultCode.NoCachedToken); }