diff options
author | András Fuchs <andras.fuchs@gmail.com> | 2013-05-26 07:54:53 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2013-05-26 07:54:53 -0700 |
commit | 2a4da5e544a22d30d5b54a2696194d814d9a442f (patch) | |
tree | ed76c7421e9669bbf263381139a29afb8eb23433 /samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive | |
parent | 85c21ae12f04cc50a0478cf69c82d441da23d002 (diff) | |
download | DotNetOpenAuth-2a4da5e544a22d30d5b54a2696194d814d9a442f.zip DotNetOpenAuth-2a4da5e544a22d30d5b54a2696194d814d9a442f.tar.gz DotNetOpenAuth-2a4da5e544a22d30d5b54a2696194d814d9a442f.tar.bz2 |
Samples improvements
The part which I needed
to improve is the ApplicationBlock where I changed the OAuth2 classes'
structure a little and extended them with a lot of useful
functionality, like adding many Facebook and WindowsLive scopes,
fields, structures including the asked-by-many easy to use birthdate
and avatar url getters. I have also implemented the Google OAuth2
authentication and created one common interface for all 3 Graphs in
the code (which has the common properties like Id, FirstName,
LastName, etc.), so the authentication code became really simple if
you use my version of your ApplicationBlock.
Diffstat (limited to 'samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive')
-rw-r--r-- | samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveClient.cs | 181 | ||||
-rw-r--r-- | samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveGraph.cs | 299 |
2 files changed, 480 insertions, 0 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveClient.cs b/samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveClient.cs new file mode 100644 index 0000000..24322af --- /dev/null +++ b/samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveClient.cs @@ -0,0 +1,181 @@ +//----------------------------------------------------------------------- +// <copyright file="WindowsLiveClient.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.ApplicationBlock { + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth2; + + public class WindowsLiveClient : WebServerClient { + private static readonly AuthorizationServerDescription WindowsLiveDescription = new AuthorizationServerDescription { + TokenEndpoint = new Uri("https://oauth.live.com/token"), + AuthorizationEndpoint = new Uri("https://oauth.live.com/authorize"), + ProtocolVersion = ProtocolVersion.V20 + }; + + /// <summary> + /// Initializes a new instance of the <see cref="WindowsLiveClient"/> class. + /// </summary> + public WindowsLiveClient() + : base(WindowsLiveDescription) { + } + + public IOAuth2Graph GetGraph(IAuthorizationState authState, string[] fields = null) { + if ((authState != null) && (authState.AccessToken != null)) { + WebRequest request = WebRequest.Create("https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(authState.AccessToken)); + WebResponse response = request.GetResponse(); + + if (response != null) { + Stream responseStream = response.GetResponseStream(); + + if (responseStream != null) { + // string debugJsonStr = new StreamReader(responseStream).ReadToEnd(); + WindowsLiveGraph windowsLiveGraph = WindowsLiveGraph.Deserialize(responseStream); + + // picture type resolution test 1 + // &type=small 96x96 + // &type=medium 96x96 + // &type=large 448x448 + + windowsLiveGraph.AvatarUrl = new Uri("https://apis.live.net/v5.0/me/picture?access_token=" + Uri.EscapeDataString(authState.AccessToken)); + + return windowsLiveGraph; + } + } + } + + return null; + } + + /// <summary> + /// Well-known scopes defined by the Windows Live service. + /// </summary> + /// <remarks> + /// This sample includes just a few scopes. For a complete list of scopes please refer to: + /// http://msdn.microsoft.com/en-us/library/hh243646.aspx + /// </remarks> + public static class Scopes { + #region Core Scopes + + /// <summary> + /// The ability of an app to read and update a user's info at any time. Without this scope, an app can access the user's info only while the user is signed in to Live Connect and is using your app. + /// </summary> + public const string OfflineAccess = "wl.offline_access"; + + /// <summary> + /// Single sign-in behavior. With single sign-in, users who are already signed in to Live Connect are also signed in to your website. + /// </summary> + public const string SignIn = "wl.signin"; + + /// <summary> + /// Read access to a user's basic profile info. Also enables read access to a user's list of contacts. + /// </summary> + public const string Basic = "wl.basic"; + + #endregion + + #region Extended Scopes + + /// <summary> + /// Read access to a user's birthday info including birth day, month, and year. + /// </summary> + public const string Birthday = "wl.birthday"; + + /// <summary> + /// Read access to a user's calendars and events. + /// </summary> + public const string Calendars = "wl.calendars"; + + /// <summary> + /// Read and write access to a user's calendars and events. + /// </summary> + public const string CalendarsUpdate = "wl.calendars_update"; + + /// <summary> + /// Read access to the birth day and birth month of a user's contacts. Note that this also gives read access to the user's birth day, birth month, and birth year. + /// </summary> + public const string ContactsBirthday = "wl.contacts_birthday"; + + /// <summary> + /// Creation of new contacts in the user's address book. + /// </summary> + public const string ContactsCreate = "wl.contacts_create"; + + /// <summary> + /// Read access to a user's calendars and events. Also enables read access to any calendars and events that other users have shared with the user. + /// </summary> + public const string ContactsCalendars = "wl.contacts_calendars"; + + /// <summary> + /// Read access to a user's albums, photos, videos, and audio, and their associated comments and tags. Also enables read access to any albums, photos, videos, and audio that other users have shared with the user. + /// </summary> + public const string ContactsPhotos = "wl.contacts_photos"; + + /// <summary> + /// Read access to Microsoft SkyDrive files that other users have shared with the user. Note that this also gives read access to the user's files stored in SkyDrive. + /// </summary> + public const string ContactsSkydrive = "wl.contacts_skydrive"; + + /// <summary> + /// Read access to a user's personal, preferred, and business email addresses. + /// </summary> + public const string Emails = "wl.emails"; + + /// <summary> + /// Creation of events on the user's default calendar. + /// </summary> + public const string EventsCreate = "wl.events_create"; + + /// <summary> + /// Enables signing in to the Windows Live Messenger Extensible Messaging and Presence Protocol (XMPP) service. + /// </summary> + public const string Messenger = "wl.messenger"; + + /// <summary> + /// Read access to a user's personal, business, and mobile phone numbers. + /// </summary> + public const string PhoneNumbers = "wl.phone_numbers"; + + /// <summary> + /// Read access to a user's photos, videos, audio, and albums. + /// </summary> + public const string Photos = "wl.photos"; + + /// <summary> + /// Read access to a user's postal addresses. + /// </summary> + public const string PostalAddresses = "wl.postal_addresses"; + + /// <summary> + /// Enables updating a user's status message. + /// </summary> + public const string Share = "wl.share"; + + /// <summary> + /// Read access to a user's files stored in SkyDrive. + /// </summary> + public const string Skydrive = "wl.skydrive"; + + /// <summary> + /// Read and write access to a user's files stored in SkyDrive. + /// </summary> + public const string SkydriveUpdate = "wl.skydrive_update"; + + /// <summary> + /// Read access to a user's employer and work position information. + /// </summary> + public const string WorkProfile = "wl.work_profile"; + + #endregion + } + } +} diff --git a/samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveGraph.cs b/samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveGraph.cs new file mode 100644 index 0000000..38095a5 --- /dev/null +++ b/samples/DotNetOpenAuth.ApplicationBlock/OAuth2/WindowsLive/WindowsLiveGraph.cs @@ -0,0 +1,299 @@ +//----------------------------------------------------------------------- +// <copyright file="WindowsLiveGraph.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.ApplicationBlock { + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Runtime.Serialization; + using System.Runtime.Serialization.Json; + using System.Text; + + //// Documentation: http://msdn.microsoft.com/en-us/library/live/hh243648.aspx#user + + [DataContract] + public class WindowsLiveGraph : IOAuth2Graph { + private static DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(WindowsLiveGraph)); + + /// <summary> + /// The user's ID. + /// </summary> + [DataMember(Name = "id", IsRequired = true)] + public string Id { get; set; } + + /// <summary> + /// The user's full name. + /// </summary> + [DataMember(Name = "name", IsRequired = true)] + public string Name { get; set; } + + /// <summary> + /// The user's first name. + /// </summary> + [DataMember(Name = "first_name")] + public string FirstName { get; set; } + + /// <summary> + /// The user's last name. + /// </summary> + [DataMember(Name = "last_name")] + public string LastName { get; set; } + + /// <summary> + /// The URL of the user's profile page. + /// </summary> + [DataMember(Name = "link")] + public Uri Link { get; set; } + + /// <summary> + /// The day of the user's birth date, or null if no birth date is specified. + /// </summary> + [DataMember(Name = "birth_day")] + public int? BirthDay { get; set; } + + /// <summary> + /// The month of the user's birth date, or null if no birth date is specified. + /// </summary> + [DataMember(Name = "birth_month")] + public int? BirthMonth { get; set; } + + /// <summary> + /// The year of the user's birth date, or null if no birth date is specified. + /// </summary> + [DataMember(Name = "birth_year")] + public int? BirthYear { get; set; } + + /// <summary> + /// An array that contains the user's work info. + /// </summary> + [DataMember(Name = "work")] + public WindowsLiveWorkProfile[] Work { get; set; } + + /// <summary> + /// The user's gender. Valid values are "male", "female", or null if the user's gender is not specified. + /// </summary> + [DataMember(Name = "gender")] + public string Gender { get; set; } + + /// <summary> + /// The user's email addresses. + /// </summary> + [DataMember(Name = "emails")] + public WindowsLiveEmails Emails { get; set; } + + /// <summary> + /// The user's postal addresses. + /// </summary> + [DataMember(Name = "addresses")] + public WindowsLiveAddresses Addresses { get; set; } + + /// <summary> + /// The user's phone numbers. + /// </summary> + [DataMember(Name = "phones")] + public WindowsLivePhones Phones { get; set; } + + /// <summary> + /// The user's locale code. + /// </summary> + [DataMember(Name = "locale", IsRequired = true)] + public string Locale { get; set; } + + /// <summary> + /// The time, in ISO 8601 format, at which the user last updated the object. + /// </summary> + [DataMember(Name = "updated_time")] + public string UpdatedTime { get; set; } + + public string Email { + get { + return this.Emails.Account; + } + } + + public Uri AvatarUrl { get; set; } + + public DateTime? BirthdayDT { + get { + if (this.BirthYear.HasValue && this.BirthMonth.HasValue && this.BirthDay.HasValue) { + return new DateTime(this.BirthYear.Value, this.BirthMonth.Value, this.BirthDay.Value); + } + + return null; + } + } + + public HumanGender GenderEnum { + get { + if (this.Gender == "male") { + return HumanGender.Male; + } else if (this.Gender == "female") { + return HumanGender.Female; + } + + return HumanGender.Unknown; + } + } + + public static WindowsLiveGraph Deserialize(string json) { + if (string.IsNullOrEmpty(json)) { + throw new ArgumentNullException("json"); + } + + return Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(json))); + } + + public static WindowsLiveGraph Deserialize(Stream jsonStream) { + if (jsonStream == null) { + throw new ArgumentNullException("jsonStream"); + } + + return (WindowsLiveGraph)jsonSerializer.ReadObject(jsonStream); + } + + [DataContract] + public class WindowsLiveEmails { + /// <summary> + /// The user's preferred email address, or null if one is not specified. + /// </summary> + [DataMember(Name = "preferred")] + public string Preferred { get; set; } + + /// <summary> + /// The email address that is associated with the account. + /// </summary> + [DataMember(Name = "account", IsRequired = true)] + public string Account { get; set; } + + /// <summary> + /// The user's personal email address, or null if one is not specified. + /// </summary> + [DataMember(Name = "personal")] + public string Personal { get; set; } + + /// <summary> + /// The user's business email address, or null if one is not specified. + /// </summary> + [DataMember(Name = "business")] + public string Business { get; set; } + + /// <summary> + /// The user's "alternate" email address, or null if one is not specified. + /// </summary> + [DataMember(Name = "other")] + public string Other { get; set; } + } + + [DataContract] + public class WindowsLivePhones { + /// <summary> + /// The user's personal phone number, or null if one is not specified. + /// </summary> + [DataMember(Name = "personal")] + public string Personal { get; set; } + + /// <summary> + /// The user's business phone number, or null if one is not specified. + /// </summary> + [DataMember(Name = "business")] + public string Business { get; set; } + + /// <summary> + /// The user's mobile phone number, or null if one is not specified. + /// </summary> + [DataMember(Name = "mobile")] + public string Mobile { get; set; } + } + + [DataContract] + public class WindowsLiveAddress { + /// <summary> + /// The street address, or null if one is not specified. + /// </summary> + [DataMember(Name = "street")] + public string Street { get; set; } + + /// <summary> + /// The second line of the street address, or null if one is not specified. + /// </summary> + [DataMember(Name = "street_2")] + public string Street2 { get; set; } + + /// <summary> + /// The city of the address, or null if one is not specified. + /// </summary> + [DataMember(Name = "city")] + public string City { get; set; } + + /// <summary> + /// The state of the address, or null if one is not specified. + /// </summary> + [DataMember(Name = "state")] + public string State { get; set; } + + /// <summary> + /// The postal code of the address, or null if one is not specified. + /// </summary> + [DataMember(Name = "postal_code")] + public string PostalCode { get; set; } + + /// <summary> + /// The region of the address, or null if one is not specified. + /// </summary> + [DataMember(Name = "region")] + public string Region { get; set; } + } + + [DataContract] + public class WindowsLiveAddresses { + /// <summary> + /// The user's personal postal address. + /// </summary> + [DataMember(Name = "personal")] + public WindowsLiveAddress Personal { get; set; } + + /// <summary> + /// The user's business postal address. + /// </summary> + [DataMember(Name = "business")] + public WindowsLiveAddress Business { get; set; } + } + + [DataContract] + public class WindowsLiveWorkProfile { + /// <summary> + /// Info about the user's employer. + /// </summary> + [DataMember(Name = "employer")] + public WindowsLiveEmployer Employer { get; set; } + + /// <summary> + /// Info about the user's employer. + /// </summary> + [DataMember(Name = "position")] + public WindowsLivePosition Position { get; set; } + } + + [DataContract] + public class WindowsLiveEmployer { + /// <summary> + /// The name of the user's employer, or null if the employer's name is not specified. + /// </summary> + [DataMember(Name = "name")] + public string Name { get; set; } + } + + [DataContract] + public class WindowsLivePosition { + /// <summary> + /// The name of the user's work position, or null if the name of the work position is not specified. + /// </summary> + [DataMember(Name = "name")] + public string Name { get; set; } + } + } +} |