using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using System.Xml;
+using System.Xml.Linq;
using OpenTween.Connection;
namespace OpenTween.Api
}
public BitlyApi(HttpClient http)
- {
- this.localHttpClient = http;
- }
+ => this.localHttpClient = http;
public async Task<Uri> ShortenAsync(Uri srcUri, string domain = null)
{
var paramWithToken = param.Concat(this.CreateAccessTokenParams());
var requestUri = new Uri(new Uri(ApiBase, endpoint), "?" + MyCommon.BuildQueryString(paramWithToken));
+ using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
- using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
- using (var response = await this.http.SendAsync(request).ConfigureAwait(false))
- {
- return await response.Content.ReadAsStringAsync()
- .ConfigureAwait(false);
- }
- }
+ using var response = await this.http.SendAsync(request)
+ .ConfigureAwait(false);
- public bool ValidateApiKey(string login, string apiKey)
- => this.ValidateApiKeyAsync(login, apiKey).Result;
+ return await response.Content.ReadAsStringAsync()
+ .ConfigureAwait(false);
+ }
- public async Task<bool> ValidateApiKeyAsync(string login, string apikey)
+ public async Task<string> GetAccessTokenAsync(string username, string password)
{
- try
+ var param = new Dictionary<string, string>
{
- var requestUri = new Uri(ApiBase, "/v3/validate");
- var param = new Dictionary<string, string>
- {
- ["login"] = ApplicationSettings.BitlyLoginId,
- ["apiKey"] = ApplicationSettings.BitlyApiKey,
- ["x_login"] = login,
- ["x_apiKey"] = apikey,
- ["format"] = "txt",
- };
+ ["grant_type"] = "password",
+ ["username"] = username,
+ ["password"] = password,
+ };
- using (var postContent = new FormUrlEncodedContent(param))
- using (var response = await this.http.PostAsync(requestUri, postContent).ConfigureAwait(false))
- {
- var responseText = await response.Content.ReadAsStringAsync()
- .ConfigureAwait(false);
+ var endpoint = new Uri(ApiBase, "/oauth/access_token");
- return responseText.TrimEnd() == "1";
- }
+ using var request = new HttpRequestMessage(HttpMethod.Post, endpoint);
+ using var postContent = new FormUrlEncodedContent(param);
+
+ var authzParam = ApplicationSettings.BitlyClientId + ":" + ApplicationSettings.BitlyClientSecret;
+ request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(authzParam)));
+
+ request.Content = postContent;
+
+ using var response = await this.http.SendAsync(request)
+ .ConfigureAwait(false);
+ var responseBytes = await response.Content.ReadAsByteArrayAsync()
+ .ConfigureAwait(false);
+
+ return this.ParseOAuthCredential(responseBytes);
+ }
+
+ private string ParseOAuthCredential(byte[] responseBytes)
+ {
+ using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(responseBytes, XmlDictionaryReaderQuotas.Max);
+ var xElm = XElement.Load(jsonReader);
+
+ var statusCode = xElm.Element("status_code")?.Value ?? "200";
+ if (statusCode != "200")
+ {
+ var statusText = xElm.Element("status_txt")?.Value;
+ throw new WebApiException(statusText ?? $"status_code = {statusCode}");
}
- catch (OperationCanceledException) { }
- catch (HttpRequestException) { }
- return false;
+ var accessToken = xElm.Element("access_token")?.Value;
+ if (accessToken == null)
+ throw new WebApiException("Property `access_token` required");
+
+ return accessToken;
}
private IEnumerable<KeyValuePair<string, string>> CreateAccessTokenParams()