Advertisement
Guest User

Untitled

a guest
Mar 27th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 54.42 KB | None | 0 0
  1. using Elmah;
  2. using Microsoft.AspNet.Identity;
  3. using Microsoft.AspNet.Identity.Owin;
  4. using Microsoft.Owin;
  5. using Microsoft.Owin.Security;
  6. using Newtonsoft.Json;
  7. using PortalApi.Helpers;
  8. using PortalApi2.Models.Student;
  9. using PortalModules;
  10. using PortalModules.Auth;
  11. using PortalWeb.Helpers;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Configuration;
  15. using System.Data.Entity.Validation;
  16. using System.Linq;
  17. using System.Net;
  18. using System.Net.Http;
  19. using System.Net.Http.Headers;
  20. using System.Security.Claims;
  21. using System.Security.Principal;
  22. using System.Text.RegularExpressions;
  23. using System.Threading.Tasks;
  24. using System.Web;
  25. using System.Web.Mvc;
  26. using System.Web.Security;
  27. using System.Xml;
  28.  
  29. namespace PortalWeb.Controllers
  30. {
  31. public class AccountController : Controller
  32. {
  33.  
  34. public async Task<ActionResult> AddGradStudents()
  35. {
  36. var apictrl = new ApiController();
  37.  
  38. var ids = new List<string> { };
  39. var path = string.Format("{0}\\grads.txt", Server.MapPath("~/App_Data"));
  40. var file = new System.IO.StreamReader(path);
  41.  
  42. do
  43. {
  44. ids.Add(file.ReadLine());
  45. } while (file.Peek() != -1);
  46.  
  47. file.Close();
  48.  
  49. var ret = new List<string>();
  50. var failCreate = new List<string>();
  51. var owinContext = Request.GetOwinContext();
  52. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  53.  
  54. foreach (var id in ids)
  55. {
  56. var result = ((await apictrl.ProxyAdmin("student/terms2", id)) as ContentResult).Content;
  57. if (result != null)
  58. {
  59. var apiResult = JsonConvert.DeserializeObject<ApiCore.Attributes.ApiResult>(result);
  60. var termData = JsonConvert.DeserializeObject<AcadTermData>(apiResult.data.ToString());
  61. if (termData.academicTerms != null)
  62. {
  63. if (!termData.academicTerms.Any(t => t.termCode == "1179"))
  64. ret.Add(termData.username);
  65. }
  66. else
  67. {
  68. var createResult = await createUserIfNotExists(owinContext, userManager, termData.username);
  69. if(createResult.HasValue && !createResult.Value)
  70. failCreate.Add(termData.username);
  71. else
  72. {
  73. var user = await userManager.FindByNameAsync(termData.username);
  74. if(!user.Claims.Any(c => c.ClaimType == "FutureCareer" && c.ClaimValue == "GRD"))
  75. owinContext.SafeAddClaim(user.Id, new Claim("FutureCareer", "GRD"));
  76. }
  77. }
  78. }
  79. }
  80.  
  81. return Json(new { didntTouch = ret, failedCreate = failCreate }, JsonRequestBehavior.AllowGet);
  82. }
  83.  
  84. public async Task<ActionResult> FindStudentIds(string usernames)
  85. {
  86. var listUsers = usernames.Split(',');
  87. var apictrl = new ApiController();
  88. var ret = new List<string>();
  89. var fail = new List<string>();
  90.  
  91. foreach (var username in listUsers)
  92. {
  93. var result = ((await apictrl.ProxyAdmin("student/bio2", username)) as ContentResult).Content;
  94. if (result != null)
  95. {
  96. var apiResult = JsonConvert.DeserializeObject<ApiCore.Attributes.ApiResult>(result);
  97. if (apiResult.data != null)
  98. {
  99. var bioData = JsonConvert.DeserializeObject<StudentBio>(apiResult.data.ToString());
  100.  
  101. ret.Add(string.Format("{0}:{1}", username, bioData.studentId));
  102. }
  103. else
  104. fail.Add(username);
  105. }
  106. }
  107.  
  108. return Json(new { didntTouch = ret, fail = fail }, JsonRequestBehavior.AllowGet);
  109. }
  110.  
  111. #region Login logic
  112.  
  113. #if DEBUG
  114. /// <summary>
  115. /// Endpoint to work with ionic serve
  116. /// </summary>
  117. /// <param name="username"></param>
  118. /// <returns></returns>
  119. public async Task<string> FakeCas(string username)
  120. {
  121. // "go to cas, return back to here, username checks out"
  122. return await LoginMobileUser(username,"nana");
  123. }
  124. #endif
  125.  
  126. /// <summary>
  127. /// Returns to here from CAS after use logged in from the app
  128. /// </summary>
  129. /// <param name="returnUrl">URL that CAS returns users to. </param>
  130. /// <param name="ticket">CAS service ticket</param>
  131. /// <returns></returns>
  132. [AllowAnonymous]
  133. public async Task<ActionResult> LoginMobile(string returnUrl, string ticket)
  134. {
  135. string deviceInfo = null;
  136. if (returnUrl != "/Index")
  137. deviceInfo = returnUrl.Substring(8);
  138.  
  139. return await DoLogin(true, returnUrl, ticket, deviceInfo);
  140. }
  141.  
  142. /// <summary>
  143. /// Return to here from CAS after user logged in from the web
  144. /// </summary>
  145. /// <param name="returnUrl">URL that CAS returns users to.</param>
  146. /// <param name="ticket">CAS service ticket</param>
  147. /// <returns></returns>
  148. [AllowAnonymous]
  149. public async Task<ActionResult> Login(string returnUrl, string ticket)
  150. {
  151. return await DoLogin(false, returnUrl, ticket);
  152. }
  153. /// <summary>
  154. /// Login endpoint for anonymous users.
  155. /// </summary>
  156. /// <param name="returnUrl"></param>
  157. /// <returns></returns>
  158. [AllowAnonymous]
  159. public async Task<ActionResult> LoginAnon(string returnUrl)
  160. {
  161. var owinContext = Request.GetOwinContext();
  162. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  163. var user = await userManager.FindByNameAsync("anonymous2");
  164. ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
  165.  
  166. var authenticationManager = Request.GetOwinContext().Authentication;
  167. var authProperties = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = new DateTimeOffset(DateTime.Now.AddHours(8)) };
  168.  
  169. authenticationManager.SignIn(authProperties, cookiesIdentity);
  170.  
  171. var xsrfCookie = getXsrfCookie("anonymous2");
  172. if (xsrfCookie == null)
  173. throw new Exception("Couldn't generate XSRF token. Log out and back in again.");
  174.  
  175. HttpContext.Response.Cookies.Add(xsrfCookie);
  176.  
  177. var domain = ConfigurationManager.AppSettings["PortalUrl"];
  178. if (Request.Url.Authority == "localhost:4455")
  179. domain = "http://localhost:4455";
  180. else if (Request.Url.Authority == "portal.uwaterloo.ca")
  181. domain = "https://portal.uwaterloo.ca";
  182.  
  183. return Redirect(domain + returnUrl);
  184. }
  185.  
  186.  
  187. [AllowAnonymous]
  188. [HttpPost]
  189. public async Task<ActionResult> LoginAnonApp(string userName)
  190. {
  191. if (string.IsNullOrEmpty(userName))
  192. userName = "anonymous";
  193.  
  194. var anonUsers = new string[] { "anonymous", "anonymous2" };
  195.  
  196. if (!anonUsers.Contains(userName))
  197. return null;
  198.  
  199. var owinContext = Request.GetOwinContext();
  200. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  201.  
  202. //var createResult = (await createUserIfNotExists(owinContext, userManager, "anonymous"));
  203. //if (createResult.HasValue && !createResult.Value)
  204. // throw new Exception("User create failed");
  205.  
  206. //var updateResult = await UpdateClaims("anonymous", owinContext);
  207. //if (!updateResult)
  208. // throw new Exception("Update claims has failed.");
  209.  
  210. return Content(await LoginMobileUser(userName, null));
  211. }
  212.  
  213. private async Task<string> LoginMobileUser(string username, string deviceInfo)
  214. {
  215. var password = getUserPassword(username);
  216. using (var client = new HttpClient())
  217. {
  218. var portalUrl = "https://portal.uwaterloo.ca";
  219. #if DEBUG
  220. portalUrl = "http://localhost:4455";
  221. #endif
  222.  
  223. #if TEST
  224. portalUrl = "https://portalbeta.uwaterloo.ca";
  225. #endif
  226. HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, portalUrl + "/oauth2/token");
  227.  
  228.  
  229. var values = new Dictionary<string, string>
  230. {
  231. { "username", username },
  232. { "password", password },
  233. {"client_id", "portalApp" },
  234. {"grant_type","password" },
  235. {"device_info",deviceInfo }
  236. };
  237.  
  238. req.Content = new FormUrlEncodedContent(values);
  239. req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  240.  
  241. var response = await client.SendAsync(req);
  242. var responseString = await response.Content.ReadAsStringAsync();
  243.  
  244. Response.ContentType = "application/json";
  245. return responseString;
  246. }
  247. }
  248. #endregion
  249.  
  250. #region Anonymous User Stuff
  251.  
  252. /// <summary>
  253. /// Checks if there are new or deleted personas compared to those that user already has.
  254. /// Quicker than re-fetching everything
  255. /// </summary>
  256. /// <param name="personas"></param>
  257. /// <returns></returns>
  258. [AllowAnonUser]
  259. public async Task<ActionResult> PersonasConfigurationChanged(string personas) {
  260. var personasArray = personas.Split(',');
  261. var anonUsers = GetAnonymousUsers();
  262. var newAnonUsers = anonUsers.Where(k => !personasArray.Contains(k.userName)).ToList();
  263.  
  264. var anonUsersUids = anonUsers.Select(k => k.userName);
  265. var deletedUsers = personasArray.Where(k => !anonUsersUids.Contains(k)).ToList();
  266. return Json(newAnonUsers.Count > 0 || deletedUsers.Count>0, JsonRequestBehavior.AllowGet);
  267. }
  268.  
  269. public static List<AnonymousUser> GetAnonymousUsers() {
  270. using (var db = new UWPortalEntities()) {
  271. return db.AnonymousUsers.ToList();
  272. }
  273. }
  274.  
  275.  
  276. /// <summary>
  277. /// gets the list of identities for anonymous users
  278. /// first thing that gets called when app starts
  279. /// </summary>
  280. /// <param name="appVersion"></param>
  281. /// <returns></returns>
  282. [AllowAnonymous]
  283. [HttpPost]
  284. public async Task<ActionResult> GetAnonTokensAndHomeSettings_7(int appVersion)
  285. {
  286. // if this is an old version that is no longer supported, respond with a special code that
  287. // will lock the user out and display an approriate message
  288. var versionInfo = ConfigHelper.GetAppVersionInfo();
  289.  
  290. // this block will handle apps after version 7, as prior version won't submit appVersion argument
  291. if (versionInfo.version > appVersion && versionInfo.phase == 2)
  292. {
  293. return Json(new { appExpired = true });
  294. }
  295.  
  296.  
  297. var tokens = new List<dynamic>();
  298. var baseDats = new List<dynamic>();
  299.  
  300. var owinContext = Request.GetOwinContext();
  301. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  302.  
  303. List<Task<dynamic>> tasks = new List<Task<dynamic>>();
  304. var anonUsers = GetAnonymousUsers();
  305.  
  306. foreach (var anonUser in anonUsers)
  307. {
  308. // get jwt token
  309. //var token = await LoginMobileUser(anonUser, null);
  310. //tokens.Add(new { userName = anonUser, token = token });
  311. tasks.Add(getJwtToken(anonUser.userName));
  312.  
  313. // get base data
  314. //var user = await userManager.FindByNameAsync(anonUser);
  315. //var principal = new GenericPrincipal(userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie), null);
  316. //var baseData = await HomeController.getBaseDataForUser(principal, false, true);
  317. //baseDats.Add(new { userName = anonUser, baseData = baseData });
  318.  
  319. var user = await userManager.FindByNameAsync(anonUser.userName);
  320. var principal = new GenericPrincipal(userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie), null);
  321. tasks.Add(getBaseData_7(principal, anonUser.userName, userManager));
  322. }
  323.  
  324. await Task.WhenAll(tasks);
  325.  
  326. for (var i = 0; i < tasks.Count; i++)
  327. {
  328. if (i % 2 == 1)
  329. {
  330. // it's base data
  331. baseDats.Add(tasks[i].Result);
  332. }
  333. else
  334. {
  335. // it's a token
  336. tokens.Add(tasks[i].Result);
  337. }
  338. }
  339.  
  340. var ret = new { tokens = tokens, baseDats = baseDats, anonUsers = anonUsers };
  341.  
  342. return Json(ret);
  343. }
  344.  
  345. /// <summary>
  346. /// gets the list of identities for anonymous users
  347. /// first thing that gets called when app starts
  348. /// </summary>
  349. /// <param name="appVersion"></param>
  350. /// <returns></returns>
  351. [AllowAnonymous]
  352. [HttpPost]
  353. public async Task<ActionResult> GetAnonTokensAndHomeSettings()
  354. {
  355. var tokens = new List<dynamic>();
  356. var baseDats = new List<dynamic>();
  357.  
  358. var owinContext = Request.GetOwinContext();
  359. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  360.  
  361. List<Task<dynamic>> tasks = new List<Task<dynamic>>();
  362. var anonUsers = GetAnonymousUsers();
  363.  
  364. foreach (var anonUser in anonUsers)
  365. {
  366. // get jwt token
  367. //var token = await LoginMobileUser(anonUser, null);
  368. //tokens.Add(new { userName = anonUser, token = token });
  369. tasks.Add(getJwtToken(anonUser.userName));
  370.  
  371. // get base data
  372. //var user = await userManager.FindByNameAsync(anonUser);
  373. //var principal = new GenericPrincipal(userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie), null);
  374. //var baseData = await HomeController.getBaseDataForUser(principal, false, true);
  375. //baseDats.Add(new { userName = anonUser, baseData = baseData });
  376.  
  377. var user = await userManager.FindByNameAsync(anonUser.userName);
  378. var principal = new GenericPrincipal(userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie), null);
  379. tasks.Add(getBaseData(principal, anonUser.userName, userManager));
  380. }
  381.  
  382. await Task.WhenAll(tasks);
  383.  
  384. for (var i = 0; i < tasks.Count; i++)
  385. {
  386. if (i % 2 == 1)
  387. {
  388. // it's base data
  389. baseDats.Add(tasks[i].Result);
  390. }
  391. else
  392. {
  393. // it's a token
  394. tokens.Add(tasks[i].Result);
  395. }
  396. }
  397.  
  398. var ret = new { tokens = tokens, baseDats = baseDats, anonUsers = anonUsers };
  399.  
  400. return Json(ret);
  401. }
  402.  
  403. /// <summary>
  404. /// Gets JWT token for the specified user (PRIVATE)
  405. /// Needs to be in a spearate function to make it into a threaded approach
  406. /// for multiple anon users
  407. /// </summary>
  408. /// <param name="username"></param>
  409. /// <returns></returns>
  410. private async Task<dynamic> getJwtToken(string username)
  411. {
  412. return await LoginMobileUser(username, null);
  413. }
  414.  
  415. private async Task<dynamic> getBaseData(GenericPrincipal principal, string userName, ApplicationUserManager userManager)
  416. {
  417.  
  418. var baseData = await HomeController.getBaseDataForUser(principal, false, true);
  419. return new { userName = userName, baseData = baseData };
  420. }
  421.  
  422. private async Task<dynamic> getBaseData_7(GenericPrincipal principal, string userName, ApplicationUserManager userManager)
  423. {
  424.  
  425. var baseData = await HomeController.getBaseDataForUser_7(principal, false, true);
  426. return new { userName = userName, baseData = baseData };
  427. }
  428.  
  429. #endregion
  430.  
  431. public static async Task<bool> UpdateClaims(string username, IOwinContext owinContext)
  432. {
  433. var progress = "";
  434. try
  435. {
  436. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  437. ApplicationUser user = await userManager.FindByNameAsync(username);
  438.  
  439. // No need to update any claims for anonymous user
  440. if (user.Claims.Any(c => c.ClaimType == "role" && c.ClaimValue == "anonymous"))
  441. return true;
  442.  
  443. // Create a principal and send it to the GetSetConfig function so that it can setup a Config record for new users.
  444. // IMPORTANT SO THAT THEY HAVE AN API KEY TO USE FOR RETRIEVING DATA
  445. var principal = new GenericPrincipal(userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie), null);
  446. var userConfig = ConfigHelper.GetSetConfig(principal);
  447.  
  448. //--------------Audience Types--------------------
  449. var NexusAudienceClaim = new Claim("Audience", "NexusUser");
  450. var StudentAudienceClaim = new Claim("Audience", "Student");
  451. var AnonRole = new Claim("role", "anonymous");
  452. var AnonRemovedRole = new Claim("role", "anonymousRoleRemoved");
  453.  
  454. var allClaims = userManager.GetClaims(user.Id).ToList();
  455.  
  456. //--------------Has logged in, so is a Nexus User--------------
  457. var nexusClaims = allClaims.Where(c => c.Is(NexusAudienceClaim)).ToList();
  458.  
  459. // If they don't have one, add it
  460. if (nexusClaims.Count == 0)
  461. owinContext.SafeAddClaim(user.Id, NexusAudienceClaim);
  462. else if (nexusClaims.Count > 1)
  463. {
  464. // If they have many copies, make sure they only end up with one
  465. for (var i = 0; i < nexusClaims.Count - 1; i++)
  466. owinContext.SafeRemoveClaim(user.Id, NexusAudienceClaim);
  467. }
  468.  
  469. progress += "nexus user set; ";
  470.  
  471. //--------------Reset staff claim--------------
  472. //if (user.Claims.HasClaim("Audience", "Staff"))
  473. // owinContext.SafeRemoveClaim(user.Id, new Claim("Audience", "Staff"));
  474.  
  475. progress += "staff reset; ";
  476.  
  477. //--------------Check if student--------------
  478. var studentAudienceClaims = userManager.GetClaims(user.Id).Where(c => c.Is(StudentAudienceClaim)).ToList();
  479.  
  480. var student = await getStudent2(username);
  481.  
  482. if (student.isStudent)
  483. {
  484. // Clean up student audience claim
  485. if (studentAudienceClaims.Count == 0)
  486. owinContext.SafeAddClaim(user.Id, StudentAudienceClaim);
  487. else if (studentAudienceClaims.Count > 1)
  488. {
  489. // If they have many copies, make sure they only end up with one
  490. for (var i = 0; i < studentAudienceClaims.Count - 1; i++)
  491. owinContext.SafeRemoveClaim(user.Id, StudentAudienceClaim);
  492. }
  493.  
  494. progress += "student reset; ";
  495.  
  496. // Make all student claims current
  497. var studentClaimTypes = new[] { "Career", "FutureCareer", "Faculty", "Department", "Plan Title", "Level", "Form of Study", "CollegeAffiliation", "Student Number" };
  498.  
  499. // Add/modify any that need it
  500. foreach (var studentClaimType in studentClaimTypes)
  501. {
  502. progress += "removing - " + studentClaimType + "; ";
  503. var studentClaims = user.Claims.Where(c => c.ClaimType == studentClaimType).ToList();
  504.  
  505. // Remove all
  506. foreach (var studentClaim in studentClaims)
  507. owinContext.SafeRemoveClaim(user.Id, new Claim(studentClaim.ClaimType, studentClaim.ClaimValue));
  508. }
  509.  
  510. progress += "student claims reset-removed; ";
  511.  
  512. // Add all new student claims
  513. foreach (var claim in student.claims)
  514. {
  515. progress += "adding - " + claim.Value + "; ";
  516. owinContext.SafeAddClaim(user.Id, claim);
  517. }
  518.  
  519. progress += "student claims reset-added; ";
  520. }
  521. else
  522. {
  523. foreach (var studentAudClaim in studentAudienceClaims)
  524. owinContext.SafeRemoveClaim(user.Id, studentAudClaim);
  525. // Add the student number claim even if there is no current term card.
  526. foreach (var claim in student.claims)
  527. {
  528. if (claim.Type== "Student Number")
  529. owinContext.SafeAddClaim(user.Id, claim);
  530. }
  531. }
  532.  
  533. #region Rez data
  534.  
  535. //--------------Check for rez data--------------
  536. try
  537. {
  538. progress += "get rez; ";
  539. var rezInfo = await getResidenceInfo(username);
  540. if (rezInfo.isInRez)
  541. {
  542. progress += "is in rez; ";
  543. var claims = userManager.GetClaims(user.Id).ToList();
  544.  
  545. // Reset ResidenceCommunity
  546. var communities = claims.Where(c => c.Type == "ResidenceCommunity").ToList();
  547. if (communities.Count > 0)
  548. {
  549. foreach (var community in communities)
  550. {
  551. owinContext.SafeRemoveClaim(user.Id, community);
  552. }
  553. }
  554. if (!string.IsNullOrWhiteSpace(rezInfo.communityName))
  555. owinContext.SafeAddClaim(user.Id, new Claim("ResidenceCommunity", rezInfo.communityName));
  556.  
  557. progress += "community reset; ";
  558.  
  559. // Reset ResidenceRoom
  560. var rooms = claims.Where(c => c.Type == "ResidenceRoom").ToList();
  561. if (rooms.Count > 0)
  562. {
  563. foreach (var room in rooms)
  564. {
  565. owinContext.SafeRemoveClaim(user.Id, room);
  566. }
  567. }
  568. if (!string.IsNullOrWhiteSpace(rezInfo.roomCode))
  569. owinContext.SafeAddClaim(user.Id, new Claim("ResidenceRoom", rezInfo.roomCode));
  570.  
  571. progress += "room reset; ";
  572.  
  573. // Reset LivingLearningCode
  574. var llCodes = claims.Where(c => c.Type == "LivingLearningCode").ToList();
  575. if (communities.Count > 0)
  576. {
  577. foreach (var llCode in llCodes)
  578. {
  579. owinContext.SafeRemoveClaim(user.Id, llCode);
  580. }
  581. }
  582. if (!string.IsNullOrWhiteSpace(rezInfo.llCode))
  583. owinContext.SafeAddClaim(user.Id, new Claim("LivingLearningCode", rezInfo.llCode));
  584.  
  585. progress += "llCode reset; ";
  586.  
  587. // Reset LivingLearningName
  588. var llNames = claims.Where(c => c.Type == "LivingLearningName").ToList();
  589. if (communities.Count > 0)
  590. {
  591. foreach (var llName in llNames)
  592. {
  593. owinContext.SafeRemoveClaim(user.Id, llName);
  594. }
  595. }
  596. if (!string.IsNullOrWhiteSpace(rezInfo.llName))
  597. owinContext.SafeAddClaim(user.Id, new Claim("LivingLearningName", rezInfo.llName));
  598.  
  599. progress += "llName reset; ";
  600. }
  601. }
  602. catch (Exception e)
  603. {
  604. Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
  605. progress += "rez err: " + e.Message + "; ";
  606. }
  607.  
  608. #endregion
  609.  
  610. progress += "rez done; ";
  611.  
  612. //--------------Check if faculty--------------
  613.  
  614. //...
  615.  
  616.  
  617. //If a user doesn't have any claim to access portal and has any of the above audiences then they will gain a claim to access the portal
  618. //If a user does have a claim defined to access portal, dont' overwrite it because access may have been revoked (CanAccessPortal: false)
  619. if (!user.Claims.Any(c => c.ClaimType == "CanAccessPortal") && user.Claims.Any(c => c.ClaimType == "Audience"))
  620. owinContext.SafeAddClaim(user.Id, new Claim("CanAccessPortal", "true"));
  621.  
  622.  
  623. // If user's config was setup for the first time last time it ran, then correctly setup the user's theme for first time
  624. if (userConfig.IsFirstLogin && student.isStudent && student.claims.Count > 0)
  625. {
  626. var studentObj = new PortalWeb.Controllers.Student();
  627. var groupCode = student.claims.FirstOrDefault(c => c.Type == "Faculty");
  628. if (groupCode != null)
  629. studentObj.Faculty = groupCode.Value;
  630. var careerCode = student.claims.FirstOrDefault(c => c.Type == "Career");
  631. if (careerCode != null)
  632. studentObj.Career = careerCode.Value;
  633. var formOfStudy = student.claims.FirstOrDefault(c => c.Type == "Form of Study");
  634. if (formOfStudy != null)
  635. studentObj.FormOfStudy = formOfStudy.Value;
  636. var planTitles = student.claims.Where(c => c.Type == "Plan Title").Select(c => c.Value).ToArray();
  637. if (planTitles.Length > 0)
  638. studentObj.PlanTitles = planTitles;
  639. var unitCodes = student.claims.Where(c => c.Type == "Department").Select(c => c.Value).ToArray();
  640. if (unitCodes.Length > 0)
  641. studentObj.Departments = unitCodes;
  642. var level = student.claims.FirstOrDefault(c => c.Type == "Level");
  643. if (level != null)
  644. studentObj.Level = level.Value;
  645. var stdNum = student.claims.FirstOrDefault(c => c.Type == "Student Number");
  646. if (stdNum != null)
  647. studentObj.StudentNumber = stdNum.Value;
  648.  
  649. var themeId = ConfigHelper.GetThemeIdFromFaculty(studentObj.Faculty, studentObj.Departments);
  650.  
  651. ConfigHelper.GetSetConfig(principal, userInfo: studentObj, themeId: themeId, resetSocial: true);
  652. }
  653.  
  654. progress += "can access done; ";
  655.  
  656. // If not a student, check if fake data is enabled. If it is not, then remove the student related claims from this session
  657. if (!student.isStudent)
  658. {
  659. progress += "not student; ";
  660.  
  661. using (var db = new UWPortalEntities())
  662. {
  663. var config = db.Configs.SingleOrDefault(c => c.Username == username);
  664. if (config != null && !config.FakeDataOn)
  665. {
  666. progress += "fake data disabled; ";
  667. var studentClaimTypes = new[] { "Career", "Faculty", "Department", "Plan Title", "Level", "Form of Study", "CollegeAffiliation", "Student Number" };
  668.  
  669. foreach (var studentClaimType in studentClaimTypes)
  670. {
  671. var studentClaims = user.Claims.Where(c => c.ClaimType == studentClaimType).ToList();
  672. foreach (var claim in studentClaims)
  673. user.Claims.Remove(claim);
  674. }
  675. }
  676. }
  677. }
  678. else
  679. {
  680. // Make sure that if they're a student, their fake data isn't turned on.
  681. using (var db = new UWPortalEntities())
  682. {
  683. var config = db.Configs.SingleOrDefault(c => c.Username == username);
  684. if (config != null && config.FakeDataOn)
  685. {
  686. config.FakeDataOn = false;
  687. db.SaveChanges();
  688. }
  689. }
  690. }
  691. progress += "past fake data; ";
  692. return true;
  693. }
  694. catch (Exception e)
  695. {
  696. Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
  697. processLoginException(e, progress, username);
  698. return false;
  699. }
  700. }
  701.  
  702. /// <summary>
  703. /// Gets the couch password for the current user.
  704. /// </summary>
  705. /// <param name="sdk"></param>
  706. /// <returns></returns>
  707. [AllowAnonUser]
  708. [HttpPost]
  709. public async Task<ActionResult> GetCouchPassword(bool sdk = false)
  710. {
  711. var couchResponse = await CouchDBService.initUser(User.Identity.Name, sdk, User.IsInRole("anonymous"));
  712. return Json(new { user = User.Identity.Name, password = CouchDBService.genPassForCurrentUser(User.Identity.Name, sdk) }, JsonRequestBehavior.AllowGet);
  713. }
  714.  
  715. private string doubleUrlEncode(string url)
  716. {
  717. return Helpers.Utils.UrlEncodeUpper(Helpers.Utils.UrlEncodeUpper(url));
  718. }
  719.  
  720. /// <summary>
  721. /// Logs user into Portal.
  722. /// </summary>
  723. /// <param name="mobile"></param>
  724. /// <param name="returnUrl"></param>
  725. /// <param name="ticket"></param>
  726. /// <param name="deviceInfo"></param>
  727. /// <returns></returns>
  728. private async Task<ActionResult> DoLogin(bool mobile, string returnUrl, string ticket, string deviceInfo = null)
  729. {
  730. if (string.IsNullOrEmpty(returnUrl))
  731. returnUrl = "/";
  732.  
  733. if (returnUrl.Equals("/Home/SignOut"))
  734. return Redirect("/");
  735.  
  736. if (returnUrl.Equals("/elmah"))
  737. returnUrl = "/";
  738.  
  739. var username = string.Empty;
  740. var progress = string.Empty;
  741.  
  742. try
  743. {
  744. var casUrl = "https://cas.uwaterloo.ca/cas";
  745. var domain = ConfigurationManager.AppSettings["PortalUrl"];
  746. if (Request.Url.Authority == "localhost:4455")
  747. domain = "http://localhost:4455";
  748. else if (Request.Url.Authority == "portal.uwaterloo.ca")
  749. domain = "https://portal.uwaterloo.ca";
  750.  
  751.  
  752.  
  753. var serviceUrl = domain + "/Account/Login" + (mobile ? "Mobile" : "") + "?returnUrl=" + doubleUrlEncode(returnUrl);
  754.  
  755. var resultUrl = string.Format("{0}/login?service={1}", casUrl, serviceUrl);
  756.  
  757.  
  758. // Returning from CAS: validate ticket
  759. if (!string.IsNullOrWhiteSpace(ticket))
  760. {
  761. var client = new WebClient();
  762. var result = client.DownloadString(string.Format("{0}/serviceValidate?ticket={1}&service={2}", casUrl, ticket, serviceUrl));
  763.  
  764. var xmlDoc = new XmlDocument();
  765. xmlDoc.LoadXml(result);
  766.  
  767. var responseNode = xmlDoc.ChildNodes[0].ChildNodes[0];
  768. if (responseNode.LocalName == "authenticationSuccess")
  769. {
  770. var userNode = responseNode.ChildNodes[0].ChildNodes[0];
  771.  
  772. username = userNode.Value.ToLower();
  773.  
  774. progress += "set value; ";
  775. }
  776. }
  777.  
  778. // CAS ticket valid
  779. if (!string.IsNullOrWhiteSpace(username))
  780. {
  781. progress += "start; ";
  782.  
  783. resultUrl = domain + returnUrl;
  784.  
  785. // Try to find user in ASP.NET identity db
  786. var owinContext = Request.GetOwinContext();
  787. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  788.  
  789. // createResult
  790. // true: user exists
  791. // false: creation failed
  792. // null: new user created
  793. var createResult = (await createUserIfNotExists(owinContext, userManager, username));
  794. if (createResult.HasValue && !createResult.Value)
  795. throw new Exception("User create failed");
  796.  
  797. progress += "user set; ";
  798.  
  799. // don't do update claims here if this is a desktop login
  800. // we're gonnna do it in a separate request via GetUpdatedClaimsIdentity to expediate first render
  801. if (mobile)
  802. {
  803. var updateResult = await UpdateClaims(username, owinContext);
  804. if (!updateResult)
  805. throw new Exception("Update claims has failed.");
  806. }
  807.  
  808. // If this is a web request (not mobile), set cookies for authentication
  809. if (!mobile)
  810. {
  811. //if this is first time for user logging in, need to run updateClaims here
  812. if (!createResult.HasValue)
  813. {
  814. var updateResult = await UpdateClaims(username, owinContext);
  815. if (!updateResult)
  816. throw new Exception("Update claims has failed.");
  817. }
  818. else
  819. {
  820. // Check to make sure they have a CanAccessPortal claim
  821. ApplicationUser user = await userManager.FindByNameAsync(username);
  822.  
  823. if (!user.Claims.Any(c => c.ClaimType == "CanAccessPortal"))
  824. owinContext.SafeAddClaim(user.Id, new Claim("CanAccessPortal", "true"));
  825. }
  826.  
  827. var signedIn = await signInAsUser(userManager, username);
  828.  
  829. progress += "cookie set; ";
  830.  
  831. setXsrf(username);
  832.  
  833. progress += "xsrf set; ";
  834. }
  835.  
  836. // if request is coming from a mobile device we need to return jwt token + refresh token + set couchdb cookie
  837. // perform a request to the oauth server with username and password and return response with the token
  838. if (mobile)
  839. {
  840. return Content(await LoginMobileUser(username, deviceInfo));
  841. }
  842. }
  843.  
  844. return Redirect(resultUrl);
  845. }
  846. catch (Exception e)
  847. {
  848. Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
  849. processLoginException(e, progress, username);
  850. return Content(e.Message);
  851. }
  852. }
  853.  
  854. /// <summary>
  855. /// DO NOT USE "username" IT'S FOR HONEYPOT PURPOSES ONLY
  856. /// USE "User.Identity.Name"
  857. /// </summary>
  858. /// <param name="username"></param>
  859. /// <returns></returns>
  860. [HttpPost]
  861. [AllowAnonUser]
  862. public async Task<ActionResult> GetUpdatedClaimsIdentity(string username)
  863. {
  864.  
  865. // DO NOT USE "username"
  866.  
  867. if (username != User.Identity.Name)
  868. {
  869. HoneyPotsController.AddHoneypotHit("GetUpdatedClaimsIdentity", HttpContext.Request.UserHostAddress, User.Identity.Name, username);
  870. }
  871.  
  872. // DO NOT USE "username"
  873.  
  874. var owinContext = Request.GetOwinContext();
  875. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  876. var updateResult = await UpdateClaims(User.Identity.Name, owinContext);
  877.  
  878. // DO NOT USE "username"
  879.  
  880. if (!updateResult)
  881. throw new Exception("Update claims has failed.");
  882. await signInAsUser(userManager, User.Identity.Name);
  883.  
  884. // DO NOT USE "username"
  885.  
  886. var user = await userManager.FindByNameAsync(User.Identity.Name);
  887. ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
  888.  
  889. // DO NOT USE "username"
  890.  
  891. var userInfo = HomeController.getClaimsAndRoles(new ClaimsPrincipal(cookiesIdentity), User.IsInRole("anonymous"));
  892. return Json(userInfo);
  893.  
  894. // DO NOT USE "username"
  895. }
  896.  
  897.  
  898. private void setXsrf(string username)
  899. {
  900. var xsrfCookie = getXsrfCookie(username);
  901. if (xsrfCookie == null)
  902. throw new Exception("Couldn't generate XSRF token. Log out and back in again.");
  903.  
  904. HttpContext.Response.Cookies.Add(xsrfCookie);
  905. }
  906.  
  907. private async Task<bool> signInAsUser(ApplicationUserManager userManager, string username, bool removeAnonClaim = false)
  908. {
  909. var user = await userManager.FindByNameAsync(username);
  910.  
  911. ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
  912.  
  913. if (removeAnonClaim)
  914. {
  915. foreach (var claim in cookiesIdentity.Claims)
  916. {
  917. if (claim.Type == "role" && claim.Value == "anonymous")
  918. {
  919. cookiesIdentity.RemoveClaim(claim);
  920. break;
  921. }
  922. }
  923. cookiesIdentity.AddClaim(new Claim("role", "anonymousRoleRemoved"));
  924. cookiesIdentity.AddClaim(new Claim("Audience", "NexusUser"));
  925. }
  926.  
  927. var authenticationManager = Request.GetOwinContext().Authentication;
  928. var authProperties = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = new DateTimeOffset(DateTime.Now.AddHours(8)) };
  929.  
  930. authenticationManager.SignIn(authProperties, cookiesIdentity);
  931. return true;
  932. }
  933.  
  934. /// <summary>
  935. ///
  936. /// </summary>
  937. /// <param name="owinContext"></param>
  938. /// <param name="userManager"></param>
  939. /// <param name="username"></param>
  940. /// <returns>true if user already exists, false if user does not exists and it failed, null if user did not exist and was just created</returns>
  941. private async Task<bool?> createUserIfNotExists(IOwinContext owinContext, ApplicationUserManager userManager, string username)
  942. {
  943. ApplicationUser user = await userManager.FindByNameAsync(username);
  944.  
  945. // User does not exist: create user
  946. if (user == null)
  947. {
  948. var password = getUserPassword(username);
  949. var newUser = new ApplicationUser { UserName = username, Email = username + "@uwaterloo.ca" };
  950. var result = await userManager.CreateAsync(newUser, password);
  951. if (!result.Succeeded)
  952. return false;
  953. else
  954. return null;
  955. }
  956. return true;
  957. }
  958.  
  959.  
  960. /// <summary>
  961. /// Gets a hashed password for the user.
  962. /// </summary>
  963. /// <param name="username"></param>
  964. /// <returns></returns>
  965. private static string getUserPassword(string username)
  966. {
  967. var concat = string.Concat(username, "fJIdwFQ5eIp7zOPa");
  968. string password = FormsAuthentication.HashPasswordForStoringInConfigFile(concat, "sha1") + ";a";
  969. return password;
  970. }
  971.  
  972. private static void processLoginException(Exception e, string progress, string username)
  973. {
  974. var dbErr = e as DbEntityValidationException;
  975. if (dbErr != null)
  976. {
  977. foreach (var eve in dbErr.EntityValidationErrors)
  978. {
  979. e.LogError(string.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State));
  980.  
  981. foreach (var ve in eve.ValidationErrors)
  982. e.LogError(string.Format("- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
  983. }
  984. }
  985. e.LogError("Account login error. Username: " + username + " \nProgress: " + progress);
  986. }
  987.  
  988. #region Admin Stuff
  989.  
  990. [Authorize(Roles = "Master Admin")]
  991. public async Task<ActionResult> showUserPassword(string userName)
  992. {
  993. var password = getUserPassword(userName);
  994. return Content(password);
  995. }
  996.  
  997.  
  998. [Authorize(Roles = "Master Admin")]
  999. [HttpPost]
  1000. public async Task<ActionResult> ImpersonateApp(string id)
  1001. {
  1002. var allowed = new[] { "pchvala", "ostruk", "jradman", "y339zhao" };
  1003. if (!allowed.Contains(User.Identity.Name))
  1004. return Content("No");
  1005.  
  1006. var owinContext = Request.GetOwinContext();
  1007. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  1008.  
  1009. var createResult = (await createUserIfNotExists(owinContext, userManager, id));
  1010. if (createResult.HasValue && !createResult.Value)
  1011. throw new Exception("User create failed");
  1012.  
  1013. var updateResult = await UpdateClaims(id, owinContext);
  1014. if (!updateResult)
  1015. throw new Exception("Update claims has failed.");
  1016.  
  1017. return Content(await LoginMobileUser(id, null));
  1018. }
  1019.  
  1020.  
  1021. [Authorize(Roles = "Master Admin")]
  1022. [HttpGet]
  1023. public async Task<ActionResult> EditAnonAccount(string id)
  1024. {
  1025. var allowed = new[] { "pchvala", "ostruk", "jradman", "y339zhao" };
  1026. if (!allowed.Contains(User.Identity.Name))
  1027. return Content("No");
  1028.  
  1029. var owinContext = Request.GetOwinContext();
  1030. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  1031.  
  1032.  
  1033. var createResult = (await createUserIfNotExists(owinContext, userManager, id));
  1034. if (createResult.HasValue && !createResult.Value)
  1035. return Content("Could not create user");
  1036.  
  1037. var updateResult = await UpdateClaims(id, owinContext);
  1038. if (!updateResult)
  1039. return Content("Update claims has failed.");
  1040.  
  1041. await signInAsUser(userManager, id, true);
  1042. setXsrf(id);
  1043.  
  1044. return Redirect("/Index");
  1045. }
  1046.  
  1047. /// <summary>
  1048. /// Impersonate access point for debug purpose.
  1049. /// </summary>
  1050. /// <param name="id"></param>
  1051. /// <returns></returns>
  1052. [Authorize(Roles = "Master Admin")]
  1053. [HttpGet]
  1054. public async Task<ActionResult> Impersonate(string id)
  1055. {
  1056. var allowed = new[] { "pchvala", "ostruk", "jradman", "y339zhao" };
  1057. if (!allowed.Contains(User.Identity.Name))
  1058. return Content("No");
  1059.  
  1060. var owinContext = Request.GetOwinContext();
  1061. var userManager = owinContext.GetUserManager<ApplicationUserManager>();
  1062.  
  1063.  
  1064. var createResult = (await createUserIfNotExists(owinContext, userManager, id));
  1065. if (createResult.HasValue && !createResult.Value)
  1066. return Content("Could not create user");
  1067.  
  1068. var updateResult = await UpdateClaims(id, owinContext);
  1069. if (!updateResult)
  1070. return Content("Update claims has failed.");
  1071.  
  1072. await signInAsUser(userManager, id);
  1073. setXsrf(id);
  1074.  
  1075. return Redirect("/Index");
  1076. }
  1077.  
  1078.  
  1079. #endregion
  1080.  
  1081. /// <summary>
  1082. /// Issues a XSRF cookie to the user. This cookie expires in 8 hrs.
  1083. /// </summary>
  1084. /// <param name="username"></param>
  1085. /// <returns></returns>
  1086. private HttpCookie getXsrfCookie(string username)
  1087. {
  1088. if (string.IsNullOrWhiteSpace(username))
  1089. return null;
  1090.  
  1091. var value = string.Format("{0}.S41T", username).GetMd5Hash();
  1092. var cookie = new HttpCookie("XSRF-TOKEN", value);
  1093. cookie.Expires = DateTime.Now.AddHours(8);
  1094. #if !DEBUG
  1095. cookie.Secure = true;
  1096. #endif
  1097.  
  1098. var key = username.GetMd5Hash();
  1099.  
  1100. try
  1101. {
  1102. using (var db = new UWPortalEntities())
  1103. {
  1104. var token = db.XsrfTokens.SingleOrDefault(x => x.Username == username && x.Key == key);
  1105. if (token == null)
  1106. {
  1107. token = new XsrfToken() { Username = username, Token = value, Key = key, TimeCreated = DateTime.Now };
  1108. db.XsrfTokens.Add(token);
  1109. }
  1110. else
  1111. token.Token = value;
  1112.  
  1113. db.SaveChanges();
  1114. }
  1115.  
  1116. return cookie;
  1117. }
  1118. catch (Exception e)
  1119. {
  1120. Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
  1121. e.LogError(string.Format("XSRF error for: {0}, key: {1}, value: {2}", username, key, value));
  1122. return null;
  1123. }
  1124. }
  1125.  
  1126. /// <summary>
  1127. /// Gets various student data for the specified user.
  1128. /// </summary>
  1129. /// <param name="username"></param>
  1130. /// <returns></returns>
  1131. private static async Task<StudentClaim> getStudent2(string username)
  1132. {
  1133. var progress = string.Empty;
  1134. var studentData = new StudentClaim() { isStudent = false, claims = new List<Claim>() };
  1135.  
  1136. try
  1137. {
  1138. progress += "getstudent2; ";
  1139.  
  1140.  
  1141. var apiResult = await ApiController.Proxy("student/terms2", username);
  1142. if (apiResult.data == null)
  1143. return studentData;
  1144.  
  1145. progress += "got api result; ";
  1146.  
  1147. var termData = JsonConvert.DeserializeObject<AcadTermData>(apiResult.data.ToString());
  1148.  
  1149. if (!string.IsNullOrWhiteSpace(termData.studentId))
  1150. studentData.claims.Add(new Claim("Student Number", termData.studentId));
  1151.  
  1152. if (termData.academicTerms == null)
  1153. return studentData;
  1154.  
  1155. progress += "got term data; ";
  1156.  
  1157. var date = DateTime.Now;
  1158. var termCode = "0";
  1159. var currentTerms = new List<AcadTerm>();
  1160.  
  1161. // Check if current term exists
  1162. termCode = date.ToTermCode();
  1163. currentTerms = termData.academicTerms.Where(t => t.termCode == termCode).ToList();
  1164.  
  1165. progress += "past cur term; ";
  1166.  
  1167. if (currentTerms.Count == 0)
  1168. {
  1169. // Check if next term exists
  1170. date = date.AddMonths(4);
  1171. termCode = date.ToTermCode();
  1172. currentTerms = termData.academicTerms.Where(t => t.termCode == termCode).ToList();
  1173.  
  1174. progress += "past next term; ";
  1175.  
  1176. if (currentTerms.Count == 0)
  1177. {
  1178. date = date.AddMonths(-8);
  1179.  
  1180. // Check up to 3 terms back
  1181. for (int i = 0; i < 3; i++)
  1182. {
  1183. progress += "get term " + i + "; ";
  1184.  
  1185. termCode = date.ToTermCode();
  1186. currentTerms = termData.academicTerms.Where(t => t.termCode == termCode).ToList();
  1187.  
  1188. if (currentTerms.Count > 0)
  1189. break;
  1190.  
  1191. date = date.AddMonths(-4);
  1192. }
  1193. }
  1194. }
  1195. else
  1196. {
  1197. // There is a current term, but check the next anyways in case it's a different career
  1198. date = date.AddMonths(4);
  1199. termCode = date.ToTermCode();
  1200. var nextTerms = termData.academicTerms.Where(t => t.termCode == termCode).ToList();
  1201. if(nextTerms.Count > 0)
  1202. {
  1203. foreach(var nextTerm in nextTerms)
  1204. studentData.claims.Add(new Claim("FutureCareer", nextTerm.academicCareer));
  1205. }
  1206. }
  1207.  
  1208. progress += "past term check; ";
  1209.  
  1210.  
  1211.  
  1212. progress += "past stdNum; ";
  1213.  
  1214. //Check whether term exists
  1215. if (currentTerms.Count > 0)
  1216. {
  1217. studentData.isStudent = true;
  1218.  
  1219. progress += "is student; ";
  1220.  
  1221. foreach (var currentTerm in currentTerms)
  1222. {
  1223. studentData.claims.AddRange(new List<Claim> {
  1224. new Claim("Career", currentTerm.academicCareer),
  1225. new Claim("Form of Study", currentTerm.formOfStudyCode),
  1226. new Claim("Faculty", currentTerm.academicGroupCode),
  1227. new Claim("Level", currentTerm.academicLevel)
  1228. });
  1229.  
  1230. progress += "done main claims; ";
  1231.  
  1232. foreach (var plan in currentTerm.plans)
  1233. {
  1234. studentData.claims.AddRange(new List<Claim> {
  1235. new Claim("Department", plan.academicOrgCode),
  1236. new Claim("Plan Title", plan.planName)
  1237. });
  1238. }
  1239.  
  1240. progress += "done plan claims; ";
  1241.  
  1242. // Get college affiliations
  1243. var colleges = await ApiController.Proxy("student/collegeAffiliations", username);
  1244. if (colleges.data != null)
  1245. {
  1246. var affiliations = JsonConvert.DeserializeObject<StudentCollegeAffiliations>(colleges.data.ToString());
  1247.  
  1248. foreach (var college in affiliations.Colleges)
  1249. studentData.claims.Add(new Claim("CollegeAffiliation", college));
  1250. }
  1251.  
  1252. progress += "done affiliation claims; ";
  1253.  
  1254. }
  1255.  
  1256. progress += "done claims; ";
  1257. }
  1258.  
  1259. return studentData;
  1260. }
  1261. catch (Exception e)
  1262. {
  1263. Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
  1264. processLoginException(e, progress, username);
  1265. return studentData;
  1266. }
  1267. }
  1268. /// <summary>
  1269. /// Gets residence information for the specified user.
  1270. /// </summary>
  1271. /// <param name="username"></param>
  1272. /// <returns></returns>
  1273. private static async Task<ResidenceInfo> getResidenceInfo(string username)
  1274. {
  1275. var rezInfo = new ResidenceInfo { isInRez = false };
  1276.  
  1277. var apiResult = await ApiController.Proxy("student/rezInfo", username);
  1278. if (apiResult.data == null)
  1279. return rezInfo;
  1280.  
  1281. var rezData = JsonConvert.DeserializeObject<RezData>(apiResult.data.ToString());
  1282. if (rezData.ResidenceData == null)
  1283. return rezInfo;
  1284.  
  1285. var now = DateTime.Now;
  1286. var start = DateTime.Parse(rezData.ResidenceData.ContractStartDate);
  1287. var end = DateTime.Parse(rezData.ResidenceData.ContractEndDate);
  1288. if (start <= now && end > now)
  1289. {
  1290. rezInfo.isInRez = true;
  1291. rezInfo.communityName = rezData.ResidenceData.CommunityName;
  1292. rezInfo.roomCode = rezData.ResidenceData.RoomCode;
  1293. rezInfo.llCode = rezData.ResidenceData.LivingLearningCode;
  1294. rezInfo.llName = rezData.ResidenceData.LivingLearningName;
  1295. }
  1296.  
  1297. return rezInfo;
  1298. }
  1299.  
  1300. public ActionResult Secured()
  1301. {
  1302. return View((User as ClaimsPrincipal).Claims);
  1303. }
  1304. }
  1305.  
  1306. public class StudentClaim
  1307. {
  1308. public bool isStudent { get; set; }
  1309. public List<Claim> claims { get; set; }
  1310. }
  1311.  
  1312. public class ResidenceInfo
  1313. {
  1314. public bool isInRez { get; set; }
  1315.  
  1316. public string communityName { get; set; }
  1317. public string roomCode { get; set; }
  1318.  
  1319. // Living Learning Code/Name
  1320. public string llCode { get; set; }
  1321. public string llName { get; set; }
  1322. }
  1323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement