OSDN Git Service

ITwitterCredentialとアクセス手段ごとの具象クラスを追加
authorKimura Youichi <kim.upsilon@bucyou.net>
Sun, 10 Dec 2023 13:03:16 +0000 (22:03 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Sun, 10 Dec 2023 13:56:21 +0000 (22:56 +0900)
16 files changed:
OpenTween.Tests/Api/TwitterApiTest.cs
OpenTween.Tests/Connection/TwitterApiConnectionTest.cs
OpenTween.Tests/Connection/TwitterCredentialCookieTest.cs [new file with mode: 0644]
OpenTween.Tests/Connection/TwitterCredentialOAuth1Test.cs [new file with mode: 0644]
OpenTween.Tests/TweenMainTest.cs
OpenTween/Api/TwitterApi.cs
OpenTween/AppendSettingDialog.cs
OpenTween/ApplicationEvents.cs
OpenTween/Connection/ITwitterCredential.cs [new file with mode: 0644]
OpenTween/Connection/TwitterApiConnection.cs
OpenTween/Connection/TwitterCredentialCookie.cs [new file with mode: 0644]
OpenTween/Connection/TwitterCredentialNone.cs [new file with mode: 0644]
OpenTween/Connection/TwitterCredentialOAuth1.cs [new file with mode: 0644]
OpenTween/Setting/SettingCommon.cs
OpenTween/Tween.cs
OpenTween/Twitter.cs

index d74088b..bac959b 100644 (file)
@@ -59,8 +59,9 @@ namespace OpenTween.Api
             Assert.IsType<TwitterApiConnection>(twitterApi.ApiConnection);
 
             var apiConnection = (TwitterApiConnection)twitterApi.ApiConnection!;
-            Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
-            Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
+            var credential = Assert.IsType<TwitterCredentialOAuth1>(apiConnection.Credential);
+            Assert.Equal("*** AccessToken ***", credential.Token);
+            Assert.Equal("*** AccessSecret ***", credential.TokenSecret);
 
             Assert.Equal(100L, twitterApi.CurrentUserId);
             Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
@@ -74,8 +75,9 @@ namespace OpenTween.Api
             Assert.IsType<TwitterApiConnection>(twitterApi.ApiConnection);
 
             apiConnection = (TwitterApiConnection)twitterApi.ApiConnection!;
-            Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
-            Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
+            credential = Assert.IsType<TwitterCredentialOAuth1>(apiConnection.Credential);
+            Assert.Equal("*** AccessToken2 ***", credential.Token);
+            Assert.Equal("*** AccessSecret2 ***", credential.TokenSecret);
 
             Assert.Equal(200L, twitterApi.CurrentUserId);
             Assert.Equal("foobar", twitterApi.CurrentScreenName);
index 1c7b53c..c646f07 100644 (file)
@@ -57,7 +57,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
@@ -95,7 +95,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
@@ -132,7 +132,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
@@ -175,7 +175,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
@@ -219,7 +219,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
@@ -251,7 +251,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
@@ -285,7 +285,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             using var image = TestUtils.CreateDummyImage();
             apiConnection.Http = http;
 
@@ -331,7 +331,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(async x =>
@@ -371,7 +371,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.HttpUpload = http;
 
             using var image = TestUtils.CreateDummyImage();
@@ -441,7 +441,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.HttpUpload = http;
 
             mockHandler.Enqueue(async x =>
@@ -486,7 +486,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(async x =>
@@ -520,7 +520,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(async x =>
@@ -555,7 +555,7 @@ namespace OpenTween.Connection
         {
             using var mockHandler = new HttpMessageHandlerMock();
             using var http = new HttpClient(mockHandler);
-            using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", "");
+            using var apiConnection = new TwitterApiConnection();
             apiConnection.Http = http;
 
             mockHandler.Enqueue(x =>
diff --git a/OpenTween.Tests/Connection/TwitterCredentialCookieTest.cs b/OpenTween.Tests/Connection/TwitterCredentialCookieTest.cs
new file mode 100644 (file)
index 0000000..938b8f5
--- /dev/null
@@ -0,0 +1,47 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using System.Net.Http;
+using Xunit;
+
+namespace OpenTween.Connection
+{
+    public class TwitterCredentialCookieTest
+    {
+        [Fact]
+        public void CreateHttpHandler_Test()
+        {
+            var appToken = new TwitterAppToken
+            {
+                AuthType = APIAuthType.TwitterComCookie,
+                TwitterComCookie = "aaa=bbb",
+            };
+            var credential = new TwitterCredentialCookie(appToken);
+
+            using var innerHandler = new HttpClientHandler();
+            using var handler = credential.CreateHttpHandler(innerHandler);
+
+            var cookieHandler = Assert.IsType<TwitterComCookieHandler>(handler);
+            Assert.Equal("aaa=bbb", cookieHandler.RawCookie);
+            Assert.Same(innerHandler, cookieHandler.InnerHandler);
+        }
+    }
+}
diff --git a/OpenTween.Tests/Connection/TwitterCredentialOAuth1Test.cs b/OpenTween.Tests/Connection/TwitterCredentialOAuth1Test.cs
new file mode 100644 (file)
index 0000000..5ede503
--- /dev/null
@@ -0,0 +1,51 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using System.Net.Http;
+using Xunit;
+
+namespace OpenTween.Connection
+{
+    public class TwitterCredentialOAuth1Test
+    {
+        [Fact]
+        public void CreateHttpHandler_Test()
+        {
+            var appToken = new TwitterAppToken
+            {
+                AuthType = APIAuthType.OAuth1,
+                OAuth1CustomConsumerKey = ApiKey.Create("consumer_key"),
+                OAuth1CustomConsumerSecret = ApiKey.Create("consumer_secret"),
+            };
+            var credential = new TwitterCredentialOAuth1(appToken, "access_token", "access_secret");
+
+            using var innerHandler = new HttpClientHandler();
+            using var handler = credential.CreateHttpHandler(innerHandler);
+
+            var oauthHandler = Assert.IsType<OAuthHandler>(handler);
+            Assert.Equal("consumer_key", oauthHandler.ConsumerKey.Value);
+            Assert.Equal("consumer_secret", oauthHandler.ConsumerSecret.Value);
+            Assert.Equal("access_token", oauthHandler.AccessToken);
+            Assert.Equal("access_secret", oauthHandler.AccessSecret);
+            Assert.Same(innerHandler, oauthHandler.InnerHandler);
+        }
+    }
+}
index 37a1ac2..87dfbec 100644 (file)
@@ -48,13 +48,7 @@ namespace OpenTween
             using var imageCache = new ImageCache();
             using var iconAssets = new IconAssetsManager();
             var thumbnailGenerator = new ThumbnailGenerator(new(autoupdate: false));
-            var twitterAppToken = new TwitterAppToken
-            {
-                AuthType = APIAuthType.OAuth1,
-                OAuth1CustomConsumerKey = ApiKey.Create("aaa"),
-                OAuth1CustomConsumerSecret = ApiKey.Create("bbb"),
-            };
-            twitter.Initialize(twitterAppToken, "", "", "", 0L);
+            twitter.Initialize(new TwitterCredentialNone(), "", 0L);
 
             using var tweenMain = new TweenMain(settings, tabinfo, twitter, imageCache, iconAssets, thumbnailGenerator);
         }
index abce763..bc97384 100644 (file)
@@ -62,13 +62,13 @@ namespace OpenTween.Api
         }
 
         public void Initialize(string accessToken, string accessSecret, long userId, string screenName)
-            => this.Initialize(this.AppToken, accessToken, accessSecret, userId, screenName);
+            => this.Initialize(new TwitterCredentialOAuth1(this.AppToken, accessToken, accessSecret), userId, screenName);
 
-        public void Initialize(TwitterAppToken appToken, string accessToken, string accessSecret, long userId, string screenName)
+        public void Initialize(ITwitterCredential credential, long userId, string screenName)
         {
-            this.AppToken = appToken;
+            this.AppToken = credential.AppToken;
 
-            var newInstance = new TwitterApiConnection(this.AppToken, accessToken, accessSecret);
+            var newInstance = new TwitterApiConnection(credential);
             var oldInstance = Interlocked.Exchange(ref this.ApiConnection, newInstance);
             oldInstance?.Dispose();
 
index 0803eb4..703cd51 100644 (file)
@@ -195,7 +195,7 @@ namespace OpenTween
                         };
 
                         using var twitterApi = new TwitterApi();
-                        twitterApi.Initialize(appToken, "", "", 0L, "");
+                        twitterApi.Initialize(new TwitterCredentialCookie(appToken), 0L, "");
                         var twitterUser = await twitterApi.AccountVerifyCredentials();
                         newAccount.UserId = twitterUser.Id;
                         newAccount.Username = twitterUser.ScreenName;
@@ -294,7 +294,7 @@ namespace OpenTween
             if (MyCommon.IsNullOrEmpty(pin))
                 return null; // キャンセルされた場合
 
-            var accessTokenResponse = await TwitterApiConnection.GetAccessTokenAsync(appToken, requestToken, pin);
+            var accessTokenResponse = await TwitterApiConnection.GetAccessTokenAsync(requestToken, pin);
 
             return new UserAccount
             {
index 539639c..04d5a69 100644 (file)
@@ -143,9 +143,9 @@ namespace OpenTween
         {
             var account = settings.Common.SelectedAccount;
             if (account != null)
-                tw.Initialize(account.GetTwitterAppToken(), account.Token, account.TokenSecret, account.Username, account.UserId);
+                tw.Initialize(account.GetTwitterCredential(), account.Username, account.UserId);
             else
-                tw.Initialize(TwitterAppToken.GetDefault(), "", "", "", 0L);
+                tw.Initialize(new TwitterCredentialNone(), "", 0L);
 
             tw.RestrictFavCheck = settings.Common.RestrictFavCheck;
             tw.ReadOwnPost = settings.Common.ReadOwnPost;
diff --git a/OpenTween/Connection/ITwitterCredential.cs b/OpenTween/Connection/ITwitterCredential.cs
new file mode 100644 (file)
index 0000000..87f5a8d
--- /dev/null
@@ -0,0 +1,34 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System.Net.Http;
+
+namespace OpenTween.Connection
+{
+    public interface ITwitterCredential
+    {
+        TwitterAppToken AppToken { get; }
+
+        HttpMessageHandler CreateHttpHandler(HttpMessageHandler innerHandler);
+    }
+}
index 35a8e0b..bfcc99b 100644 (file)
@@ -52,35 +52,20 @@ namespace OpenTween.Connection
 
         public bool IsDisposed { get; private set; } = false;
 
-        public string AccessToken { get; }
-
-        public string AccessSecret { get; }
-
         internal HttpClient Http;
         internal HttpClient HttpUpload;
         internal HttpClient HttpStreaming;
 
-        private readonly TwitterAppToken appToken;
+        internal ITwitterCredential Credential { get; }
 
-        public TwitterApiConnection(ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret)
-            : this(
-                new()
-                {
-                    AuthType = APIAuthType.OAuth1,
-                    OAuth1CustomConsumerKey = consumerKey,
-                    OAuth1CustomConsumerSecret = consumerSecret,
-                },
-                accessToken,
-                accessSecret
-            )
+        public TwitterApiConnection()
+            : this(new TwitterCredentialNone())
         {
         }
 
-        public TwitterApiConnection(TwitterAppToken appToken, string accessToken, string accessSecret)
+        public TwitterApiConnection(ITwitterCredential credential)
         {
-            this.appToken = appToken;
-            this.AccessToken = accessToken;
-            this.AccessSecret = accessSecret;
+            this.Credential = credential;
 
             this.InitializeHttpClients();
             Networking.WebProxyChanged += this.Networking_WebProxyChanged;
@@ -89,12 +74,12 @@ namespace OpenTween.Connection
         [MemberNotNull(nameof(Http), nameof(HttpUpload), nameof(HttpStreaming))]
         private void InitializeHttpClients()
         {
-            this.Http = InitializeHttpClient(this.appToken, this.AccessToken, this.AccessSecret);
+            this.Http = InitializeHttpClient(this.Credential);
 
-            this.HttpUpload = InitializeHttpClient(this.appToken, this.AccessToken, this.AccessSecret);
+            this.HttpUpload = InitializeHttpClient(this.Credential);
             this.HttpUpload.Timeout = Networking.UploadImageTimeout;
 
-            this.HttpStreaming = InitializeHttpClient(this.appToken, this.AccessToken, this.AccessSecret, disableGzip: true);
+            this.HttpStreaming = InitializeHttpClient(this.Credential, disableGzip: true);
             this.HttpStreaming.Timeout = Timeout.InfiniteTimeSpan;
         }
 
@@ -500,14 +485,29 @@ namespace OpenTween.Connection
         {
             var uri = new Uri(RestApiBase, authServiceProvider);
 
-            return OAuthEchoHandler.CreateHandler(
-                innerHandler,
-                uri,
-                this.appToken.OAuth1ConsumerKey,
-                this.appToken.OAuth1ConsumerSecret,
-                this.AccessToken,
-                this.AccessSecret,
-                realm);
+            if (this.Credential is TwitterCredentialOAuth1 oauthCredential)
+            {
+                return OAuthEchoHandler.CreateHandler(
+                    innerHandler,
+                    uri,
+                    oauthCredential.AppToken.OAuth1ConsumerKey,
+                    oauthCredential.AppToken.OAuth1ConsumerSecret,
+                    oauthCredential.Token,
+                    oauthCredential.TokenSecret,
+                    realm);
+            }
+            else
+            {
+                // MobipictureApi クラス向けの暫定対応
+                return OAuthEchoHandler.CreateHandler(
+                    innerHandler,
+                    uri,
+                    ApiKey.Create(""),
+                    ApiKey.Create(""),
+                    "",
+                    "",
+                    realm);
+            }
         }
 
         public void Dispose()
@@ -538,19 +538,20 @@ namespace OpenTween.Connection
         private void Networking_WebProxyChanged(object sender, EventArgs e)
             => this.InitializeHttpClients();
 
-        public static async Task<(string Token, string TokenSecret)> GetRequestTokenAsync(TwitterAppToken appToken)
+        public static async Task<TwitterCredentialOAuth1> GetRequestTokenAsync(TwitterAppToken appToken)
         {
+            var emptyCredential = new TwitterCredentialOAuth1(appToken, "", "");
             var param = new Dictionary<string, string>
             {
                 ["oauth_callback"] = "oob",
             };
-            var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/request_token"), param, appToken, oauthToken: null)
+            var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/request_token"), param, emptyCredential)
                 .ConfigureAwait(false);
 
-            return (response["oauth_token"], response["oauth_token_secret"]);
+            return new(appToken, response["oauth_token"], response["oauth_token_secret"]);
         }
 
-        public static Uri GetAuthorizeUri((string Token, string TokenSecret) requestToken, string? screenName = null)
+        public static Uri GetAuthorizeUri(TwitterCredentialOAuth1 requestToken, string? screenName = null)
         {
             var param = new Dictionary<string, string>
             {
@@ -563,13 +564,13 @@ namespace OpenTween.Connection
             return new Uri("https://api.twitter.com/oauth/authorize?" + MyCommon.BuildQueryString(param));
         }
 
-        public static async Task<IDictionary<string, string>> GetAccessTokenAsync(TwitterAppToken appToken, (string Token, string TokenSecret) requestToken, string verifier)
+        public static async Task<IDictionary<string, string>> GetAccessTokenAsync(TwitterCredentialOAuth1 credential, string verifier)
         {
             var param = new Dictionary<string, string>
             {
                 ["oauth_verifier"] = verifier,
             };
-            var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/access_token"), param, appToken, requestToken)
+            var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/access_token"), param, credential)
                 .ConfigureAwait(false);
 
             return response;
@@ -578,14 +579,10 @@ namespace OpenTween.Connection
         private static async Task<IDictionary<string, string>> GetOAuthTokenAsync(
             Uri uri,
             IDictionary<string, string> param,
-            TwitterAppToken appToken,
-            (string Token, string TokenSecret)? oauthToken)
+            TwitterCredentialOAuth1 credential
+        )
         {
-            HttpClient authorizeClient;
-            if (oauthToken != null)
-                authorizeClient = InitializeHttpClient(appToken.OAuth1ConsumerKey, appToken.OAuth1ConsumerSecret, oauthToken.Value.Token, oauthToken.Value.TokenSecret);
-            else
-                authorizeClient = InitializeHttpClient(appToken.OAuth1ConsumerKey, appToken.OAuth1ConsumerSecret, "", "");
+            using var authorizeClient = InitializeHttpClient(credential);
 
             var requestUri = new Uri(uri, "?" + MyCommon.BuildQueryString(param));
 
@@ -617,24 +614,7 @@ namespace OpenTween.Connection
             }
         }
 
-        private static HttpClient InitializeHttpClient(ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret, bool disableGzip = false)
-        {
-            var builder = Networking.CreateHttpClientBuilder();
-
-            builder.SetupHttpClientHandler(x =>
-            {
-                x.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
-
-                if (disableGzip)
-                    x.AutomaticDecompression = DecompressionMethods.None;
-            });
-
-            builder.AddHandler(x => new OAuthHandler(x, consumerKey, consumerSecret, accessToken, accessSecret));
-
-            return builder.Build();
-        }
-
-        private static HttpClient InitializeHttpClient(TwitterAppToken appToken, string accessToken, string accessSecret, bool disableGzip = false)
+        private static HttpClient InitializeHttpClient(ITwitterCredential credential, bool disableGzip = false)
         {
             var builder = Networking.CreateHttpClientBuilder();
 
@@ -646,14 +626,7 @@ namespace OpenTween.Connection
                     x.AutomaticDecompression = DecompressionMethods.None;
             });
 
-            builder.AddHandler(x => appToken.AuthType switch
-            {
-                APIAuthType.OAuth1
-                    => new OAuthHandler(x, appToken.OAuth1ConsumerKey, appToken.OAuth1ConsumerSecret, accessToken, accessSecret),
-                APIAuthType.TwitterComCookie
-                    => new TwitterComCookieHandler(x, appToken.TwitterComCookie),
-                _ => throw new NotImplementedException(),
-            });
+            builder.AddHandler(x => credential.CreateHttpHandler(x));
 
             return builder.Build();
         }
diff --git a/OpenTween/Connection/TwitterCredentialCookie.cs b/OpenTween/Connection/TwitterCredentialCookie.cs
new file mode 100644 (file)
index 0000000..14452e0
--- /dev/null
@@ -0,0 +1,38 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System.Net.Http;
+
+namespace OpenTween.Connection
+{
+    public class TwitterCredentialCookie : ITwitterCredential
+    {
+        public TwitterAppToken AppToken { get; }
+
+        public TwitterCredentialCookie(TwitterAppToken appToken)
+            => this.AppToken = appToken;
+
+        public HttpMessageHandler CreateHttpHandler(HttpMessageHandler innerHandler)
+            => new TwitterComCookieHandler(innerHandler, this.AppToken.TwitterComCookie);
+    }
+}
diff --git a/OpenTween/Connection/TwitterCredentialNone.cs b/OpenTween/Connection/TwitterCredentialNone.cs
new file mode 100644 (file)
index 0000000..67d1c86
--- /dev/null
@@ -0,0 +1,36 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System.Net.Http;
+
+namespace OpenTween.Connection
+{
+    public class TwitterCredentialNone : ITwitterCredential
+    {
+        public TwitterAppToken AppToken
+            => TwitterAppToken.GetDefault();
+
+        public HttpMessageHandler CreateHttpHandler(HttpMessageHandler innerHandler)
+            => innerHandler;
+    }
+}
diff --git a/OpenTween/Connection/TwitterCredentialOAuth1.cs b/OpenTween/Connection/TwitterCredentialOAuth1.cs
new file mode 100644 (file)
index 0000000..298ace0
--- /dev/null
@@ -0,0 +1,52 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System.Net.Http;
+
+namespace OpenTween.Connection
+{
+    public class TwitterCredentialOAuth1 : ITwitterCredential
+    {
+        public TwitterAppToken AppToken { get; }
+
+        public string Token { get; }
+
+        public string TokenSecret { get; }
+
+        public TwitterCredentialOAuth1(TwitterAppToken appToken, string accessToken, string accessSecret)
+        {
+            this.AppToken = appToken;
+            this.Token = accessToken;
+            this.TokenSecret = accessSecret;
+        }
+
+        public HttpMessageHandler CreateHttpHandler(HttpMessageHandler innerHandler)
+            => new OAuthHandler(
+                innerHandler,
+                this.AppToken.OAuth1ConsumerKey,
+                this.AppToken.OAuth1ConsumerSecret,
+                this.Token,
+                this.TokenSecret
+            );
+    }
+}
index 3e9f656..5d9f3ad 100644 (file)
@@ -398,6 +398,20 @@ namespace OpenTween
             };
         }
 
+        public ITwitterCredential GetTwitterCredential()
+        {
+            var appToken = this.GetTwitterAppToken();
+
+            return appToken.AuthType switch
+            {
+                APIAuthType.OAuth1
+                    => new TwitterCredentialOAuth1(appToken, this.TwitterOAuth1ConsumerKey, this.TwitterOAuth1ConsumerSecret),
+                APIAuthType.TwitterComCookie
+                    => new TwitterCredentialCookie(appToken),
+                _ => new TwitterCredentialNone(),
+            };
+        }
+
         private string Encrypt(string password)
         {
             if (MyCommon.IsNullOrEmpty(password)) password = "";
index 63e2988..0dc3568 100644 (file)
@@ -2555,9 +2555,9 @@ namespace OpenTween
 
                     var account = this.settings.Common.SelectedAccount;
                     if (account != null)
-                        this.tw.Initialize(account.GetTwitterAppToken(), account.Token, account.TokenSecret, account.Username, account.UserId);
+                        this.tw.Initialize(account.GetTwitterCredential(), account.Username, account.UserId);
                     else
-                        this.tw.Initialize(TwitterAppToken.GetDefault(), "", "", "", 0L);
+                        this.tw.Initialize(new TwitterCredentialNone(), "", 0L);
 
                     this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck;
                     this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost;
index f100a88..48be5ba 100644 (file)
@@ -228,15 +228,14 @@ namespace OpenTween
             this.Api.Initialize(token, tokenSecret, userId, username);
         }
 
-        public void Initialize(TwitterAppToken appToken, string token, string tokenSecret, string username, long userId)
+        public void Initialize(ITwitterCredential credential, string username, long userId)
         {
             // OAuth認証
-            if (MyCommon.IsNullOrEmpty(token) || MyCommon.IsNullOrEmpty(tokenSecret) || MyCommon.IsNullOrEmpty(username))
-            {
+            if (credential is TwitterCredentialNone)
                 Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid;
-            }
+
             this.ResetApiStatus();
-            this.Api.Initialize(appToken, token, tokenSecret, userId, username);
+            this.Api.Initialize(credential, userId, username);
         }
 
         public async Task<PostClass?> PostStatus(PostStatusParams param)