/// <summary> /// Takes an OAuth code and turns it into an API token. /// </summary> /// <param name="code">A code returned from the OAuth page (https://quizlet.com/authorize/)</param> /// <param name="success">A delegate to be called when the authentication succeeds.</param> /// <param name="failure">What to do when the authentication fails.</param> /// <param name="token">A CancellationToken, which is currently useless.</param> public void Authenticate(string code, Action success, Action<Exception> failure, CancellationToken token) { var fields = "grant_type=authorization_code&code=" + code + "&redirect_uri=https://q.asztal.net/"; var req = new HttpsRequest("POST", "/oauth/token"); req.BasicAuthorization(ClientID, SecretKey); req.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; req.PostData = Encoding.UTF8.GetBytes(fields); FetchJSON(req, json => { try { if (json is JsonDictionary) { var ctx = new JsonContext(); var accessToken = ctx.FromJson<string>((json as JsonDictionary).Items["access_token"]); var userName = ctx.FromJson<string>((json as JsonDictionary).Items["user_id"]); var tokenExpiry = DateTime.Now.AddSeconds(ctx.FromJson<double>((json as JsonDictionary).Items["expires_in"])); Credentials = new Credentials(accessToken, userName, tokenExpiry); success(); } else { failure(new FormatException("Quizlet server returned an invalid response.")); } } catch (KeyNotFoundException) { failure(new FormatException("Quizlet server returned an invalid response.")); } catch (JsonConvertException) { failure(new FormatException("Quizlet server returned an invalid response.")); } }, failure, token); }