OSDN Git Service

using var を使用する
[opentween/open-tween.git] / OpenTween / Api / BitlyApi.cs
index 4dcb73e..09d6780 100644 (file)
@@ -23,9 +23,13 @@ using System;
 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
@@ -48,9 +52,7 @@ namespace OpenTween.Api
         }
 
         public BitlyApi(HttpClient http)
-        {
-            this.localHttpClient = http;
-        }
+            => this.localHttpClient = http;
 
         public async Task<Uri> ShortenAsync(Uri srcUri, string domain = null)
         {
@@ -77,45 +79,59 @@ namespace OpenTween.Api
             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()