PageRenderTime 64ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/Web/Ispinia/MVC6_Seed_Project/src/MVC6_Seed_Project/Controllers/ManageController.cs

https://gitlab.com/Meteor-MC/plugins
C# | 347 lines | 287 code | 25 blank | 35 comment | 42 complexity | 58ac3bf9f6cc18a47b9b3fc9dad397fd MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using System.Security.Claims;
  6. using Microsoft.AspNet.Authorization;
  7. using Microsoft.AspNet.Identity;
  8. using Microsoft.AspNet.Mvc;
  9. using Microsoft.Extensions.Logging;
  10. using MVC6_Seed_Project.Models;
  11. using MVC6_Seed_Project.Services;
  12. using MVC6_Seed_Project.ViewModels.Manage;
  13. namespace MVC6_Seed_Project.Controllers
  14. {
  15. [Authorize]
  16. public class ManageController : Controller
  17. {
  18. private readonly UserManager<ApplicationUser> _userManager;
  19. private readonly SignInManager<ApplicationUser> _signInManager;
  20. private readonly IEmailSender _emailSender;
  21. private readonly ISmsSender _smsSender;
  22. private readonly ILogger _logger;
  23. public ManageController(
  24. UserManager<ApplicationUser> userManager,
  25. SignInManager<ApplicationUser> signInManager,
  26. IEmailSender emailSender,
  27. ISmsSender smsSender,
  28. ILoggerFactory loggerFactory)
  29. {
  30. _userManager = userManager;
  31. _signInManager = signInManager;
  32. _emailSender = emailSender;
  33. _smsSender = smsSender;
  34. _logger = loggerFactory.CreateLogger<ManageController>();
  35. }
  36. //
  37. // GET: /Manage/Index
  38. [HttpGet]
  39. public async Task<IActionResult> Index(ManageMessageId? message = null)
  40. {
  41. ViewData["StatusMessage"] =
  42. message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
  43. : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
  44. : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
  45. : message == ManageMessageId.Error ? "An error has occurred."
  46. : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
  47. : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
  48. : "";
  49. var user = await GetCurrentUserAsync();
  50. var model = new IndexViewModel
  51. {
  52. HasPassword = await _userManager.HasPasswordAsync(user),
  53. PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
  54. TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
  55. Logins = await _userManager.GetLoginsAsync(user),
  56. BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user)
  57. };
  58. return View(model);
  59. }
  60. //
  61. // POST: /Manage/RemoveLogin
  62. [HttpPost]
  63. [ValidateAntiForgeryToken]
  64. public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
  65. {
  66. ManageMessageId? message = ManageMessageId.Error;
  67. var user = await GetCurrentUserAsync();
  68. if (user != null)
  69. {
  70. var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
  71. if (result.Succeeded)
  72. {
  73. await _signInManager.SignInAsync(user, isPersistent: false);
  74. message = ManageMessageId.RemoveLoginSuccess;
  75. }
  76. }
  77. return RedirectToAction(nameof(ManageLogins), new { Message = message });
  78. }
  79. //
  80. // GET: /Manage/AddPhoneNumber
  81. public IActionResult AddPhoneNumber()
  82. {
  83. return View();
  84. }
  85. //
  86. // POST: /Manage/AddPhoneNumber
  87. [HttpPost]
  88. [ValidateAntiForgeryToken]
  89. public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
  90. {
  91. if (!ModelState.IsValid)
  92. {
  93. return View(model);
  94. }
  95. // Generate the token and send it
  96. var user = await GetCurrentUserAsync();
  97. var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
  98. await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
  99. return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
  100. }
  101. //
  102. // POST: /Manage/EnableTwoFactorAuthentication
  103. [HttpPost]
  104. [ValidateAntiForgeryToken]
  105. public async Task<IActionResult> EnableTwoFactorAuthentication()
  106. {
  107. var user = await GetCurrentUserAsync();
  108. if (user != null)
  109. {
  110. await _userManager.SetTwoFactorEnabledAsync(user, true);
  111. await _signInManager.SignInAsync(user, isPersistent: false);
  112. _logger.LogInformation(1, "User enabled two-factor authentication.");
  113. }
  114. return RedirectToAction(nameof(Index), "Manage");
  115. }
  116. //
  117. // POST: /Manage/DisableTwoFactorAuthentication
  118. [HttpPost]
  119. [ValidateAntiForgeryToken]
  120. public async Task<IActionResult> DisableTwoFactorAuthentication()
  121. {
  122. var user = await GetCurrentUserAsync();
  123. if (user != null)
  124. {
  125. await _userManager.SetTwoFactorEnabledAsync(user, false);
  126. await _signInManager.SignInAsync(user, isPersistent: false);
  127. _logger.LogInformation(2, "User disabled two-factor authentication.");
  128. }
  129. return RedirectToAction(nameof(Index), "Manage");
  130. }
  131. //
  132. // GET: /Manage/VerifyPhoneNumber
  133. [HttpGet]
  134. public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
  135. {
  136. var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
  137. // Send an SMS to verify the phone number
  138. return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
  139. }
  140. //
  141. // POST: /Manage/VerifyPhoneNumber
  142. [HttpPost]
  143. [ValidateAntiForgeryToken]
  144. public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
  145. {
  146. if (!ModelState.IsValid)
  147. {
  148. return View(model);
  149. }
  150. var user = await GetCurrentUserAsync();
  151. if (user != null)
  152. {
  153. var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
  154. if (result.Succeeded)
  155. {
  156. await _signInManager.SignInAsync(user, isPersistent: false);
  157. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
  158. }
  159. }
  160. // If we got this far, something failed, redisplay the form
  161. ModelState.AddModelError(string.Empty, "Failed to verify phone number");
  162. return View(model);
  163. }
  164. //
  165. // GET: /Manage/RemovePhoneNumber
  166. [HttpGet]
  167. public async Task<IActionResult> RemovePhoneNumber()
  168. {
  169. var user = await GetCurrentUserAsync();
  170. if (user != null)
  171. {
  172. var result = await _userManager.SetPhoneNumberAsync(user, null);
  173. if (result.Succeeded)
  174. {
  175. await _signInManager.SignInAsync(user, isPersistent: false);
  176. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
  177. }
  178. }
  179. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  180. }
  181. //
  182. // GET: /Manage/ChangePassword
  183. [HttpGet]
  184. public IActionResult ChangePassword()
  185. {
  186. return View();
  187. }
  188. //
  189. // POST: /Manage/ChangePassword
  190. [HttpPost]
  191. [ValidateAntiForgeryToken]
  192. public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
  193. {
  194. if (!ModelState.IsValid)
  195. {
  196. return View(model);
  197. }
  198. var user = await GetCurrentUserAsync();
  199. if (user != null)
  200. {
  201. var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
  202. if (result.Succeeded)
  203. {
  204. await _signInManager.SignInAsync(user, isPersistent: false);
  205. _logger.LogInformation(3, "User changed their password successfully.");
  206. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
  207. }
  208. AddErrors(result);
  209. return View(model);
  210. }
  211. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  212. }
  213. //
  214. // GET: /Manage/SetPassword
  215. [HttpGet]
  216. public IActionResult SetPassword()
  217. {
  218. return View();
  219. }
  220. //
  221. // POST: /Manage/SetPassword
  222. [HttpPost]
  223. [ValidateAntiForgeryToken]
  224. public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
  225. {
  226. if (!ModelState.IsValid)
  227. {
  228. return View(model);
  229. }
  230. var user = await GetCurrentUserAsync();
  231. if (user != null)
  232. {
  233. var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
  234. if (result.Succeeded)
  235. {
  236. await _signInManager.SignInAsync(user, isPersistent: false);
  237. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
  238. }
  239. AddErrors(result);
  240. return View(model);
  241. }
  242. return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  243. }
  244. //GET: /Manage/ManageLogins
  245. [HttpGet]
  246. public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
  247. {
  248. ViewData["StatusMessage"] =
  249. message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
  250. : message == ManageMessageId.AddLoginSuccess ? "The external login was added."
  251. : message == ManageMessageId.Error ? "An error has occurred."
  252. : "";
  253. var user = await GetCurrentUserAsync();
  254. if (user == null)
  255. {
  256. return View("Error");
  257. }
  258. var userLogins = await _userManager.GetLoginsAsync(user);
  259. var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
  260. ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
  261. return View(new ManageLoginsViewModel
  262. {
  263. CurrentLogins = userLogins,
  264. OtherLogins = otherLogins
  265. });
  266. }
  267. //
  268. // POST: /Manage/LinkLogin
  269. [HttpPost]
  270. [ValidateAntiForgeryToken]
  271. public IActionResult LinkLogin(string provider)
  272. {
  273. // Request a redirect to the external login provider to link a login for the current user
  274. var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
  275. var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, User.GetUserId());
  276. return new ChallengeResult(provider, properties);
  277. }
  278. //
  279. // GET: /Manage/LinkLoginCallback
  280. [HttpGet]
  281. public async Task<ActionResult> LinkLoginCallback()
  282. {
  283. var user = await GetCurrentUserAsync();
  284. if (user == null)
  285. {
  286. return View("Error");
  287. }
  288. var info = await _signInManager.GetExternalLoginInfoAsync(User.GetUserId());
  289. if (info == null)
  290. {
  291. return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
  292. }
  293. var result = await _userManager.AddLoginAsync(user, info);
  294. var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
  295. return RedirectToAction(nameof(ManageLogins), new { Message = message });
  296. }
  297. #region Helpers
  298. private void AddErrors(IdentityResult result)
  299. {
  300. foreach (var error in result.Errors)
  301. {
  302. ModelState.AddModelError(string.Empty, error.Description);
  303. }
  304. }
  305. public enum ManageMessageId
  306. {
  307. AddPhoneSuccess,
  308. AddLoginSuccess,
  309. ChangePasswordSuccess,
  310. SetTwoFactorSuccess,
  311. SetPasswordSuccess,
  312. RemoveLoginSuccess,
  313. RemovePhoneSuccess,
  314. Error
  315. }
  316. private async Task<ApplicationUser> GetCurrentUserAsync()
  317. {
  318. return await _userManager.FindByIdAsync(HttpContext.User.GetUserId());
  319. }
  320. #endregion
  321. }
  322. }