Yammer Authentication Class

  1. using Newtonsoft.Json;
  2. using RestSharp;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Configuration;
  6. using System.Diagnostics;
  7. using System.IO;
  8. using System.Net;
  9. using System.Security.Authentication;
  10. using System.Text.RegularExpressions;
  11.  
  12. namespace YammerDataExport.YammerLogin
  13. {
  14. public class YammerAuthentication
  15. {
  16. private const string _YammerURL = "https://www.yammer.com";
  17. private string _AuthTokenCode;
  18. public string oAuthToken
  19. {
  20. get
  21. {
  22. return ConfigurationManager.AppSettings["oAuthToken"];
  23. }
  24. set
  25. {
  26. System.Configuration.Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  27. configFile.AppSettings.Settings["oAuthToken"].Value = value.ToString();
  28. configFile.Save(ConfigurationSaveMode.Modified);
  29. ConfigurationManager.RefreshSection("appSettings");
  30. }
  31. }
  32. private string ClientID
  33. {
  34. get
  35. {
  36. return ConfigurationManager.AppSettings["ClientID"];
  37. }
  38. }
  39. private string ClientSecret
  40. {
  41. get
  42. {
  43. return ConfigurationManager.AppSettings["ClientSecret"];
  44. }
  45. }
  46. private string RedirectURL
  47. {
  48. get
  49. {
  50. var redirectURL = ConfigurationManager.AppSettings["RedirectURL"];
  51. if (!redirectURL.EndsWith("/"))
  52. redirectURL = redirectURL + "/";
  53. return redirectURL;
  54. }
  55. }
  56. public YammerUser LoggedInYammerUser { get; private set; }
  57.  
  58. public YammerAuthentication()
  59. {
  60. if (String.IsNullOrWhiteSpace(oAuthToken))
  61. {
  62. oAuthToken = GetOAuthToken(ClientID, ClientSecret, 240);
  63. }
  64. if (!IsOAuthTokenValid())
  65. {
  66. oAuthToken = GetOAuthToken(ClientID, ClientSecret, 240);
  67. }
  68. }
  69.  
  70. private Boolean IsOAuthTokenValid()
  71. {
  72. var client = new RestClient(String.Format("{0}/api/v1/users/current.json", _YammerURL));
  73. var request = new RestRequest(Method.GET);
  74.  
  75. request.AddHeader("Accept", "*/*");
  76. request.AddHeader("Authorization", String.Format("Bearer {0}", oAuthToken));
  77.  
  78. var response = client.Get(request);
  79. if (response.StatusCode == HttpStatusCode.OK)
  80. {
  81. LoggedInYammerUser = JsonConvert.DeserializeObject<YammerUser>(response.Content);
  82. return true;
  83. }
  84. return false;
  85.  
  86. }
  87. private string GetOAuthToken(string clientId, string clientSecret, int timeoutInSeconds)
  88. {
  89.  
  90. var watchingThread = new System.Threading.Thread(WatchForCode);
  91. watchingThread.Start();
  92. if (!watchingThread.Join(TimeSpan.FromSeconds(timeoutInSeconds)))
  93. {
  94. watchingThread.Abort();
  95. throw new Exception(String.Format("The timeout to login is set to {0} seconds and the time limit was exceeded.", timeoutInSeconds));
  96. }
  97. return GetOAuthCodeFromTokenCode(clientId, clientSecret, _AuthTokenCode);
  98.  
  99. }
  100.  
  101. private void WatchForCode()
  102. {
  103. const string closeWindowResponse = "<!DOCTYPE html><html><head></head><body onload=\"closeThis();\"><h1>Yammer Authorization Successfull</h1><p>This window can now be closed.</p><script type=\"text/javascript\">function closeMe() { window.close(); } function closeThis() { window.close(); }</script></body></html>";
  104.  
  105. using (var listener = new HttpListener())
  106. {
  107. listener.Prefixes.Add(RedirectURL.Replace("localhost","+"));
  108. listener.Start();
  109. var yammerAuthURL = String.Format("{0}/oauth2/authorize?client_id={1}&redirect_uri={2}", _YammerURL, ClientID, RedirectURL);
  110. using (Process.Start(yammerAuthURL))
  111. {
  112. while (true)
  113. {
  114. var context = listener.GetContext();
  115. var regexString = "([http].*[0-9])";
  116. if (context.Request.Url.AbsolutePath == Regex.Replace(RedirectURL, regexString, String.Empty))
  117. {
  118. var code = context.Request.QueryString["code"];
  119. if (code == null)
  120. {
  121. throw new AuthenticationException("Access denied, no return code was returned");
  122. }
  123.  
  124. var writer = new StreamWriter(context.Response.OutputStream);
  125. writer.WriteLine(closeWindowResponse);
  126. writer.Flush();
  127.  
  128. context.Response.Close();
  129. System.Threading.Thread.Sleep(1000);
  130. _AuthTokenCode = code;
  131. break;
  132. }
  133. else
  134. {
  135. context.Response.StatusCode = 404;
  136. context.Response.Close();
  137. }
  138. }
  139.  
  140. }
  141. }
  142. }
  143. private string GetOAuthCodeFromTokenCode(string clientId, string clientSecret,string tokenCode)
  144. {
  145. var client = new RestClient(String.Format("{0}/oauth2/access_token", _YammerURL));
  146. var request = new RestRequest(Method.POST);
  147.  
  148. request.Parameters.Clear();
  149.  
  150. var bodyText = string.Format("client_id={0}&client_secret={1}&code={2}&grant_type=authorization_code", clientId, clientSecret, tokenCode);
  151. request.AddParameter("", bodyText, ParameterType.RequestBody);
  152.  
  153. var response = client.Post(request);
  154. if (response.StatusCode != HttpStatusCode.OK)
  155. {
  156. return null;
  157. }
  158. dynamic jsonObject = JsonConvert.DeserializeObject(response.Content);
  159. return jsonObject.access_token.token;
  160. }
  161.  
  162. }
  163.  
  164. public class PreviousCompany
  165. {
  166. public string employer { get; set; }
  167. public string position { get; set; }
  168. public string description { get; set; }
  169. public int start_year { get; set; }
  170. public int end_year { get; set; }
  171. }
  172.  
  173. public class School
  174. {
  175. public string school { get; set; }
  176. public string degree { get; set; }
  177. public string description { get; set; }
  178. public int start_year { get; set; }
  179. public int end_year { get; set; }
  180. }
  181.  
  182. public class Im
  183. {
  184. public string provider { get; set; }
  185. public string username { get; set; }
  186. }
  187.  
  188. public class PhoneNumber
  189. {
  190. public string type { get; set; }
  191. public string number { get; set; }
  192. }
  193.  
  194. public class EmailAddress
  195. {
  196. public string type { get; set; }
  197. public string address { get; set; }
  198. }
  199.  
  200. public class Contact
  201. {
  202. public Im im { get; set; }
  203. public List<PhoneNumber> phone_numbers { get; set; }
  204. public List<EmailAddress> email_addresses { get; set; }
  205. public bool has_fake_email { get; set; }
  206. }
  207.  
  208. public class Stats
  209. {
  210. public int following { get; set; }
  211. public int followers { get; set; }
  212. public int updates { get; set; }
  213. }
  214.  
  215. public class Settings
  216. {
  217. public string xdr_proxy { get; set; }
  218. }
  219.  
  220. public class NetworkSettings
  221. {
  222. public string message_prompt { get; set; }
  223. public string allow_attachments { get; set; }
  224. public bool show_communities_directory { get; set; }
  225. public bool allow_notes { get; set; }
  226. public bool allow_yammer_apps { get; set; }
  227. public bool enable_groups { get; set; }
  228. public string admin_can_delete_messages { get; set; }
  229. public bool allow_inline_document_view { get; set; }
  230. public bool allow_inline_video { get; set; }
  231. public bool enable_private_messages { get; set; }
  232. public bool allow_external_sharing { get; set; }
  233. public bool enable_chat { get; set; }
  234. }
  235.  
  236. public class WebPreferences
  237. {
  238. public string absolute_timestamps { get; set; }
  239. public string threaded_mode { get; set; }
  240. public NetworkSettings network_settings { get; set; }
  241. public string enter_does_not_submit_message { get; set; }
  242. public string preferred_my_feed { get; set; }
  243. public string prescribed_my_feed { get; set; }
  244. public bool sticky_my_feed { get; set; }
  245. public string enable_chat { get; set; }
  246. public bool dismissed_feed_tooltip { get; set; }
  247. public bool dismissed_group_tooltip { get; set; }
  248. public bool dismissed_profile_prompt { get; set; }
  249. public bool dismissed_invite_tooltip { get; set; }
  250. public bool dismissed_apps_tooltip { get; set; }
  251. public object dismissed_invite_tooltip_at { get; set; }
  252. public object dismissed_browser_lifecycle_banner { get; set; }
  253. public bool make_yammer_homepage { get; set; }
  254. public string locale { get; set; }
  255. public int yammer_now_app_id { get; set; }
  256. public bool has_yammer_now { get; set; }
  257. public bool has_mobile_client { get; set; }
  258. }
  259.  
  260. public class YammerUser
  261. {
  262. public string type { get; set; }
  263. public int id { get; set; }
  264. public int network_id { get; set; }
  265. public string state { get; set; }
  266. public object guid { get; set; }
  267. public string job_title { get; set; }
  268. public string location { get; set; }
  269. public string significant_other { get; set; }
  270. public string kids_names { get; set; }
  271. public string interests { get; set; }
  272. public string summary { get; set; }
  273. public string expertise { get; set; }
  274. public string full_name { get; set; }
  275. public string activated_at { get; set; }
  276. public bool show_ask_for_photo { get; set; }
  277. public string first_name { get; set; }
  278. public string last_name { get; set; }
  279. public string network_name { get; set; }
  280. public List<string> network_domains { get; set; }
  281. public string url { get; set; }
  282. public string web_url { get; set; }
  283. public string name { get; set; }
  284. public string mugshot_url { get; set; }
  285. public string mugshot_url_template { get; set; }
  286. public string birth_date { get; set; }
  287. public string timezone { get; set; }
  288. public List<string> external_urls { get; set; }
  289. public string admin { get; set; }
  290. public string verified_admin { get; set; }
  291. public string can_broadcast { get; set; }
  292. public string department { get; set; }
  293. public string email { get; set; }
  294. public bool can_create_new_network { get; set; }
  295. public bool can_browse_external_networks { get; set; }
  296. public List<PreviousCompany> previous_companies { get; set; }
  297. public List<School> schools { get; set; }
  298. public Contact contact { get; set; }
  299. public Stats stats { get; set; }
  300. public Settings settings { get; set; }
  301. public WebPreferences web_preferences { get; set; }
  302. public bool follow_general_messages { get; set; }
  303. }
  304. }