1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
//-----------------------------------------------------------------------
// <copyright file="GoogleConsumer.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace DotNetOAuth.CommonConsumers {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using DotNetOAuth.ChannelElements;
using DotNetOAuth.Messaging;
/// <summary>
/// A consumer capable of communicating with Google Data APIs.
/// </summary>
public class GoogleConsumer : CommonConsumerBase {
/// <summary>
/// The Consumer to use for accessing Google data APIs.
/// </summary>
private static readonly ServiceProviderDescription GoogleDescription = new ServiceProviderDescription {
RequestTokenEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
UserAuthorizationEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthAuthorizeToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
AccessTokenEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetAccessToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
};
/// <summary>
/// A mapping between Google's applications and their URI scope values.
/// </summary>
private static readonly Dictionary<Applications, string> DataScopeUris = new Dictionary<Applications, string> {
{ Applications.Contacts, "http://www.google.com/m8/feeds/" },
{ Applications.Calendar, "http://www.google.com/calendar/feeds/" },
};
/// <summary>
/// The URI to get contacts once authorization is granted.
/// </summary>
private static readonly MessageReceivingEndpoint GetContactsEndpoint = new MessageReceivingEndpoint("http://www.google.com/m8/feeds/contacts/default/full/", HttpDeliveryMethods.GetRequest);
/// <summary>
/// Initializes a new instance of the <see cref="GoogleConsumer"/> class.
/// </summary>
/// <param name="tokenManager">The token manager.</param>
/// <param name="consumerKey">The consumer key.</param>
public GoogleConsumer(ITokenManager tokenManager, string consumerKey)
: base(GoogleDescription, tokenManager, consumerKey) {
}
/// <summary>
/// The many specific authorization scopes Google offers.
/// </summary>
[Flags]
public enum Applications : long {
/// <summary>
/// The Gmail address book.
/// </summary>
Contacts = 0x1,
/// <summary>
/// Appointments in Google Calendar.
/// </summary>
Calendar = 0x2,
}
/// <summary>
/// Requests authorization from Google to access data from a set of Google applications.
/// </summary>
/// <param name="requestedAccessScope">The requested access scope.</param>
public void RequestAuthorization(Applications requestedAccessScope) {
Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix(Protocol.Default.ParameterPrefix);
var extraParameters = new Dictionary<string, string> {
{ "scope", this.GetScopeUri(requestedAccessScope) },
};
var request = this.Consumer.PrepareRequestUserAuthorization(callback, extraParameters, null);
this.Consumer.Channel.Send(request).Send();
}
/// <summary>
/// Gets the access token on the next page request after a call to <see cref="RequestAuthorization"/>.
/// </summary>
/// <returns>The access token that should be stored for later use.</returns>
public string GetAccessToken() {
var response = this.Consumer.ProcessUserAuthorization();
return response != null ? response.AccessToken : null;
}
/// <summary>
/// Gets the Gmail address book's contents.
/// </summary>
/// <param name="accessToken">The access token previously retrieved from the <see cref="GetAccessToken"/> method.</param>
/// <returns>An XML document returned by Google.</returns>
public XDocument GetContacts(string accessToken) {
var response = this.PrepareAuthorizedRequestAndSend(GetContactsEndpoint, accessToken);
XDocument result = XDocument.Parse(response.Body);
return result;
}
/// <summary>
/// A general method for sending OAuth-authorized requests for user data from Google.
/// </summary>
/// <param name="endpoint">The Google URL to retrieve the data from.</param>
/// <param name="accessToken">The access token previously retrieved from the <see cref="GetAccessToken"/> method.</param>
/// <returns>Whatever the response Google sends.</returns>
public Response PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, string accessToken) {
return this.Consumer.PrepareAuthorizedRequestAndSend(endpoint, accessToken);
}
/// <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>
private string GetScopeUri(Applications scope) {
return string.Join(" ", GetIndividualFlags(scope).Select(app => DataScopeUris[(Applications)app]).ToArray());
}
}
}
|