Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions QuickBooksSharp/Authentication/AuthenticationService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Flurl;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net.Http;
Expand All @@ -10,7 +11,8 @@ namespace QuickBooksSharp
{
public class AuthenticationService : IAuthenticationService
{
private readonly QuickBooksHttpClient _client = new QuickBooksHttpClient(null, null, new NoRetryRunPolicy());
private readonly QuickBooksHttpClient _client = new QuickBooksHttpClient(null, null, new NoRetryRunPolicy(), null);
private readonly ILogger? _logger;

//TODO: retrieve the endpoints URLs dynamically
//See https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-openid-discovery-doc
Expand All @@ -20,6 +22,12 @@ public class AuthenticationService : IAuthenticationService
private const string USER_INFO_ENDPOINT_URL = "https://accounts.platform.intuit.com/v1/openid_connect/userinfo";
private const string USER_INFO_ENDPOINT_SANDBOX_URL = "https://sandbox-accounts.platform.intuit.com/v1/openid_connect/userinfo";

public AuthenticationService(ILogger? logger = null)
{
_logger = logger;
_client = new QuickBooksHttpClient(null, null, new NoRetryRunPolicy(), logger);
}

public string GenerateAuthorizationPromptUrl(string clientId, IEnumerable<string> scopes, string redirectUrl, string state)
{
return new Url("https://appcenter.intuit.com/connect/oauth2")
Expand All @@ -33,7 +41,7 @@ public string GenerateAuthorizationPromptUrl(string clientId, IEnumerable<string

public async Task<UserInfo> GetUserInfo(string accessToken, bool useSandbox)
{
return await new QuickBooksHttpClient(accessToken, null, RunPolicy.DefaultRunPolicy).GetAsync<UserInfo>(useSandbox ? USER_INFO_ENDPOINT_SANDBOX_URL : USER_INFO_ENDPOINT_URL);
return await new QuickBooksHttpClient(accessToken, null, RunPolicy.DefaultRunPolicy, _logger).GetAsync<UserInfo>(useSandbox ? USER_INFO_ENDPOINT_SANDBOX_URL : USER_INFO_ENDPOINT_URL);
}

public async Task<TokenResponse> GetOAuthTokenAsync(string clientId, string clientSecret, string code, string redirectUrl)
Expand Down
38 changes: 37 additions & 1 deletion QuickBooksSharp/Infrastructure/QuickBooksHttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Flurl;
using Microsoft.Extensions.Logging;
using System;
using System.Net;
using System.Net.Http;
Expand All @@ -16,6 +17,7 @@ public class QuickBooksHttpClient : IQuickBooksHttpClient
private readonly string? _accessToken;
private readonly long? _realmId;
private IRunPolicy _runPolicy;
private ILogger? _logger;

private static HttpClient _httpClient = new HttpClient(new HttpClientHandler
{
Expand Down Expand Up @@ -43,11 +45,12 @@ static QuickBooksHttpClient()
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}

public QuickBooksHttpClient(string? accessToken, long? realmId, IRunPolicy runPolicy)
public QuickBooksHttpClient(string? accessToken, long? realmId, IRunPolicy runPolicy, ILogger? logger)
{
_accessToken = accessToken;
_realmId = realmId;
_runPolicy = runPolicy;
_logger = logger;
}

public async Task<TResponse> GetAsync<TResponse>(Url url)
Expand Down Expand Up @@ -80,7 +83,40 @@ public async Task<HttpResponseMessage> SendAsync(Func<HttpRequestMessage> makeRe
if (_accessToken != null)
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

Guid requestGuid = Guid.NewGuid();

if (_logger != null)
{
string requestString = string.Empty;
if (request.Content != null)
{
await request.Content.LoadIntoBufferAsync(); //Ensure content is buffered for logging in case of retries
requestString = await request.Content.ReadAsStringAsync();
}
_logger?.LogDebug(100, "Sending request {requestGuid} to {RequestUrl} with body {RequestBody} and headers {RequestHeaders}",
requestGuid,
request.RequestUri,
requestString,
request.Headers);
}

var response = await _httpClient.SendAsync(request);

if (_logger != null)
{
string responseString = string.Empty;
if (response.Content != null)
{
await response.Content.LoadIntoBufferAsync(); //Ensure content is buffered for logging in case of retries
responseString = await response.Content.ReadAsStringAsync();
}
_logger?.LogDebug(101, "Received response {StatusCode} for request {requestGuid} with body {ResponseBody} and headers {ResponseHeaders}",
response.StatusCode,
requestGuid,
responseString,
response.Headers);
}

var ex = response.IsSuccessStatusCode ? null : new QuickBooksException(request, response, await response.Content.ReadAsStringAsync());

if (ex?.IsRateLimit == true)
Expand Down
1 change: 1 addition & 0 deletions QuickBooksSharp/QuickBooksSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<ItemGroup>
<PackageReference Include="Flurl" Version="3.0.1" />
<PackageReference Include="Macross.Json.Extensions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.10" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
<PackageReference Include="System.Reactive" Version="6.0.0" />
</ItemGroup>
Expand Down
5 changes: 3 additions & 2 deletions QuickBooksSharp/Services/DataService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Flurl;
using Microsoft.Extensions.Logging;
using QuickBooksSharp.Entities;
using System;
using System.Collections.Generic;
Expand All @@ -16,9 +17,9 @@ public class DataService : IDataService

protected readonly Url _serviceUrl;

public DataService(string accessToken, long realmId, bool useSandbox, IRunPolicy? runPolicy = null)
public DataService(string accessToken, long realmId, bool useSandbox, IRunPolicy? runPolicy = null, ILogger? logger = null)
{
_client = new QuickBooksHttpClient(accessToken, realmId, runPolicy ?? RunPolicy.DefaultRunPolicy);
_client = new QuickBooksHttpClient(accessToken, realmId, runPolicy ?? RunPolicy.DefaultRunPolicy, logger);
_serviceUrl = QuickBooksUrl.Build(useSandbox, realmId);
}

Expand Down