PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/SurveyTool/Controllers/ManageController.cs

https://gitlab.com/codeboard/surveyTools
C# | 387 lines | 317 code | 32 blank | 38 comment | 50 complexity | 7beac5eb7833fc7c3a248741771a95c3 MD5 | raw file
  1. using System;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using Microsoft.AspNet.Identity;
  7. using Microsoft.AspNet.Identity.Owin;
  8. using Microsoft.Owin.Security;
  9. using SurveyTool.Models;
  10. namespace SurveyTool.Controllers
  11. {
  12. [Authorize]
  13. public class ManageController : Controller
  14. {
  15. private ApplicationSignInManager _signInManager;
  16. private ApplicationUserManager _userManager;
  17. public ManageController()
  18. {
  19. }
  20. public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
  21. {
  22. UserManager = userManager;
  23. SignInManager = signInManager;
  24. }
  25. public ApplicationSignInManager SignInManager
  26. {
  27. get
  28. {
  29. return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
  30. }
  31. private set
  32. {
  33. _signInManager = value;
  34. }
  35. }
  36. public ApplicationUserManager UserManager
  37. {
  38. get
  39. {
  40. return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
  41. }
  42. private set
  43. {
  44. _userManager = value;
  45. }
  46. }
  47. //
  48. // GET: /Manage/Index
  49. public async Task<ActionResult> Index(ManageMessageId? message)
  50. {
  51. ViewBag.StatusMessage =
  52. message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
  53. : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
  54. : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
  55. : message == ManageMessageId.Error ? "An error has occurred."
  56. : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
  57. : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
  58. : "";
  59. var userId = User.Identity.GetUserId();
  60. var model = new IndexViewModel
  61. {
  62. HasPassword = HasPassword(),
  63. PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),
  64. TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),
  65. Logins = await UserManager.GetLoginsAsync(userId),
  66. BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId)
  67. };
  68. return View(model);
  69. }
  70. //
  71. // POST: /Manage/RemoveLogin
  72. [HttpPost]
  73. [ValidateAntiForgeryToken]
  74. public async Task<ActionResult> RemoveLogin(string loginProvider, string providerKey)
  75. {
  76. ManageMessageId? message;
  77. var result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
  78. if (result.Succeeded)
  79. {
  80. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  81. if (user != null)
  82. {
  83. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  84. }
  85. message = ManageMessageId.RemoveLoginSuccess;
  86. }
  87. else
  88. {
  89. message = ManageMessageId.Error;
  90. }
  91. return RedirectToAction("ManageLogins", new { Message = message });
  92. }
  93. //
  94. // GET: /Manage/AddPhoneNumber
  95. public ActionResult AddPhoneNumber()
  96. {
  97. return View();
  98. }
  99. //
  100. // POST: /Manage/AddPhoneNumber
  101. [HttpPost]
  102. [ValidateAntiForgeryToken]
  103. public async Task<ActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
  104. {
  105. if (!ModelState.IsValid)
  106. {
  107. return View(model);
  108. }
  109. // Generate the token and send it
  110. var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), model.Number);
  111. if (UserManager.SmsService != null)
  112. {
  113. var message = new IdentityMessage
  114. {
  115. Destination = model.Number,
  116. Body = "Your security code is: " + code
  117. };
  118. await UserManager.SmsService.SendAsync(message);
  119. }
  120. return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number });
  121. }
  122. //
  123. // POST: /Manage/EnableTwoFactorAuthentication
  124. [HttpPost]
  125. [ValidateAntiForgeryToken]
  126. public async Task<ActionResult> EnableTwoFactorAuthentication()
  127. {
  128. await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
  129. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  130. if (user != null)
  131. {
  132. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  133. }
  134. return RedirectToAction("Index", "Manage");
  135. }
  136. //
  137. // POST: /Manage/DisableTwoFactorAuthentication
  138. [HttpPost]
  139. [ValidateAntiForgeryToken]
  140. public async Task<ActionResult> DisableTwoFactorAuthentication()
  141. {
  142. await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false);
  143. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  144. if (user != null)
  145. {
  146. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  147. }
  148. return RedirectToAction("Index", "Manage");
  149. }
  150. //
  151. // GET: /Manage/VerifyPhoneNumber
  152. public async Task<ActionResult> VerifyPhoneNumber(string phoneNumber)
  153. {
  154. var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), phoneNumber);
  155. // Send an SMS through the SMS provider to verify the phone number
  156. return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
  157. }
  158. //
  159. // POST: /Manage/VerifyPhoneNumber
  160. [HttpPost]
  161. [ValidateAntiForgeryToken]
  162. public async Task<ActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
  163. {
  164. if (!ModelState.IsValid)
  165. {
  166. return View(model);
  167. }
  168. var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code);
  169. if (result.Succeeded)
  170. {
  171. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  172. if (user != null)
  173. {
  174. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  175. }
  176. return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess });
  177. }
  178. // If we got this far, something failed, redisplay form
  179. ModelState.AddModelError("", "Failed to verify phone");
  180. return View(model);
  181. }
  182. //
  183. // GET: /Manage/RemovePhoneNumber
  184. public async Task<ActionResult> RemovePhoneNumber()
  185. {
  186. var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null);
  187. if (!result.Succeeded)
  188. {
  189. return RedirectToAction("Index", new { Message = ManageMessageId.Error });
  190. }
  191. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  192. if (user != null)
  193. {
  194. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  195. }
  196. return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess });
  197. }
  198. //
  199. // GET: /Manage/ChangePassword
  200. public ActionResult ChangePassword()
  201. {
  202. return View();
  203. }
  204. //
  205. // POST: /Manage/ChangePassword
  206. [HttpPost]
  207. [ValidateAntiForgeryToken]
  208. public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
  209. {
  210. if (!ModelState.IsValid)
  211. {
  212. return View(model);
  213. }
  214. var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
  215. if (result.Succeeded)
  216. {
  217. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  218. if (user != null)
  219. {
  220. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  221. }
  222. return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
  223. }
  224. AddErrors(result);
  225. return View(model);
  226. }
  227. //
  228. // GET: /Manage/SetPassword
  229. public ActionResult SetPassword()
  230. {
  231. return View();
  232. }
  233. //
  234. // POST: /Manage/SetPassword
  235. [HttpPost]
  236. [ValidateAntiForgeryToken]
  237. public async Task<ActionResult> SetPassword(SetPasswordViewModel model)
  238. {
  239. if (ModelState.IsValid)
  240. {
  241. var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
  242. if (result.Succeeded)
  243. {
  244. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  245. if (user != null)
  246. {
  247. await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
  248. }
  249. return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess });
  250. }
  251. AddErrors(result);
  252. }
  253. // If we got this far, something failed, redisplay form
  254. return View(model);
  255. }
  256. //
  257. // GET: /Manage/ManageLogins
  258. public async Task<ActionResult> ManageLogins(ManageMessageId? message)
  259. {
  260. ViewBag.StatusMessage =
  261. message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
  262. : message == ManageMessageId.Error ? "An error has occurred."
  263. : "";
  264. var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
  265. if (user == null)
  266. {
  267. return View("Error");
  268. }
  269. var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId());
  270. var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
  271. ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
  272. return View(new ManageLoginsViewModel
  273. {
  274. CurrentLogins = userLogins,
  275. OtherLogins = otherLogins
  276. });
  277. }
  278. //
  279. // POST: /Manage/LinkLogin
  280. [HttpPost]
  281. [ValidateAntiForgeryToken]
  282. public ActionResult LinkLogin(string provider)
  283. {
  284. // Request a redirect to the external login provider to link a login for the current user
  285. return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId());
  286. }
  287. //
  288. // GET: /Manage/LinkLoginCallback
  289. public async Task<ActionResult> LinkLoginCallback()
  290. {
  291. var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
  292. if (loginInfo == null)
  293. {
  294. return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
  295. }
  296. var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
  297. return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
  298. }
  299. protected override void Dispose(bool disposing)
  300. {
  301. if (disposing && _userManager != null)
  302. {
  303. _userManager.Dispose();
  304. _userManager = null;
  305. }
  306. base.Dispose(disposing);
  307. }
  308. #region Helpers
  309. // Used for XSRF protection when adding external logins
  310. private const string XsrfKey = "XsrfId";
  311. private IAuthenticationManager AuthenticationManager
  312. {
  313. get
  314. {
  315. return HttpContext.GetOwinContext().Authentication;
  316. }
  317. }
  318. private void AddErrors(IdentityResult result)
  319. {
  320. foreach (var error in result.Errors)
  321. {
  322. ModelState.AddModelError("", error);
  323. }
  324. }
  325. private bool HasPassword()
  326. {
  327. var user = UserManager.FindById(User.Identity.GetUserId());
  328. if (user != null)
  329. {
  330. return user.PasswordHash != null;
  331. }
  332. return false;
  333. }
  334. private bool HasPhoneNumber()
  335. {
  336. var user = UserManager.FindById(User.Identity.GetUserId());
  337. if (user != null)
  338. {
  339. return user.PhoneNumber != null;
  340. }
  341. return false;
  342. }
  343. public enum ManageMessageId
  344. {
  345. AddPhoneSuccess,
  346. ChangePasswordSuccess,
  347. SetTwoFactorSuccess,
  348. SetPasswordSuccess,
  349. RemoveLoginSuccess,
  350. RemovePhoneSuccess,
  351. Error
  352. }
  353. #endregion
  354. }
  355. }