summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveClient.cs
blob: ffbbf26308fcb2d0fd64cd33350a14db5911d69e (plain)
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
//-----------------------------------------------------------------------
// <copyright file="WindowsLiveClient.cs" company="Microsoft">
//     Copyright (c) Microsoft. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.AspNet.Clients {
	using System;
	using System.Collections.Generic;
	using System.IO;
	using System.Net;
	using System.Text;
	using DotNetOpenAuth.Messaging;

	public sealed class WindowsLiveClient : OAuth2Client {
		private const string TokenEndpoint = "https://oauth.live.com/token";
		private const string AuthorizationEndpoint = "https://oauth.live.com/authorize";
		private readonly string _appId;
		private readonly string _appSecret;

		public WindowsLiveClient(string appId, string appSecret)
			: base("windowslive") {
			if (String.IsNullOrEmpty(appId)) {
				throw new ArgumentNullException("appId");
			}

			if (String.IsNullOrEmpty("appSecret")) {
				throw new ArgumentNullException("appSecret");
			}

			_appId = appId;
			_appSecret = appSecret;
		}

		protected override Uri GetServiceLoginUrl(Uri returnUrl) {
			var builder = new UriBuilder(AuthorizationEndpoint);
			MessagingUtilities.AppendQueryArgs(builder,
				new KeyValuePair<string, string>[]
				{
					new KeyValuePair<string, string>("client_id", _appId),
					new KeyValuePair<string, string>("scope", "wl.basic"),
					new KeyValuePair<string, string>("response_type", "code"),
					new KeyValuePair<string, string>("redirect_uri", returnUrl.ToString())
				});

			return builder.Uri;
		}

		protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) {
			var builder = new StringBuilder();
			builder.AppendFormat("client_id={0}", _appId);
			builder.AppendFormat("&redirect_uri={0}", Uri.EscapeDataString(returnUrl.ToString()));
			builder.AppendFormat("&client_secret={0}", _appSecret);
			builder.AppendFormat("&code={0}", authorizationCode);
			builder.Append("&grant_type=authorization_code");

			WebRequest tokenRequest = WebRequest.Create(TokenEndpoint);
			tokenRequest.ContentType = "application/x-www-form-urlencoded";
			tokenRequest.ContentLength = builder.Length;
			tokenRequest.Method = "POST";

			using (Stream requestStream = tokenRequest.GetRequestStream()) {
				var writer = new StreamWriter(requestStream);
				writer.Write(builder.ToString());
				writer.Flush();
			}

			HttpWebResponse tokenResponse = (HttpWebResponse)tokenRequest.GetResponse();
			if (tokenResponse.StatusCode == HttpStatusCode.OK) {
				using (Stream responseStream = tokenResponse.GetResponseStream()) {
					var tokenData = JsonHelper.Deserialize<OAuth2AccessTokenData>(responseStream);
					if (tokenData != null) {
						return tokenData.AccessToken;
					}
				}
			}

			return null;
		}

		protected override IDictionary<string, string> GetUserData(string accessToken) {
			WindowsLiveUserData graph;
			var request = WebRequest.Create("https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(accessToken));
			using (var response = request.GetResponse()) {
				using (var responseStream = response.GetResponseStream()) {
					graph = JsonHelper.Deserialize<WindowsLiveUserData>(responseStream);
				}
			}

			var userData = new Dictionary<string, string>();
			userData.AddItemIfNotEmpty("id", graph.Id);
			userData.AddItemIfNotEmpty("username", graph.Name);
			userData.AddItemIfNotEmpty("name", graph.Name);
			userData.AddItemIfNotEmpty("link", graph.Link == null ? null : graph.Link.ToString());
			userData.AddItemIfNotEmpty("gender", graph.Gender);
			userData.AddItemIfNotEmpty("firstname", graph.FirstName);
			userData.AddItemIfNotEmpty("lastname", graph.LastName);
			return userData;
		}
	}
}