//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOAuth {
using System;
using System.Collections.Generic;
using System.Net;
using DotNetOAuth.ChannelElements;
using DotNetOAuth.Messages;
using DotNetOAuth.Messaging;
using DotNetOAuth.Messaging.Bindings;
///
/// A website or application that uses OAuth to access the Service Provider on behalf of the User.
///
public class Consumer {
///
/// 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.
public Consumer(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.Channel = new OAuthChannel(signingElement, store, new OAuthMessageTypeProvider(tokenManager), this.WebRequestHandler);
this.ServiceProvider = serviceDescription;
this.TokenManager = tokenManager;
}
///
/// Gets or sets the Consumer Key used to communicate with the Service Provider.
///
public string ConsumerKey { get; set; }
///
/// Gets or sets the Consumer Secret used to communicate with the Service Provider.
///
public string ConsumerSecret { 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; private 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; }
///
/// Gets or sets the channel to use for sending/receiving messages.
///
internal OAuthChannel Channel { get; set; }
///
/// Begins an OAuth authorization request and redirects 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.
/// The pending user agent redirect based message to be sent as an HttpResponse.
public Response RequestUserAuthorization(Uri callback, IDictionary extraParameters) {
// Obtain an unauthorized request token.
var requestToken = new RequestTokenMessage(this.ServiceProvider.RequestTokenEndpoint) {
ConsumerKey = this.ConsumerKey,
ConsumerSecret = this.ConsumerSecret,
};
requestToken.AddNonOAuthParameters(extraParameters);
var requestTokenResponse = this.Channel.Request(requestToken);
this.TokenManager.StoreNewRequestToken(this.ConsumerKey, requestTokenResponse.RequestToken, requestTokenResponse.TokenSecret, null/*TODO*/);
// Request user authorization.
var requestAuthorization = new DirectUserToServiceProviderMessage(this.ServiceProvider.UserAuthorizationEndpoint) {
Callback = callback,
RequestToken = requestTokenResponse.RequestToken,
};
return this.Channel.Send(requestAuthorization);
}
///
/// Processes an incoming authorization-granted message from an SP and obtains an access token.
///
/// The access token.
public string ProcessUserAuthorization() {
var authorizationMessage = this.Channel.ReadFromRequest();
// Exchange request token for access token.
string requestTokenSecret = this.TokenManager.GetTokenSecret(authorizationMessage.RequestToken);
var requestAccess = new RequestAccessTokenMessage(this.ServiceProvider.AccessTokenEndpoint) {
RequestToken = authorizationMessage.RequestToken,
TokenSecret = requestTokenSecret,
ConsumerKey = this.ConsumerKey,
ConsumerSecret = this.ConsumerSecret,
};
var grantAccess = this.Channel.Request(requestAccess);
this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, authorizationMessage.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
return grantAccess.AccessToken;
}
///
/// 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 CreateAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) {
IDirectedProtocolMessage message = this.CreateAuthorizedRequestInternal(endpoint, accessToken);
WebRequest wr = this.Channel.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 SendAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) {
IDirectedProtocolMessage message = this.CreateAuthorizedRequestInternal(endpoint, accessToken);
HttpWebRequest wr = this.Channel.InitializeRequest(message);
return this.WebRequestHandler.GetResponse(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.
internal AccessProtectedResourcesMessage CreateAuthorizedRequestInternal(MessageReceivingEndpoint endpoint, string accessToken) {
if (endpoint == null) {
throw new ArgumentNullException("endpoint");
}
if (String.IsNullOrEmpty(accessToken)) {
throw new ArgumentNullException("accessToken");
}
AccessProtectedResourcesMessage message = new AccessProtectedResourcesMessage(endpoint) {
AccessToken = accessToken,
TokenSecret = this.TokenManager.GetTokenSecret(accessToken),
ConsumerKey = this.ConsumerKey,
ConsumerSecret = this.ConsumerSecret,
};
return message;
}
}
}