From a96718f7b3bd4e3223d1aae14cb02afedad7da65 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 6 Jan 2016 22:32:12 -0800 Subject: [PATCH] Fixed Twitter notifications New: Twitter notifications now require a Twitter (see settings for details) Closes #1049 --- .../Notifications/Twitter/Twitter.cs | 4 +-- .../Notifications/Twitter/TwitterService.cs | 30 +++++++++---------- .../Notifications/Twitter/TwitterSettings.cs | 18 +++++++---- src/UI/.idea/encodings.xml | 1 + src/UI/.idea/misc.xml | 3 +- .../Edit/NotificationEditView.js | 15 ++++++++-- src/UI/Settings/ProviderSettingsModelBase.js | 24 +++++++++++---- src/UI/oauth.html | 2 +- 8 files changed, 65 insertions(+), 32 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs b/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs index 4f3c9a3aa..85b454c97 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs @@ -42,7 +42,7 @@ namespace NzbDrone.Core.Notifications.Twitter { nextStep = "step2", action = "openWindow", - url = _twitterService.GetOAuthRedirect(query["callbackUrl"].ToString()) + url = _twitterService.GetOAuthRedirect(query["consumerKey"].ToString(), query["consumerSecret"].ToString(), query["callbackUrl"].ToString()) }; } else if (stage == "step2") @@ -50,7 +50,7 @@ namespace NzbDrone.Core.Notifications.Twitter return new { action = "updateFields", - fields = _twitterService.GetOAuthToken(query["oauth_token"].ToString(), query["oauth_verifier"].ToString()) + fields = _twitterService.GetOAuthToken(query["consumerKey"].ToString(), query["consumerSecret"].ToString(), query["oauth_token"].ToString(), query["oauth_verifier"].ToString()) }; } return new {}; diff --git a/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs b/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs index f08191eee..12a4cf28d 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/TwitterService.cs @@ -15,8 +15,8 @@ namespace NzbDrone.Core.Notifications.Twitter { void SendNotification(string message, TwitterSettings settings); ValidationFailure Test(TwitterSettings settings); - string GetOAuthRedirect(string callbackUrl); - object GetOAuthToken(string oauthToken, string oauthVerifier); + string GetOAuthRedirect(string consumerKey, string consumerSecret, string callbackUrl); + object GetOAuthToken(string consumerKey, string consumerSecret, string oauthToken, string oauthVerifier); } public class TwitterService : ITwitterService @@ -24,8 +24,8 @@ namespace NzbDrone.Core.Notifications.Twitter private readonly IHttpClient _httpClient; private readonly Logger _logger; - private static string _consumerKey = "5jSR8a3cp0ToOqSMLMv5GtMQD"; - private static string _consumerSecret = "dxoZjyMq4BLsC8KxyhSOrIndhCzJ0Dik2hrLzqyJcqoGk4Pfsp"; +// private static string _consumerKey = "5jSR8a3cp0ToOqSMLMv5GtMQD"; +// private static string _consumerSecret = "dxoZjyMq4BLsC8KxyhSOrIndhCzJ0Dik2hrLzqyJcqoGk4Pfsp"; public TwitterService(IHttpClient httpClient, Logger logger) { @@ -43,10 +43,10 @@ namespace NzbDrone.Core.Notifications.Twitter return HttpUtility.ParseQueryString(response.Content); } - public object GetOAuthToken(string oauthToken, string oauthVerifier) + public object GetOAuthToken(string consumerKey, string consumerSecret, string oauthToken, string oauthVerifier) { // Creating a new instance with a helper method - var oAuthRequest = OAuthRequest.ForAccessToken(_consumerKey, _consumerSecret, oauthToken, "", oauthVerifier); + var oAuthRequest = OAuthRequest.ForAccessToken(consumerKey, consumerSecret, oauthToken, "", oauthVerifier); oAuthRequest.RequestUrl = "https://api.twitter.com/oauth/access_token"; var qscoll = OAuthQuery(oAuthRequest); @@ -57,10 +57,10 @@ namespace NzbDrone.Core.Notifications.Twitter }; } - public string GetOAuthRedirect(string callbackUrl) + public string GetOAuthRedirect(string consumerKey, string consumerSecret, string callbackUrl) { // Creating a new instance with a helper method - var oAuthRequest = OAuthRequest.ForRequestToken(_consumerKey, _consumerSecret, callbackUrl); + var oAuthRequest = OAuthRequest.ForRequestToken(consumerKey, consumerSecret, callbackUrl); oAuthRequest.RequestUrl = "https://api.twitter.com/oauth/request_token"; var qscoll = OAuthQuery(oAuthRequest); @@ -73,10 +73,10 @@ namespace NzbDrone.Core.Notifications.Twitter { var oAuth = new TinyTwitter.OAuthInfo { + ConsumerKey = settings.ConsumerKey, + ConsumerSecret = settings.ConsumerSecret, AccessToken = settings.AccessToken, - AccessSecret = settings.AccessTokenSecret, - ConsumerKey = _consumerKey, - ConsumerSecret = _consumerSecret + AccessSecret = settings.AccessTokenSecret }; var twitter = new TinyTwitter.TinyTwitter(oAuth); @@ -96,9 +96,9 @@ namespace NzbDrone.Core.Notifications.Twitter twitter.UpdateStatus(message); } } - catch (WebException e) + catch (WebException ex) { - using (var response = e.Response) + using (var response = ex.Response) { var httpResponse = (HttpWebResponse)response; @@ -107,14 +107,14 @@ namespace NzbDrone.Core.Notifications.Twitter if (responseStream == null) { _logger.Trace("Status Code: {0}", httpResponse.StatusCode); - throw new TwitterException("Error received from Twitter: " + httpResponse.StatusCode, _logger , e); + throw new TwitterException("Error received from Twitter: " + httpResponse.StatusCode, ex); } using (var reader = new StreamReader(responseStream)) { var responseBody = reader.ReadToEnd(); _logger.Trace("Reponse: {0} Status Code: {1}", responseBody, httpResponse.StatusCode); - throw new TwitterException("Error received from Twitter: " + responseBody, _logger, e); + throw new TwitterException("Error received from Twitter: " + responseBody, ex); } } } diff --git a/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs b/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs index 2be9cb409..08f83b007 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs @@ -9,6 +9,8 @@ namespace NzbDrone.Core.Notifications.Twitter { public TwitterSettingsValidator() { + RuleFor(c => c.ConsumerKey).NotEmpty(); + RuleFor(c => c.ConsumerSecret).NotEmpty(); RuleFor(c => c.AccessToken).NotEmpty(); RuleFor(c => c.AccessTokenSecret).NotEmpty(); //TODO: Validate that it is a valid username (numbers, letters and underscores - I think) @@ -30,19 +32,25 @@ namespace NzbDrone.Core.Notifications.Twitter AuthorizeNotification = "step1"; } - [FieldDefinition(0, Label = "Access Token", Advanced = true)] + [FieldDefinition(0, Label = "Consumer Key", HelpText = "Consumer key from a Twitter application", HelpLink = "https://github.com/Sonarr/Sonarr/wiki/Twitter-Notifications")] + public string ConsumerKey { get; set; } + + [FieldDefinition(1, Label = "Consumer Secret", HelpText = "Consumer secret from a Twitter application", HelpLink = "https://github.com/Sonarr/Sonarr/wiki/Twitter-Notifications")] + public string ConsumerSecret { get; set; } + + [FieldDefinition(2, Label = "Access Token", Advanced = true)] public string AccessToken { get; set; } - [FieldDefinition(1, Label = "Access Token Secret", Advanced = true)] + [FieldDefinition(3, Label = "Access Token Secret", Advanced = true)] public string AccessTokenSecret { get; set; } - [FieldDefinition(2, Label = "Mention", HelpText = "Mention this user in sent tweets")] + [FieldDefinition(4, Label = "Mention", HelpText = "Mention this user in sent tweets")] public string Mention { get; set; } - [FieldDefinition(3, Label = "Direct Message", Type = FieldType.Checkbox, HelpText = "Send a direct message instead of a public message")] + [FieldDefinition(5, Label = "Direct Message", Type = FieldType.Checkbox, HelpText = "Send a direct message instead of a public message")] public bool DirectMessage { get; set; } - [FieldDefinition(4, Label = "Connect to twitter", Type = FieldType.Action)] + [FieldDefinition(6, Label = "Connect to twitter", Type = FieldType.Action)] public string AuthorizeNotification { get; set; } public NzbDroneValidationResult Validate() diff --git a/src/UI/.idea/encodings.xml b/src/UI/.idea/encodings.xml index c312d510a..e55d06786 100644 --- a/src/UI/.idea/encodings.xml +++ b/src/UI/.idea/encodings.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/src/UI/.idea/misc.xml b/src/UI/.idea/misc.xml index 5be062889..3e64709c0 100644 --- a/src/UI/.idea/misc.xml +++ b/src/UI/.idea/misc.xml @@ -4,5 +4,4 @@