summaryrefslogtreecommitdiffstats
path: root/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs')
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs131
1 files changed, 50 insertions, 81 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
index e665d96..7bbfaa1 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs
@@ -35,22 +35,18 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// The description of Twitter's OAuth protocol URIs for use with actually reading/writing
/// a user's private Twitter data.
/// </summary>
- public static readonly ServiceProviderDescription ServiceDescription = new ServiceProviderDescription {
- RequestTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/request_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
- UserAuthorizationEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/authorize", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
- AccessTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/access_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
- TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
- };
+ public static readonly ServiceProviderDescription ServiceDescription = new ServiceProviderDescription(
+ "https://api.twitter.com/oauth/request_token",
+ "https://api.twitter.com/oauth/authorize",
+ "https://api.twitter.com/oauth/access_token");
/// <summary>
/// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature.
/// </summary>
- public static readonly ServiceProviderDescription SignInWithTwitterServiceDescription = new ServiceProviderDescription {
- RequestTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/request_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
- UserAuthorizationEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
- AccessTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/access_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
- TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
- };
+ public static readonly ServiceProviderDescription SignInWithTwitterServiceDescription = new ServiceProviderDescription(
+ "https://api.twitter.com/oauth/request_token",
+ "https://api.twitter.com/oauth/authenticate",
+ "https://api.twitter.com/oauth/access_token");
/// <summary>
/// The URI to get a user's favorites.
@@ -68,22 +64,33 @@ namespace DotNetOpenAuth.ApplicationBlock {
private static readonly Uri VerifyCredentialsEndpoint = new Uri("http://api.twitter.com/1/account/verify_credentials.xml");
- /// <summary>
- /// The consumer used for the Sign in to Twitter feature.
- /// </summary>
- private static WebConsumer signInConsumer;
+ private class HostFactories : IHostFactories {
+ private static readonly IHostFactories underlyingFactories = new DefaultOAuthHostFactories();
- /// <summary>
- /// The lock acquired to initialize the <see cref="signInConsumer"/> field.
- /// </summary>
- private static object signInConsumerInitLock = new object();
+ public HttpMessageHandler CreateHttpMessageHandler() {
+ return new WebRequestHandler();
+ }
- /// <summary>
- /// Initializes static members of the <see cref="TwitterConsumer"/> class.
- /// </summary>
- static TwitterConsumer() {
- // Twitter can't handle the Expect 100 Continue HTTP header.
- ServicePointManager.FindServicePoint(GetFavoritesEndpoint).Expect100Continue = false;
+ public HttpClient CreateHttpClient(HttpMessageHandler handler = null) {
+ var client = underlyingFactories.CreateHttpClient(handler);
+
+ // Twitter can't handle the Expect 100 Continue HTTP header.
+ client.DefaultRequestHeaders.ExpectContinue = false;
+ return client;
+ }
+ }
+
+ public static Consumer CreateConsumer(bool forWeb = true) {
+ string consumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
+ if (IsTwitterConsumerConfigured) {
+ ITemporaryCredentialStorage storage = forWeb ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() : new MemoryTemporaryCredentialStorage();
+ return new Consumer(consumerKey, consumerSecret, ServiceDescription, storage) {
+ HostFactories = new HostFactories(),
+ };
+ } else {
+ throw new InvalidOperationException("No Twitter OAuth consumer key and secret could be found in web.config AppSettings.");
+ }
}
/// <summary>
@@ -96,45 +103,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- /// <summary>
- /// Gets the consumer to use for the Sign in to Twitter feature.
- /// </summary>
- /// <value>The twitter sign in.</value>
- private static WebConsumer TwitterSignIn {
- get {
- if (signInConsumer == null) {
- lock (signInConsumerInitLock) {
- if (signInConsumer == null) {
- signInConsumer = new WebConsumer(SignInWithTwitterServiceDescription, ShortTermUserSessionTokenManager);
- }
- }
- }
-
- return signInConsumer;
- }
- }
-
- private static InMemoryTokenManager ShortTermUserSessionTokenManager {
- get {
- var store = HttpContext.Current.Session;
- var tokenManager = (InMemoryTokenManager)store["TwitterShortTermUserSessionTokenManager"];
- if (tokenManager == null) {
- string consumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
- string consumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
- if (IsTwitterConsumerConfigured) {
- tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
- store["TwitterShortTermUserSessionTokenManager"] = tokenManager;
- } else {
- throw new InvalidOperationException("No Twitter OAuth consumer key and secret could be found in web.config AppSettings.");
- }
- }
-
- return tokenManager;
- }
- }
-
- public static async Task<JArray> GetUpdatesAsync(
- ConsumerBase twitter, string accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static async Task<JArray> GetUpdatesAsync(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
using (var httpClient = twitter.CreateHttpClient(accessToken)) {
using (var response = await httpClient.GetAsync(GetFriendTimelineStatusEndpoint, cancellationToken)) {
response.EnsureSuccessStatusCode();
@@ -145,7 +114,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<XDocument> GetFavorites(ConsumerBase twitter, string accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static async Task<XDocument> GetFavorites(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
using (var httpClient = twitter.CreateHttpClient(accessToken)) {
using (HttpResponseMessage response = await httpClient.GetAsync(GetFavoritesEndpoint, cancellationToken)) {
response.EnsureSuccessStatusCode();
@@ -154,7 +123,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<XDocument> UpdateProfileBackgroundImageAsync(ConsumerBase twitter, string accessToken, string image, bool tile, CancellationToken cancellationToken) {
+ public static async Task<XDocument> UpdateProfileBackgroundImageAsync(Consumer twitter, AccessToken accessToken, string image, bool tile, CancellationToken cancellationToken) {
var imageAttachment = new StreamContent(File.OpenRead(image));
imageAttachment.Headers.ContentType = new MediaTypeHeaderValue("image/" + Path.GetExtension(image).Substring(1).ToLowerInvariant());
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UpdateProfileBackgroundImageEndpoint);
@@ -172,12 +141,12 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static Task<XDocument> UpdateProfileImageAsync(ConsumerBase twitter, string accessToken, string pathToImage, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static Task<XDocument> UpdateProfileImageAsync(Consumer twitter, AccessToken accessToken, string pathToImage, CancellationToken cancellationToken = default(CancellationToken)) {
string contentType = "image/" + Path.GetExtension(pathToImage).Substring(1).ToLowerInvariant();
return UpdateProfileImageAsync(twitter, accessToken, File.OpenRead(pathToImage), contentType, cancellationToken);
}
- public static async Task<XDocument> UpdateProfileImageAsync(ConsumerBase twitter, string accessToken, Stream image, string contentType, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static async Task<XDocument> UpdateProfileImageAsync(Consumer twitter, AccessToken accessToken, Stream image, string contentType, CancellationToken cancellationToken = default(CancellationToken)) {
var imageAttachment = new StreamContent(image);
imageAttachment.Headers.ContentType = new MediaTypeHeaderValue(contentType);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UpdateProfileImageEndpoint);
@@ -193,7 +162,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<XDocument> VerifyCredentialsAsync(ConsumerBase twitter, string accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static async Task<XDocument> VerifyCredentialsAsync(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
using (var httpClient = twitter.CreateHttpClient(accessToken)) {
using (var response = await httpClient.GetAsync(VerifyCredentialsEndpoint, cancellationToken)) {
response.EnsureSuccessStatusCode();
@@ -204,7 +173,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
}
- public static async Task<string> GetUsername(ConsumerBase twitter, string accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static async Task<string> GetUsername(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) {
XDocument xml = await VerifyCredentialsAsync(twitter, accessToken, cancellationToken);
XPathNavigator nav = xml.CreateNavigator();
return nav.SelectSingleNode("/user/screen_name").Value;
@@ -223,14 +192,17 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// <c>return StartSignInWithTwitter().<see cref="MessagingUtilities.AsActionResult">AsActionResult()</see></c>
/// to actually perform the redirect.
/// </remarks>
- public static async Task<HttpResponseMessage> StartSignInWithTwitterAsync(bool forceNewLogin = false, CancellationToken cancellationToken = default(CancellationToken)) {
+ public static async Task<Uri> StartSignInWithTwitterAsync(bool forceNewLogin = false, CancellationToken cancellationToken = default(CancellationToken)) {
var redirectParameters = new Dictionary<string, string>();
if (forceNewLogin) {
redirectParameters["force_login"] = "true";
}
Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix("oauth_");
- var request = await TwitterSignIn.PrepareRequestUserAuthorizationAsync(callback, null, redirectParameters, cancellationToken);
- return await TwitterSignIn.Channel.PrepareResponseAsync(request, cancellationToken);
+
+ var consumer = CreateConsumer();
+ consumer.ServiceProvider = SignInWithTwitterServiceDescription;
+ Uri redirectUrl = await consumer.RequestUserAuthorizationAsync(callback, cancellationToken: cancellationToken);
+ return redirectUrl;
}
/// <summary>
@@ -241,19 +213,16 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// <returns>
/// A tuple with the screen name and Twitter unique user ID if successful; otherwise <c>null</c>.
/// </returns>
- public static async Task<Tuple<string, int>> TryFinishSignInWithTwitterAsync(CancellationToken cancellationToken = default(CancellationToken)) {
- var response = await TwitterSignIn.ProcessUserAuthorizationAsync(cancellationToken: cancellationToken);
+ public static async Task<Tuple<string, int>> TryFinishSignInWithTwitterAsync(Uri completeUrl, CancellationToken cancellationToken = default(CancellationToken)) {
+ var consumer = CreateConsumer();
+ consumer.ServiceProvider = SignInWithTwitterServiceDescription;
+ var response = await consumer.ProcessUserAuthorizationAsync(completeUrl, cancellationToken: cancellationToken);
if (response == null) {
return null;
}
string screenName = response.ExtraData["screen_name"];
int userId = int.Parse(response.ExtraData["user_id"]);
-
- // If we were going to make this LOOK like OpenID even though it isn't,
- // this seems like a reasonable, secure claimed id to allow the user to assume.
- ////OpenId.Identifier fake_claimed_id = string.Format(CultureInfo.InvariantCulture, "http://twitter.com/{0}#{1}", screenName, userId);
-
return Tuple.Create(screenName, userId);
}
}