From 86a1e3bef40f255d5ef28e81767e0a4842752732 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 22 Jan 2023 19:53:30 +0900 Subject: [PATCH] =?utf8?q?OAuth2Session=E3=82=92=E4=BD=BF=E7=94=A8?= =?utf8?q?=E3=81=97=E3=81=9FAPI=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B9?= =?utf8?q?=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- OpenTween/AppendSettingDialog.cs | 25 +++++++- OpenTween/ApplicationSettings.cs | 5 ++ OpenTween/AuthTypeSelectDialog.cs | 8 +++ OpenTween/Connection/Networking.cs | 1 + OpenTween/Connection/TwitterApiConnection.cs | 2 + OpenTween/Connection/TwitterAppToken.cs | 2 + OpenTween/Connection/TwitterComCookieHandler.cs | 81 +++++++++++++++++++++++++ OpenTween/Setting/SettingCommon.cs | 11 ++++ 8 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 OpenTween/Connection/TwitterComCookieHandler.cs diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index e0377ab8..fa4cc1ea 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -185,9 +185,28 @@ namespace OpenTween if (appToken == null) return; - var newAccount = await this.PinAuth(appToken); - if (newAccount == null) - return; + UserAccount newAccount; + if (appToken.AuthType == APIAuthType.TwitterComCookie) + { + newAccount = new() + { + TwitterAuthType = appToken.AuthType, + TwitterComCookie = appToken.TwitterComCookie, + }; + + using var twitterApi = new TwitterApi(); + twitterApi.Initialize(appToken, "", "", 0L, ""); + var twitterUser = await twitterApi.AccountVerifyCredentials(); + newAccount.UserId = twitterUser.Id; + newAccount.Username = twitterUser.ScreenName; + } + else + { + var account = await this.PinAuth(appToken); + if (account == null) + return; + newAccount = account; + } var authUserCombo = this.BasedPanel.AuthUserCombo; diff --git a/OpenTween/ApplicationSettings.cs b/OpenTween/ApplicationSettings.cs index d7c7a466..8d3522e5 100644 --- a/OpenTween/ApplicationSettings.cs +++ b/OpenTween/ApplicationSettings.cs @@ -127,6 +127,11 @@ namespace OpenTween /// public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("%e%p93BdDzlwbYIC5Ych/47OQ==%xYZTCYaBxzS4An3o7Qcigjp9QMtu5vi5iEAW/sNgoOoAUyuHJRPP3Ovs20ZV2fAYKxUDiu76dxLfObwI7QjSRA==%YEruRDAQdbJzO+y6kn7+U/uIyIyNra/8Ulo+L6KJcWA="); + /// + /// で使用する Bearer token + /// + public static readonly ApiKey TwitterComBearerToken = ApiKey.Create("%e%D2/mWPJwkdhuxnXCCnPiAw==%mAH3yTqmvpdf7Zukmlan0yXhUoAuVTo0fBjOsI3RXwP3/NpS2V4/UmcwGy6aZPEl05wDrL9e1BCKdfbB4+cvQUasEGWU1RRW4KsLyzFMX+nqnvP6cgl2Oa7ek0KDT5xShl+gnOCq03dWBPY0uKrLZA==%5+REZK8MSrAzlMM4C6oph/rIJje8YqSDPOiHFiSOyh4="); + // ===================================================================== // Foursquare // https://developer.foursquare.com/ から取得できます。 diff --git a/OpenTween/AuthTypeSelectDialog.cs b/OpenTween/AuthTypeSelectDialog.cs index 50b2efa4..a23767eb 100644 --- a/OpenTween/AuthTypeSelectDialog.cs +++ b/OpenTween/AuthTypeSelectDialog.cs @@ -53,6 +53,14 @@ namespace OpenTween OAuth1ConsumerSecret = ApiKey.Create(this.OAuth1ConsumerSecretTextBox.Text), }; } + else if (this.UseTwitterComCookieRadioButton.Checked) + { + result = new() + { + AuthType = APIAuthType.TwitterComCookie, + TwitterComCookie = this.TwitterComCookieTextBox.Text, + }; + } else { return; diff --git a/OpenTween/Connection/Networking.cs b/OpenTween/Connection/Networking.cs index cd7db98e..b75013ce 100644 --- a/OpenTween/Connection/Networking.cs +++ b/OpenTween/Connection/Networking.cs @@ -141,6 +141,7 @@ namespace OpenTween.Connection { var handler = new WebRequestHandler { + UseCookies = false, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, }; diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index 3d570057..21d664c7 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -594,6 +594,8 @@ namespace OpenTween.Connection { APIAuthType.OAuth1 => new OAuthHandler(innerHandler, appToken.OAuth1ConsumerKey, appToken.OAuth1ConsumerSecret, accessToken, accessSecret), + APIAuthType.TwitterComCookie + => new TwitterComCookieHandler(innerHandler, appToken.TwitterComCookie), _ => throw new NotImplementedException(), }; diff --git a/OpenTween/Connection/TwitterAppToken.cs b/OpenTween/Connection/TwitterAppToken.cs index c37a6a07..b762ab73 100644 --- a/OpenTween/Connection/TwitterAppToken.cs +++ b/OpenTween/Connection/TwitterAppToken.cs @@ -38,6 +38,8 @@ namespace OpenTween.Connection public ApiKey OAuth1ConsumerSecret { get; set; } = ApiKey.Create(""); + public string TwitterComCookie { get; set; } = ""; + public static TwitterAppToken GetDefault() { return new() diff --git a/OpenTween/Connection/TwitterComCookieHandler.cs b/OpenTween/Connection/TwitterComCookieHandler.cs new file mode 100644 index 00000000..9f330526 --- /dev/null +++ b/OpenTween/Connection/TwitterComCookieHandler.cs @@ -0,0 +1,81 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2023 kim_upsilon (@kim_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 , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTween.Connection +{ + public class TwitterComCookieHandler : DelegatingHandler + { + public string RawCookie { get; private set; } = ""; + + public string CsrfToken { get; private set; } = ""; + + public string AuthToken { get; private set; } = ""; + + public TwitterComCookieHandler(HttpMessageHandler innerHandler, string rawCookie) + : base(innerHandler) + { + this.SetCookie(rawCookie); + } + + public void SetCookie(string rawCookie) + { + this.RawCookie = rawCookie; + + var pairs = rawCookie.Split(';') + .Select(x => x.Trim().Split(new[] { '=' }, 2)) + .Where(x => x.Length == 2) + .Select(x => new KeyValuePair(x[0], x[1])); + + string? GetValue(string key) + => pairs.Where(x => x.Key == key).Select(x => x.Value).FirstOrDefault(); + + this.CsrfToken = GetValue("ct0") ?? ""; + this.AuthToken = GetValue("auth_token") ?? ""; + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (!MyCommon.IsNullOrEmpty(this.RawCookie)) + { + request.Headers.Add("x-twitter-auth-type", "OAuth2Session"); + request.Headers.Add("x-csrf-token", this.CsrfToken); + request.Headers.Add("cookie", this.GenerateCookieValue()); + request.Headers.Authorization = new("Bearer", ApplicationSettings.TwitterComBearerToken.Value); + } + + return await base.SendAsync(request, cancellationToken) + .ConfigureAwait(false); + } + + private string GenerateCookieValue() + => $"ct0={this.CsrfToken}; auth_token={this.AuthToken}"; + } +} diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index ffee8b49..ed6ae8eb 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -366,6 +366,15 @@ namespace OpenTween set => this.TwitterOAuth1ConsumerSecret = this.Decrypt(value); } + [XmlIgnore] + public string TwitterComCookie { get; set; } = ""; + + public string TwitterComCookieEncrypted + { + get => this.Encrypt(this.TwitterComCookie); + set => this.TwitterComCookie = this.Decrypt(value); + } + public string Token = ""; [XmlIgnore] @@ -384,6 +393,7 @@ namespace OpenTween AuthType = this.TwitterAuthType, OAuth1ConsumerKey = ApiKey.Create(this.TwitterOAuth1ConsumerKey), OAuth1ConsumerSecret = ApiKey.Create(this.TwitterOAuth1ConsumerSecret), + TwitterComCookie = this.TwitterComCookie, }; } @@ -431,5 +441,6 @@ namespace OpenTween public enum APIAuthType { OAuth1, + TwitterComCookie, } } \ No newline at end of file -- 2.11.0