diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2013-02-26 22:55:18 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2013-02-26 22:55:18 -0800 |
commit | 6204dcf07f31b78478bc1ddb55a6ca9027617b67 (patch) | |
tree | 2b92fff13f9e253c9504e73b677ec61b352d9f38 /samples/DotNetOpenAuth.ApplicationBlock | |
parent | 38a1162c5cbaea035e655dc9accd92f9de5019ed (diff) | |
download | DotNetOpenAuth-6204dcf07f31b78478bc1ddb55a6ca9027617b67.zip DotNetOpenAuth-6204dcf07f31b78478bc1ddb55a6ca9027617b67.tar.gz DotNetOpenAuth-6204dcf07f31b78478bc1ddb55a6ca9027617b67.tar.bz2 |
Fixes some OAuth 1 build breaks.
Diffstat (limited to 'samples/DotNetOpenAuth.ApplicationBlock')
3 files changed, 129 insertions, 99 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs index 2302837..def378f 100644 --- a/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs +++ b/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.ApplicationBlock { using System; using System.Collections.Generic; + using System.Configuration; using System.Diagnostics; using System.Globalization; using System.IO; @@ -19,6 +20,7 @@ namespace DotNetOpenAuth.ApplicationBlock { using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; + using System.Web; using System.Xml; using System.Xml.Linq; using DotNetOpenAuth.Messaging; @@ -66,6 +68,18 @@ namespace DotNetOpenAuth.ApplicationBlock { private static readonly Uri GetContactsEndpoint = new Uri("http://www.google.com/m8/feeds/contacts/default/full/"); /// <summary> + /// Initializes a new instance of the <see cref="GoogleConsumer"/> class. + /// </summary> + public GoogleConsumer() { + this.ServiceProvider = ServiceDescription; + this.ConsumerKey = ConfigurationManager.AppSettings["googleConsumerKey"]; + this.ConsumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"]; + this.TemporaryCredentialStorage = HttpContext.Current != null + ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() + : new MemoryTemporaryCredentialStorage(); + } + + /// <summary> /// The many specific authorization scopes Google offers. /// </summary> [Flags] @@ -151,19 +165,23 @@ namespace DotNetOpenAuth.ApplicationBlock { Maps = 0x8000, } - public GoogleConsumer() { + /// <summary> + /// Gets the scope URI in Google's format. + /// </summary> + /// <param name="scope">The scope, which may include one or several Google applications.</param> + /// <returns>A space-delimited list of URIs for the requested Google applications.</returns> + public static string GetScopeUri(Applications scope) { + return string.Join(" ", Util.GetIndividualFlags(scope).Select(app => DataScopeUris[(Applications)app]).ToArray()); } /// <summary> /// Requests authorization from Google to access data from a set of Google applications. /// </summary> - /// <param name="consumer">The Google consumer previously constructed using <see cref="CreateWebConsumer" /> or <see cref="CreateDesktopConsumer" />.</param> /// <param name="requestedAccessScope">The requested access scope.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// A task that completes with the asynchronous operation. /// </returns> - /// <exception cref="System.ArgumentNullException">consumer</exception> public Task<Uri> RequestUserAuthorizationAsync(Applications requestedAccessScope, CancellationToken cancellationToken = default(CancellationToken)) { var extraParameters = new Dictionary<string, string> { { "scope", GetScopeUri(requestedAccessScope) }, @@ -175,7 +193,6 @@ namespace DotNetOpenAuth.ApplicationBlock { /// <summary> /// Gets the Gmail address book's contents. /// </summary> - /// <param name="consumer">The Google consumer.</param> /// <param name="accessToken">The access token previously retrieved.</param> /// <param name="maxResults">The maximum number of entries to return. If you want to receive all of the contacts, rather than only the default maximum, you can specify a very large number here.</param> /// <param name="startIndex">The 1-based index of the first result to be retrieved (for paging).</param> @@ -183,7 +200,6 @@ namespace DotNetOpenAuth.ApplicationBlock { /// <returns> /// An XML document returned by Google. /// </returns> - /// <exception cref="System.ArgumentNullException">consumer</exception> public async Task<XDocument> GetContactsAsync(AccessToken accessToken, int maxResults = 25, int startIndex = 1, CancellationToken cancellationToken = default(CancellationToken)) { // Enable gzip compression. Google only compresses the response for recognized user agent headers. - Mike Lim var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip }; @@ -244,14 +260,5 @@ namespace DotNetOpenAuth.ApplicationBlock { } } } - - /// <summary> - /// Gets the scope URI in Google's format. - /// </summary> - /// <param name="scope">The scope, which may include one or several Google applications.</param> - /// <returns>A space-delimited list of URIs for the requested Google applications.</returns> - public static string GetScopeUri(Applications scope) { - return string.Join(" ", Util.GetIndividualFlags(scope).Select(app => DataScopeUris[(Applications)app]).ToArray()); - } } } diff --git a/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs index 7bbfaa1..bb6f9d3 100644 --- a/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs +++ b/samples/DotNetOpenAuth.ApplicationBlock/TwitterConsumer.cs @@ -30,7 +30,7 @@ namespace DotNetOpenAuth.ApplicationBlock { /// <summary> /// A consumer capable of communicating with Twitter. /// </summary> - public static class TwitterConsumer { + public class TwitterConsumer : Consumer { /// <summary> /// The description of Twitter's OAuth protocol URIs for use with actually reading/writing /// a user's private Twitter data. @@ -64,19 +64,36 @@ namespace DotNetOpenAuth.ApplicationBlock { private static readonly Uri VerifyCredentialsEndpoint = new Uri("http://api.twitter.com/1/account/verify_credentials.xml"); - private class HostFactories : IHostFactories { - private static readonly IHostFactories underlyingFactories = new DefaultOAuthHostFactories(); - - public HttpMessageHandler CreateHttpMessageHandler() { - return new WebRequestHandler(); - } + /// <summary> + /// Initializes a new instance of the <see cref="TwitterConsumer"/> class. + /// </summary> + public TwitterConsumer() { + this.ServiceProvider = ServiceDescription; + this.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"]; + this.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"]; + this.TemporaryCredentialStorage = HttpContext.Current != null + ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() + : new MemoryTemporaryCredentialStorage(); + } - public HttpClient CreateHttpClient(HttpMessageHandler handler = null) { - var client = underlyingFactories.CreateHttpClient(handler); + /// <summary> + /// Initializes a new instance of the <see cref="TwitterConsumer"/> class. + /// </summary> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + public TwitterConsumer(string consumerKey, string consumerSecret) + : this() { + this.ConsumerKey = consumerKey; + this.ConsumerSecret = consumerSecret; + } - // Twitter can't handle the Expect 100 Continue HTTP header. - client.DefaultRequestHeaders.ExpectContinue = false; - return client; + /// <summary> + /// Gets a value indicating whether the Twitter consumer key and secret are set in the web.config file. + /// </summary> + public static bool IsTwitterConsumerConfigured { + get { + return !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerKey"]) && + !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerSecret"]); } } @@ -86,7 +103,7 @@ namespace DotNetOpenAuth.ApplicationBlock { if (IsTwitterConsumerConfigured) { ITemporaryCredentialStorage storage = forWeb ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() : new MemoryTemporaryCredentialStorage(); return new Consumer(consumerKey, consumerSecret, ServiceDescription, storage) { - HostFactories = new HostFactories(), + HostFactories = new TwitterHostFactories(), }; } else { throw new InvalidOperationException("No Twitter OAuth consumer key and secret could be found in web.config AppSettings."); @@ -94,17 +111,55 @@ namespace DotNetOpenAuth.ApplicationBlock { } /// <summary> - /// Gets a value indicating whether the Twitter consumer key and secret are set in the web.config file. + /// Prepares a redirect that will send the user to Twitter to sign in. /// </summary> - public static bool IsTwitterConsumerConfigured { - get { - return !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerKey"]) && - !string.IsNullOrEmpty(ConfigurationManager.AppSettings["twitterConsumerSecret"]); + /// <param name="forceNewLogin">if set to <c>true</c> the user will be required to re-enter their Twitter credentials even if already logged in to Twitter.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns> + /// The redirect message. + /// </returns> + /// <remarks> + /// Call <see cref="OutgoingWebResponse.Send" /> or + /// <c>return StartSignInWithTwitter().<see cref="MessagingUtilities.AsActionResult">AsActionResult()</see></c> + /// to actually perform the redirect. + /// </remarks> + 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 consumer = CreateConsumer(); + consumer.ServiceProvider = SignInWithTwitterServiceDescription; + Uri redirectUrl = await consumer.RequestUserAuthorizationAsync(callback, cancellationToken: cancellationToken); + return redirectUrl; + } + + /// <summary> + /// Checks the incoming web request to see if it carries a Twitter authentication response, + /// and provides the user's Twitter screen name and unique id if available. + /// </summary> + /// <param name="completeUrl">The URL that came back from the service provider to complete the authorization.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <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(Uri completeUrl = null, CancellationToken cancellationToken = default(CancellationToken)) { + var consumer = CreateConsumer(); + consumer.ServiceProvider = SignInWithTwitterServiceDescription; + var response = await consumer.ProcessUserAuthorizationAsync(completeUrl ?? HttpContext.Current.Request.Url, cancellationToken: cancellationToken); + if (response == null) { + return null; } + + string screenName = response.ExtraData["screen_name"]; + int userId = int.Parse(response.ExtraData["user_id"]); + return Tuple.Create(screenName, userId); } - public static async Task<JArray> GetUpdatesAsync(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { - using (var httpClient = twitter.CreateHttpClient(accessToken)) { + public async Task<JArray> GetUpdatesAsync(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { + using (var httpClient = this.CreateHttpClient(accessToken)) { using (var response = await httpClient.GetAsync(GetFriendTimelineStatusEndpoint, cancellationToken)) { response.EnsureSuccessStatusCode(); string jsonString = await response.Content.ReadAsStringAsync(); @@ -114,8 +169,8 @@ namespace DotNetOpenAuth.ApplicationBlock { } } - public static async Task<XDocument> GetFavorites(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { - using (var httpClient = twitter.CreateHttpClient(accessToken)) { + public async Task<XDocument> GetFavorites(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { + using (var httpClient = this.CreateHttpClient(accessToken)) { using (HttpResponseMessage response = await httpClient.GetAsync(GetFavoritesEndpoint, cancellationToken)) { response.EnsureSuccessStatusCode(); return XDocument.Parse(await response.Content.ReadAsStringAsync()); @@ -123,7 +178,7 @@ namespace DotNetOpenAuth.ApplicationBlock { } } - public static async Task<XDocument> UpdateProfileBackgroundImageAsync(Consumer twitter, AccessToken accessToken, string image, bool tile, CancellationToken cancellationToken) { + public async Task<XDocument> UpdateProfileBackgroundImageAsync(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); @@ -132,7 +187,7 @@ namespace DotNetOpenAuth.ApplicationBlock { content.Add(new StringContent(tile.ToString().ToLowerInvariant()), "tile"); request.Content = content; request.Headers.ExpectContinue = false; - using (var httpClient = twitter.CreateHttpClient(accessToken)) { + using (var httpClient = this.CreateHttpClient(accessToken)) { using (HttpResponseMessage response = await httpClient.SendAsync(request, cancellationToken)) { response.EnsureSuccessStatusCode(); string responseString = await response.Content.ReadAsStringAsync(); @@ -141,19 +196,19 @@ namespace DotNetOpenAuth.ApplicationBlock { } } - public static Task<XDocument> UpdateProfileImageAsync(Consumer twitter, AccessToken accessToken, string pathToImage, CancellationToken cancellationToken = default(CancellationToken)) { + public Task<XDocument> UpdateProfileImageAsync(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); + return this.UpdateProfileImageAsync(accessToken, File.OpenRead(pathToImage), contentType, cancellationToken); } - public static async Task<XDocument> UpdateProfileImageAsync(Consumer twitter, AccessToken accessToken, Stream image, string contentType, CancellationToken cancellationToken = default(CancellationToken)) { + public async Task<XDocument> UpdateProfileImageAsync(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); var content = new MultipartFormDataContent(); content.Add(imageAttachment, "image", "twitterPhoto"); request.Content = content; - using (var httpClient = twitter.CreateHttpClient(accessToken)) { + using (var httpClient = this.CreateHttpClient(accessToken)) { using (HttpResponseMessage response = await httpClient.SendAsync(request, cancellationToken)) { response.EnsureSuccessStatusCode(); string responseString = await response.Content.ReadAsStringAsync(); @@ -162,8 +217,8 @@ namespace DotNetOpenAuth.ApplicationBlock { } } - public static async Task<XDocument> VerifyCredentialsAsync(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { - using (var httpClient = twitter.CreateHttpClient(accessToken)) { + public async Task<XDocument> VerifyCredentialsAsync(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { + using (var httpClient = this.CreateHttpClient(accessToken)) { using (var response = await httpClient.GetAsync(VerifyCredentialsEndpoint, cancellationToken)) { response.EnsureSuccessStatusCode(); using (var stream = await response.Content.ReadAsStreamAsync()) { @@ -173,57 +228,26 @@ namespace DotNetOpenAuth.ApplicationBlock { } } - public static async Task<string> GetUsername(Consumer twitter, AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { - XDocument xml = await VerifyCredentialsAsync(twitter, accessToken, cancellationToken); + public async Task<string> GetUsername(AccessToken accessToken, CancellationToken cancellationToken = default(CancellationToken)) { + XDocument xml = await this.VerifyCredentialsAsync(accessToken, cancellationToken); XPathNavigator nav = xml.CreateNavigator(); return nav.SelectSingleNode("/user/screen_name").Value; } - /// <summary> - /// Prepares a redirect that will send the user to Twitter to sign in. - /// </summary> - /// <param name="forceNewLogin">if set to <c>true</c> the user will be required to re-enter their Twitter credentials even if already logged in to Twitter.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns> - /// The redirect message. - /// </returns> - /// <remarks> - /// Call <see cref="OutgoingWebResponse.Send" /> or - /// <c>return StartSignInWithTwitter().<see cref="MessagingUtilities.AsActionResult">AsActionResult()</see></c> - /// to actually perform the redirect. - /// </remarks> - 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"; + private class TwitterHostFactories : IHostFactories { + private static readonly IHostFactories underlyingFactories = new DefaultOAuthHostFactories(); + + public HttpMessageHandler CreateHttpMessageHandler() { + return new WebRequestHandler(); } - Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix("oauth_"); - var consumer = CreateConsumer(); - consumer.ServiceProvider = SignInWithTwitterServiceDescription; - Uri redirectUrl = await consumer.RequestUserAuthorizationAsync(callback, cancellationToken: cancellationToken); - return redirectUrl; - } + public HttpClient CreateHttpClient(HttpMessageHandler handler = null) { + var client = underlyingFactories.CreateHttpClient(handler); - /// <summary> - /// Checks the incoming web request to see if it carries a Twitter authentication response, - /// and provides the user's Twitter screen name and unique id if available. - /// </summary> - /// <param name="cancellationToken">The cancellation token.</param> - /// <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(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; + // Twitter can't handle the Expect 100 Continue HTTP header. + client.DefaultRequestHeaders.ExpectContinue = false; + return client; } - - string screenName = response.ExtraData["screen_name"]; - int userId = int.Parse(response.ExtraData["user_id"]); - return Tuple.Create(screenName, userId); } } } diff --git a/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs index 4bcb112..1dff5b6 100644 --- a/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs +++ b/samples/DotNetOpenAuth.ApplicationBlock/YammerConsumer.cs @@ -13,12 +13,13 @@ namespace DotNetOpenAuth.ApplicationBlock { using System.Text; using System.Threading; using System.Threading.Tasks; + using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; - public static class YammerConsumer { + public class YammerConsumer : Consumer { /// <summary> /// The Consumer to use for accessing Google data APIs. /// </summary> @@ -28,6 +29,15 @@ namespace DotNetOpenAuth.ApplicationBlock { "https://www.yammer.com/oauth/authorize", "https://www.yammer.com/oauth/access_token"); + public YammerConsumer() { + this.ServiceProvider = ServiceDescription; + this.ConsumerKey = ConfigurationManager.AppSettings["YammerConsumerKey"]; + this.ConsumerSecret = ConfigurationManager.AppSettings["YammerConsumerSecret"]; + this.TemporaryCredentialStorage = HttpContext.Current != null + ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() + : new MemoryTemporaryCredentialStorage(); + } + /// <summary> /// Gets a value indicating whether the Twitter consumer key and secret are set in the web.config file. /// </summary> @@ -37,16 +47,5 @@ namespace DotNetOpenAuth.ApplicationBlock { !string.IsNullOrEmpty(ConfigurationManager.AppSettings["yammerConsumerSecret"]); } } - - public static Consumer CreateConsumer(bool forWeb = true) { - string consumerKey = ConfigurationManager.AppSettings["yammerConsumerKey"]; - string consumerSecret = ConfigurationManager.AppSettings["yammerConsumerSecret"]; - if (IsConsumerConfigured) { - ITemporaryCredentialStorage storage = forWeb ? (ITemporaryCredentialStorage)new CookieTemporaryCredentialStorage() : new MemoryTemporaryCredentialStorage(); - return new Consumer(consumerKey, consumerSecret, ServiceDescription, storage); - } else { - throw new InvalidOperationException("No Yammer OAuth consumer key and secret could be found in web.config AppSettings."); - } - } } } |