public async Task AuthenticateForLimitedPublicAsync(bool forCartManagement) { if (forCartManagement && string.IsNullOrEmpty(SessionToken)) { var sessionTokenUri = Billboard.GetSessionTokenUri(); var sessionTokenResponse = await GetAsync <SessionToken>(sessionTokenUri).ConfigureAwait(false); if (sessionTokenResponse != null) { SessionToken = sessionTokenResponse.session_token; } } var billboard = await Billboard.GetResourceAccessAsync(this).ConfigureAwait(false); var tokenUri = FormLimitedPublicTokenUri(billboard); var log = BeginLog("POST", tokenUri); var response = await PostLimitedPublicTokenRequestAsync(tokenUri).ConfigureAwait(false); LogResponse(log, response); await ThrowIfFailAsync(response, log).ConfigureAwait(false); EndLog(log, String.Empty); await SetTokensAsync(response).ConfigureAwait(false); }
private async Task <HttpResponseMessage> RetryIfTokenExpired(Func <Task <HttpResponseMessage> > req) { // BEWARE: Don't call any higher-level Get or Post here which might themselves do a retry. var response = await req().ConfigureAwait(false); if (response.StatusCode != HttpStatusCode.Unauthorized || _httpClient.DefaultRequestHeaders.Authorization == null || string.IsNullOrEmpty(RefreshToken)) { return(response); } // perhaps bearer token is expired var billboard = await Billboard.GetResourceAccessAsync(this).ConfigureAwait(false); if (SessionToken == null) { // since no session token is involved, try to use refresh token to get new bearer token var refreshUri = Billboard.ResolveTemplate(billboard.Token.Uri, Billboard.Templates.RefreshTokenQuery, new { client_id = ApiKey, refresh_token = RefreshToken }); _httpClient.DefaultRequestHeaders.Authorization = null; response = await _httpClient.PostAsync(refreshUri, null).ConfigureAwait(false); if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Unauthorized) { return(response); } if (response.StatusCode == HttpStatusCode.Unauthorized) { // refresh token might be expired; start over response = await PostLimitedPublicTokenRequestAsync(FormLimitedPublicTokenUri(billboard)).ConfigureAwait(false); if (response.StatusCode != HttpStatusCode.OK) { return(response); } } } else { // todo: when we implement shopper authentication, if we have a shopper, this needs to be the shopper token request, not limited public // if used a session token to get bearer token, unfortunately refresh token is doo doo // start over with existing session token if have one if (!string.IsNullOrEmpty(SessionToken)) { response = await PostLimitedPublicTokenRequestAsync(FormLimitedPublicTokenUri(billboard)).ConfigureAwait(false); } if (response.StatusCode == HttpStatusCode.Unauthorized) { // perhaps session token is expired; need to get a new session token // our thoughts and prayers go out to the poor shopper who is now going to lose their cart contents var sessionTokenUri = Billboard.GetSessionTokenUri(); var json = await GetStringAsync(sessionTokenUri, true /*no retry!*/).ConfigureAwait(false); if (!string.IsNullOrEmpty(json)) { var sessionTokenResponse = JsonConvert.DeserializeObject <SessionToken>(json); if (sessionTokenResponse != null) { SessionToken = sessionTokenResponse.session_token; } } response = await PostLimitedPublicTokenRequestAsync(FormLimitedPublicTokenUri(billboard)).ConfigureAwait(false); if (response.StatusCode != HttpStatusCode.OK) { return(response); } } } // whew!!! we got reauthorized await SetTokensAsync(response).ConfigureAwait(false); // replay request return(await req().ConfigureAwait(false)); }