PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/Code/Channels/Hotmail/HotmailContactsChannel.cs

http://github.com/waseems/inbox2_desktop
C# | 171 lines | 136 code | 29 blank | 6 comment | 3 complexity | 1ec79211c71c1650764de6c2dd710267 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.IO;
  5. using System.IO.Compression;
  6. using System.Linq;
  7. using System.ServiceModel;
  8. using System.ServiceModel.Description;
  9. using System.ServiceModel.Web;
  10. using System.Xml;
  11. using System.Xml.Linq;
  12. using Inbox2.Channels.Hotmail.REST;
  13. using Inbox2.Platform.Channels.ServiceModel;
  14. using Inbox2.Platform.Channels.Entities;
  15. using Inbox2.Platform.Channels.Interfaces;
  16. namespace Inbox2.Channels.Hotmail
  17. {
  18. class HotmailContactsChannel : IClientContactsChannel
  19. {
  20. protected const string contactsFeedUrl = "https://livecontacts.services.live.com/users/@L@{0}/REST/LiveContacts/Contacts";
  21. private const string appId = "000000004C00C9B8";
  22. private const string secretKey = "3QYoxaTDOAi1gYzMqg3lls4bvhz48ip8";
  23. private static string authHeader;
  24. private static string lid;
  25. static void GetAuthHeader()
  26. {
  27. //TODO: replace this with scraping and return the right response values for the 4 variables
  28. //i.e.: call method ContactsAuthentication.AuthenticateContactsSharing(username, password)
  29. string responseConsentToken = "eact%3Duw5Ym5wpNL9Jo51f9N38Div7B9HmBTkwDof75T22MRvbToDeXSEYvZzWRuRMjHkw%252B8kbWcbKJ4ZwWdGcKm%252FeCJYCPIKTHMSCzx4gZscI9w21NKV%252BqjKFkQ6t9b6%252FccObokDfN6XCU1MBFddNoenuIAyo2o44luRpkDcokM3TgfSdtj%252Bg0hZUR8V8IIIvLmelc1KTjcI%252F3GJ2pBQXkxur0O4YKGu8cFF0y8gNVuXJvpL%252BcFq5%252Fdq8wMzTT6SnGbZgHyPqJv6UQZsYpC9EM%252FQmSlcxinLZf%252BV%252BxB25qNHE2GD05SFiUYKwEf%252FSS5a9RMziv8jThJTReCeFaBLbJClvGIr7D3zHh051REFWl97FlvH2oGcNMze5K9R%252Fxb9pi0%252BFcUCA6hTveVuyih0zOZY5TFyhvltaU2aemq3BBFOa%252FHRbTMu5kGAoW%252FUJiNf4FODvuZCF%252BrH%252BMMEV5V5b3WEsTPlytEG9HhzAjWpMV6i784pqXQjB7gF6Iuy2T8JKujk2wN%252FuFIS6F4Z%252BGMUbRYBxgmuLZMALShiscC6gC4JQuW7fr2zcTqBEmChmJAi9D9T97AVBWL5cyzrjxpkqm8Dr7z8KYqGcoWQ8VVy1JMcxW3vMGMJZPZBQUz1AOYut2xqd7kt1sssDfI7Owv4M7uU55K16IImxPR4LAmapujGLtTjWwfSoKYZBl2%252B41%252BuzPcvyUw%252BQqDu2aOCe1YuZ%252FaJry3tcIk43R0V9LFQ9HFEto8g8R7PeUlx9469jFhNPGPqzFy7Qlc%252BYGwf4nRwbrizAx5HKx9QuIcl%252FByK227CX0u7e7UkUzMQ%252FfTc13TpfvFk%252FBo5aXeoxjAKwrnyFeeDUKHiEsHwjwu2EW7kGfTdAOodUACDsoQDnrrrs%252BOX80Q4BzfVhZYy3F8XDAmdczqqzaGimQLK9UETvr%252F03GzCZdJResKRJNAeaaZ6Ahdy9ebJ64qvSvFq8jBOV1%252FY1rq8clX%252F5GZxnXzqT8gN%252F%252B9%252F8ktllYZi4QLmxaT2ChY2qnE8Fxx7GomY0k%252B5sDWhdqD18Ddu9HSFSaAFq4DflnTWis6jCLJ6WpqaeBGwJyPEGm0IYlVbQ0k7X5WnKYjKrC3kl68%252BqU6lL0T1nRoa8mZNXdeXZ72W%252FLQp21IrOH6NZhnomPBID2myyJ09QtuUkXlSaWbT5A0oRcE9ywPY4EvplbggyLxpke9jL%252BtIUQtNXdGN%252B%252FwjQhREw8dfMRHoRl6VN%252BmGLONeVvoR6Lvi%252BXJZhBz36XwwfhXtGb7kKIud8E9as%252FMC6YZcUNBn%252F28Zj9YdcRmM2iAAs9DBvw5tTmgAfPYU%253D";
  30. string responseResponseCode = "RequestApproved";
  31. string responseAction = "delauth";
  32. string responseAppctx = "";
  33. NameValueCollection nvc = new NameValueCollection(4);
  34. WindowsLiveLogin wll = new WindowsLiveLogin(appId, secretKey);
  35. nvc.Add("ConsentToken", responseConsentToken);
  36. nvc.Add("ResponseCode", responseResponseCode);
  37. nvc.Add("action", responseAction);
  38. nvc.Add("appctx", responseAppctx);
  39. WindowsLiveLogin.ConsentToken ct = wll.ProcessConsent(nvc);
  40. authHeader = String.Format("DelegatedToken dt=\"{0}\"", ct.DelegationToken);
  41. lid = ct.LocationID;
  42. }
  43. public IEnumerable<ChannelContact> GetContacts()
  44. {
  45. EnsureAuthentication();
  46. UriBuilder uriBuilder = new UriBuilder();
  47. uriBuilder.Scheme = "HTTPS";
  48. uriBuilder.Path = "/users/@L@" + lid + "/REST/LiveContacts";
  49. uriBuilder.Host = "livecontacts.services.live.com";
  50. uriBuilder.Port = 443;
  51. string uriPath = uriBuilder.Uri.AbsoluteUri;
  52. ILiveContacts channel = BuildContactsChannel(uriPath);
  53. using (new OperationContextScope(channel as IContextChannel))
  54. {
  55. // Auth header is required
  56. WebOperationContext.Current.OutgoingRequest.Headers.Set("Authorization", authHeader);
  57. WebOperationContext.Current.OutgoingRequest.Headers.Add("Accept-Encoding", "deflate");
  58. WebOperationContext.Current.OutgoingRequest.Headers.Add("Pragma", "No-Cache");
  59. WebOperationContext.Current.OutgoingRequest.UserAgent = "Windows Live Data Interactive SDK";
  60. WebOperationContext.Current.OutgoingRequest.Method = "GET";
  61. WebOperationContext.Current.OutgoingRequest.ContentType = "application/xml; charset=utf-8";
  62. // Since the response is chucked we have to read it in as a Stream
  63. Stream responseStream = channel.Contacts();
  64. responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
  65. XElement element;
  66. using (XmlTextReader reader = new XmlTextReader(responseStream))
  67. element = XElement.Load(reader);
  68. foreach (var entry in element.Elements("Contact"))
  69. {
  70. if(entry.Element("Emails") != null)
  71. {
  72. yield return ParseContact(entry);
  73. }
  74. }
  75. }
  76. }
  77. public IClientContactsChannel Clone()
  78. {
  79. return new HotmailContactsChannel
  80. {
  81. Hostname = Hostname,
  82. Port = Port,
  83. IsSecured = IsSecured,
  84. MaxConcurrentConnections = MaxConcurrentConnections,
  85. CredentialsProvider = CredentialsProvider
  86. };
  87. }
  88. protected ILiveContacts BuildContactsChannel(string epAddress)
  89. {
  90. EndpointAddress address = new EndpointAddress(epAddress);
  91. var binding = RawMapper.GetCustomBinding(new WebHttpBinding(WebHttpSecurityMode.Transport));
  92. ChannelFactory<ILiveContacts> cf = new ChannelFactory<ILiveContacts>(binding, address);
  93. cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
  94. var channel = cf.CreateChannel();
  95. return channel;
  96. }
  97. //TODO: right implementation
  98. protected ChannelContact ParseContact(XElement element)
  99. {
  100. ChannelContact contact = new ChannelContact();
  101. contact.Person.Name = element.Element("Profiles").Element("Personal").Element("DisplayName").Value;
  102. contact.Profile.ChannelProfileKey = element.Element("ID").Value;
  103. // Todo could be different kind of addressses; home, work etc
  104. contact.Profile.SourceAddress = new SourceAddress(
  105. element.Element("Emails").Element("Email").Element("Address").Value,
  106. element.Element("Profiles").Element("Personal").Element("DisplayName").Value);
  107. return contact;
  108. }
  109. protected void EnsureAuthentication()
  110. {
  111. if (String.IsNullOrEmpty(authHeader))
  112. GetAuthHeader();
  113. }
  114. #region Properties
  115. public string Hostname
  116. {
  117. get { return "https://livecontacts.services.live.com/"; }
  118. set { }
  119. }
  120. public int Port
  121. {
  122. get { return 443; }
  123. set { }
  124. }
  125. public bool IsSecured
  126. {
  127. get { return true; }
  128. set { }
  129. }
  130. public bool IsEnabled { get; set; }
  131. public int MaxConcurrentConnections { get; set; }
  132. public IChannelCredentialsProvider CredentialsProvider { get; set; }
  133. public string Protocol
  134. {
  135. get { return "HotmailContactsAPI"; }
  136. }
  137. #endregion
  138. public void Dispose()
  139. {
  140. }
  141. }
  142. }