diff --git a/Controllers/AuthController.cs b/Controllers/AuthController.cs index 3cbb74b..e54da88 100644 --- a/Controllers/AuthController.cs +++ b/Controllers/AuthController.cs @@ -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 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(); } - [HttpGet("start/{qboid}")] - public async Task GetAsync([FromRoute]string qboid) + [HttpGet("start/{state}")] + public async Task 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 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(); var access_token_expires_in = AccessTokenObject["expires_in"].Value(); + + //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);