//----------------------------------------------------------------------- // // Copyright (c) Microsoft. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; using System.Collections.Specialized; /// /// Represents a Twitter client /// public class TwitterClient : OAuthClient { #region Constants and Fields /// /// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature. /// public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription( "https://api.twitter.com/oauth/request_token", "https://api.twitter.com/oauth/authenticate", "https://api.twitter.com/oauth/access_token"); #endregion #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// The consumer key. /// The consumer secret. public TwitterClient(string consumerKey, string consumerSecret) : base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { } #endregion #region Methods /// /// Check if authentication succeeded after user is redirected back from the service provider. /// /// The response token returned from service provider /// The cancellation token. /// /// Authentication result /// [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We don't care if the request for additional data fails.")] protected override async Task VerifyAuthenticationCoreAsync(AccessTokenResponse response, CancellationToken cancellationToken) { string userId = response.ExtraData["user_id"]; string userName = response.ExtraData["screen_name"]; var profileRequestUrl = new Uri("https://api.twitter.com/1/users/show.xml?user_id=" + MessagingUtilities.EscapeUriDataStringRfc3986(userId)); var authorizingHandler = this.WebWorker.CreateMessageHandler(response.AccessToken); var extraData = new NameValueCollection(); extraData.Add("accesstoken", response.AccessToken.Token); extraData.Add("accesstokensecret", response.AccessToken.Secret); try { using (var httpClient = new HttpClient(authorizingHandler)) { using (HttpResponseMessage profileResponse = await httpClient.GetAsync(profileRequestUrl, cancellationToken)) { using (Stream responseStream = await profileResponse.Content.ReadAsStreamAsync()) { XDocument document = LoadXDocumentFromStream(responseStream); extraData.AddDataIfNotEmpty(document, "name"); extraData.AddDataIfNotEmpty(document, "location"); extraData.AddDataIfNotEmpty(document, "description"); extraData.AddDataIfNotEmpty(document, "url"); } } } } catch (Exception) { // At this point, the authentication is already successful. // Here we are just trying to get additional data if we can. // If it fails, no problem. } return new AuthenticationResult( isSuccessful: true, provider: this.ProviderName, providerUserId: userId, userName: userName, extraData: extraData); } #endregion } }