public async Task <DiscordToken> GetTokenAsync(string returnUrl, string code, string state) { if (Oauth2State.Matches(state)) { var request = new HttpRequestMessage() { RequestUri = new Uri($"{Http.BaseAddress}oauth2/token"), Method = HttpMethod.Post }; request.Content = new FormUrlEncodedContent(new Dictionary <string, string>() { { "client_id", Settings.DiscordClientId }, { "client_secret", Settings.DiscordClientSecret }, { "grant_type", "authorization_code" }, { "code", code }, { "redirect_uri", returnUrl }, { "scope", _scope } }); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); var response = await Http.SendAsync(request); if (response.IsSuccessStatusCode) { var result = await response.Content.ReadFromJsonAsync <TokenResponse>(); try { double seconds = result.expires_in; var token = new DiscordToken() { AccessToken = result.access_token, TokenType = result.token_type, Expires = DateTime.UtcNow.AddSeconds(seconds), RefreshToken = result.refresh_token, Scope = result.scope }; // Get the Discord Id associated with this request var user = await GetUserAsync(token.AccessToken); token.DiscordId = user.DiscordId; token.DiscordUser = user; // FIXME: probably move more of the Discord API work to different library return(token); } catch (Exception) { // FIXME: more specific exception throw new Exception("Failed to obtain token for request."); } } else { var error = await request.Content.ReadAsStringAsync(); // FIXME: InvalidOperationException for this throw new Exception("Failed to obtain token for request. " + error); } } else { // FIXME: custom exception for this throw new InvalidOperationException("OAuth request was not initiated by this server."); } }
public DiscordOauth2(ISettings settings, DiscordHttpClient http, Oauth2State state) { Http = http; Settings = settings; Oauth2State = state; }