//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Net; using DotNetOAuth.ChannelElements; using DotNetOAuth.Messages; using DotNetOAuth.Messaging; using DotNetOAuth.Messaging.Bindings; /// /// Base class for and types. /// public class ConsumerBase { /// /// Initializes a new instance of the class. /// /// The endpoints and behavior of the Service Provider. /// The host's method of storing and recalling tokens and secrets. protected ConsumerBase(ServiceProviderDescription serviceDescription, ITokenManager tokenManager) { if (serviceDescription == null) { throw new ArgumentNullException("serviceDescription"); } if (tokenManager == null) { throw new ArgumentNullException("tokenManager"); } this.WebRequestHandler = new StandardWebRequestHandler(); ITamperProtectionChannelBindingElement signingElement = serviceDescription.CreateTamperProtectionElement(); INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge); this.OAuthChannel = new OAuthChannel(signingElement, store, tokenManager, new OAuthConsumerMessageTypeProvider(), this.WebRequestHandler); this.ServiceProvider = serviceDescription; } /// /// Gets or sets the Consumer Key used to communicate with the Service Provider. /// public string ConsumerKey { get; set; } /// /// Gets the Service Provider that will be accessed. /// public ServiceProviderDescription ServiceProvider { get; private set; } /// /// Gets the persistence store for tokens and secrets. /// public ITokenManager TokenManager { get { return this.OAuthChannel.TokenManager; } } /// /// Gets the channel to use for sending/receiving messages. /// public Channel Channel { get { return this.OAuthChannel; } } /// /// Gets or sets the channel to use for sending/receiving messages. /// internal OAuthChannel OAuthChannel { get; set; } /// /// Gets or sets the object that processes s. /// /// /// This defaults to a straightforward implementation, but can be set /// to a mock object for testing purposes. /// internal IWebRequestHandler WebRequestHandler { get; set; } /// /// Creates a web request prepared with OAuth authorization /// that may be further tailored by adding parameters by the caller. /// /// The URL and method on the Service Provider to send the request to. /// The access token that permits access to the protected resource. /// The initialized WebRequest object. public WebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) { IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken); HttpWebRequest wr = this.OAuthChannel.InitializeRequest(message); return wr; } /// /// Creates a web request prepared with OAuth authorization /// that may be further tailored by adding parameters by the caller. /// /// The URL and method on the Service Provider to send the request to. /// The access token that permits access to the protected resource. /// The initialized WebRequest object. /// Thrown if the request fails for any reason after it is sent to the Service Provider. public Response PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, string accessToken) { IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken); HttpWebRequest wr = this.OAuthChannel.InitializeRequest(message); return this.WebRequestHandler.GetResponse(wr); } /// /// Prepares an OAuth message that begins an authorization request that will /// redirect the user to the Service Provider to provide that authorization. /// /// /// An optional Consumer URL that the Service Provider should redirect the /// User Agent to upon successful authorization. /// /// Extra parameters to add to the request token message. Optional. /// Extra parameters to add to the redirect to Service Provider message. Optional. /// The request token that must be exchanged for an access token after the user has provided authorization. /// The pending user agent redirect based message to be sent as an HttpResponse. [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "3#", Justification = "Two results")] protected internal UserAuthorizationRequest PrepareRequestUserAuthorization(Uri callback, IDictionary requestParameters, IDictionary redirectParameters, out string requestToken) { // Obtain an unauthorized request token. var token = new UnauthorizedTokenRequest(this.ServiceProvider.RequestTokenEndpoint) { ConsumerKey = this.ConsumerKey, }; token.AddNonOAuthParameters(requestParameters); var requestTokenResponse = this.Channel.Request(token); this.TokenManager.StoreNewRequestToken(token, requestTokenResponse); // Request user authorization. ITokenContainingMessage assignedRequestToken = requestTokenResponse; var requestAuthorization = new UserAuthorizationRequest(this.ServiceProvider.UserAuthorizationEndpoint, assignedRequestToken.Token) { Callback = callback, }; requestAuthorization.AddNonOAuthParameters(redirectParameters); requestToken = requestAuthorization.RequestToken; return requestAuthorization; } /// /// Creates a web request prepared with OAuth authorization /// that may be further tailored by adding parameters by the caller. /// /// The URL and method on the Service Provider to send the request to. /// The access token that permits access to the protected resource. /// The initialized WebRequest object. protected internal AccessProtectedResourceRequest CreateAuthorizingMessage(MessageReceivingEndpoint endpoint, string accessToken) { if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (String.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException("accessToken"); } AccessProtectedResourceRequest message = new AccessProtectedResourceRequest(endpoint) { AccessToken = accessToken, ConsumerKey = this.ConsumerKey, }; return message; } /// /// Exchanges a given request token for access token. /// /// The request token that the user has authorized. /// The access token assigned by the Service Provider. protected AuthorizedTokenResponse ProcessUserAuthorization(string requestToken) { var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint) { RequestToken = requestToken, ConsumerKey = this.ConsumerKey, }; var grantAccess = this.Channel.Request(requestAccess); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestToken, grantAccess.AccessToken, grantAccess.TokenSecret); return grantAccess; } } }