This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
@@ -24,6 +25,8 @@ namespace qbridge.Controllers
|
||||
|
||||
public const string DISCOVERY_DOCUMENT_URL = "https://developer.api.intuit.com/.well-known/openid_sandbox_configuration";
|
||||
|
||||
public static Dictionary<string, QBToken> TOKEN_STORE = null;
|
||||
|
||||
//current 2019 fall disco doc urls
|
||||
//Sandbox: https://developer.api.intuit.com/.well-known/openid_sandbox_configuration
|
||||
//Production: https://developer.api.intuit.com/.well-known/openid_configuration
|
||||
@@ -66,20 +69,25 @@ namespace qbridge.Controllers
|
||||
public OAuthRedirectController(IHttpClientFactory clientFactory)
|
||||
{
|
||||
_clientFactory = clientFactory;
|
||||
TOKEN_STORE = new Dictionary<string, QBToken>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpGet("start/{qboid}")]
|
||||
public async Task<IActionResult> GetAsync([FromRoute]string qboid)
|
||||
[HttpGet("start/{state}")]
|
||||
public async Task<IActionResult> GetAsync([FromRoute]string state)
|
||||
{
|
||||
|
||||
if (string.IsNullOrWhiteSpace(qboid))
|
||||
if (string.IsNullOrWhiteSpace(state))
|
||||
{
|
||||
return BadRequest("QBOID value is required");
|
||||
return BadRequest("state value is required");
|
||||
}
|
||||
|
||||
//Job one is to clean out the old entries in the token store if necessary
|
||||
//rather than bothering with some kind of recurring task just do it on every fetch for now
|
||||
SweepTokenStore();
|
||||
|
||||
//GET THE DISCOVERY DOCUMENT
|
||||
//Discovery document contains the actual current endpoints to use for various ops
|
||||
await GetQBDiscoveryDocument();
|
||||
@@ -106,7 +114,7 @@ namespace qbridge.Controllers
|
||||
{"scope", "com.intuit.quickbooks.accounting" },
|
||||
{"redirect_uri",REDIRECT_URI },
|
||||
{"response_type","code"},
|
||||
{"state",qboid}
|
||||
{"state",state}
|
||||
};
|
||||
|
||||
url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(AuthorizationEndpoint, queryParams);
|
||||
@@ -122,7 +130,7 @@ namespace qbridge.Controllers
|
||||
}
|
||||
|
||||
|
||||
// Redirect endpoint
|
||||
// Redirect endpoint, this is used by the Intuit auth server to redirect back to with the good stuff
|
||||
//Step 4 here: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/openid-connect
|
||||
[HttpGet("redirect")]
|
||||
public async Task<IActionResult> GetAsync([FromQuery] string state, [FromQuery]string code, [FromQuery]string realmId)
|
||||
@@ -184,6 +192,13 @@ namespace qbridge.Controllers
|
||||
var x_refresh_token_expires_in = AccessTokenObject["x_refresh_token_expires_in"].Value<long>();
|
||||
var access_token_expires_in = AccessTokenObject["expires_in"].Value<long>();
|
||||
|
||||
|
||||
//TODO: Instead of returning the token here, store it in memory so QBOI can fetch it via the session id token in the "state" variable here
|
||||
//return instead that user is successfully logged in and QBOI is ready to access
|
||||
|
||||
//Store the token!!
|
||||
TOKEN_STORE.Add(state,new QBToken(){realmId=realmId,access_token=access_token,refresh_token=refresh_token,TokenBirthday=DateTime.Now});
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
access_token = access_token,
|
||||
@@ -210,6 +225,54 @@ namespace qbridge.Controllers
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//examine stored tokens, if matching one found then return it and erase from the list?
|
||||
[HttpGet("fetch/{state}")]
|
||||
public IActionResult FetchTokenAsync([FromRoute]string state)
|
||||
{
|
||||
|
||||
if (string.IsNullOrWhiteSpace(state))
|
||||
{
|
||||
return BadRequest("state value is required");
|
||||
}
|
||||
|
||||
return Ok();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class QBToken
|
||||
{
|
||||
public string realmId { get; set; }
|
||||
public string access_token { get; set; }
|
||||
public string refresh_token { get; set; }
|
||||
public DateTime TokenBirthday { get; set; }
|
||||
|
||||
}
|
||||
|
||||
//Remove stale tokens
|
||||
public static void SweepTokenStore()
|
||||
{
|
||||
//ditch tokens older than 7 days
|
||||
//this works because our system in place is intended to be re-authed every session
|
||||
DateTime dtExpireAfter=DateTime.Now.AddDays(-7);
|
||||
//if the token birthday is newer than 7 days ago then select it to remain
|
||||
TOKEN_STORE = TOKEN_STORE.Where(pair => pair.Value.TokenBirthday < dtExpireAfter)
|
||||
.ToDictionary(pair => pair.Key,
|
||||
pair => pair.Value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static string Base64Encode(string plainText)
|
||||
{
|
||||
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
|
||||
|
||||
Reference in New Issue
Block a user