This commit is contained in:
2019-10-02 00:08:33 +00:00
parent 98971b58b9
commit 82ed32a52f

View File

@@ -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);