//-----------------------------------------------------------------------
//
// 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;
}
}
}