)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Home » Code Library » ManageController (Ia.Wa.Controllers)

Public general use code classes and xml files that we've compiled and used over the years:

    1: // Licensed to the .NET Foundation under one or more agreements.
    2: // The .NET Foundation licenses this file to you under the MIT license.
    3:  
    4: using Ia.Wa.Models;
    5: using Ia.Wa.Models.ManageViewModels;
    6: using IdentitySample.Services;
    7: using Microsoft.AspNetCore.Authorization;
    8: using Microsoft.AspNetCore.Identity;
    9: using Microsoft.AspNetCore.Mvc;
   10:  
   11: namespace Ia.Wa.Controllers
   12: {
   13:     ////////////////////////////////////////////////////////////////////////////
   14:  
   15:     /// <summary publish="true">
   16:     ///
   17:     /// </summary>
   18:     /// 
   19:     /// <remarks> 
   20:     /// Copyright � 2006-2025 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   21:     ///
   22:     /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
   23:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   24:     ///
   25:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   26:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   27:     /// 
   28:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   29:     /// 
   30:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   31:     /// </remarks> 
   32:     [Authorize]
   33:     public class ManageController : Controller
   34:     {
   35:         private readonly UserManager<IdentityUser> _userManager;
   36:         private readonly SignInManager<IdentityUser> _signInManager;
   37:         private readonly IEmailSender _emailSender;
   38:         private readonly ISmsSender _smsSender;
   39:         private readonly ILogger _logger;
   40:  
   41:         public ManageController(
   42:         UserManager<IdentityUser> userManager,
   43:         SignInManager<IdentityUser> signInManager,
   44:         IEmailSender emailSender,
   45:         ISmsSender smsSender,
   46:         ILoggerFactory loggerFactory)
   47:         {
   48:             _userManager = userManager;
   49:             _signInManager = signInManager;
   50:             _emailSender = emailSender;
   51:             _smsSender = smsSender;
   52:             _logger = loggerFactory.CreateLogger<ManageController>();
   53:         }
   54:  
   55:         //
   56:         // GET: /Manage/Index
   57:         [HttpGet]
   58:         [Route("identity/manage")]
   59:         public async Task<IActionResult> Index(ManageMessageId? message = null)
   60:         {
   61:             ViewData["StatusMessage"] =
   62:                 message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
   63:                 : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
   64:                 : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
   65:                 : message == ManageMessageId.Error ? "An error has occurred."
   66:                 : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
   67:                 : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
   68:                 : "";
   69:  
   70:             var user = await GetCurrentUserAsync();
   71:             var model = new IndexViewModel
   72:             {
   73:                 HasPassword = await _userManager.HasPasswordAsync(user),
   74:                 PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
   75:                 TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
   76:                 Logins = await _userManager.GetLoginsAsync(user),
   77:                 BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user),
   78:                 AuthenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user)
   79:             };
   80:             return View(model);
   81:         }
   82:  
   83:         //
   84:         // POST: /Manage/RemoveLogin
   85:         [HttpPost]
   86:         [ValidateAntiForgeryToken]
   87:         [Route("identity/manage/remove-login")]
   88:         public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
   89:         {
   90:             ManageMessageId? message = ManageMessageId.Error;
   91:             var user = await GetCurrentUserAsync();
   92:             if (user != null)
   93:             {
   94:                 var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
   95:                 if (result.Succeeded)
   96:                 {
   97:                     await _signInManager.SignInAsync(user, isPersistent: false);
   98:                     message = ManageMessageId.RemoveLoginSuccess;
   99:                 }
  100:             }
  101:             return RedirectToAction(nameof(ManageLogins), new { Message = message });
  102:         }
  103:  
  104:         //
  105:         // GET: /Manage/AddPhoneNumber
  106:         [Route("identity/manage/add-phone-number")]
  107:         public IActionResult AddPhoneNumber()
  108:         {
  109:             return View();
  110:         }
  111:  
  112:         //
  113:         // POST: /Manage/AddPhoneNumber
  114:         [HttpPost]
  115:         [ValidateAntiForgeryToken]
  116:         [Route("identity/manage/add-phone-number")]
  117:         public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
  118:         {
  119:             if (!ModelState.IsValid)
  120:             {
  121:                 return View(model);
  122:             }
  123:             // Generate the token and send it
  124:             var user = await GetCurrentUserAsync();
  125:             var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
  126:             await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
  127:             return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
  128:         }
  129:  
  130:         //
  131:         // POST: /Manage/ResetAuthenticatorKey
  132:         [HttpPost]
  133:         [ValidateAntiForgeryToken]
  134:         [Route("identity/manage/reset-authenticator-key")]
  135:         public async Task<IActionResult> ResetAuthenticatorKey()
  136:         {
  137:             var user = await GetCurrentUserAsync();
  138:             if (user != null)
  139:             {
  140:                 await _userManager.ResetAuthenticatorKeyAsync(user);
  141:                 _logger.LogInformation(1, "User reset authenticator key.");
  142:             }
  143:             return RedirectToAction(nameof(Index), "Manage");
  144:         }
  145:  
  146:         //
  147:         // POST: /Manage/GenerateRecoveryCode
  148:         [HttpPost]
  149:         [ValidateAntiForgeryToken]
  150:         [Route("identity/manage/generate-recovery-code")]
  151:         public async Task<IActionResult> GenerateRecoveryCode()
  152:         {
  153:             var user = await GetCurrentUserAsync();
  154:             if (user != null)
  155:             {
  156:                 var codes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 5);
  157:                 _logger.LogInformation(1, "User generated new recovery code.");
  158:                 return View("DisplayRecoveryCodes", new DisplayRecoveryCodesViewModel { Codes = codes });
  159:             }
  160:             return View("Error");
  161:         }
  162:  
  163:         //
  164:         // POST: /Manage/EnableTwoFactorAuthentication
  165:         [HttpPost]
  166:         [ValidateAntiForgeryToken]
  167:         [Route("identity/manage/enable-two-factor-authentication")]
  168:         public async Task<IActionResult> EnableTwoFactorAuthentication()
  169:         {
  170:             var user = await GetCurrentUserAsync();
  171:             if (user != null)
  172:             {
  173:                 await _userManager.SetTwoFactorEnabledAsync(user, true);
  174:                 await _signInManager.SignInAsync(user, isPersistent: false);
  175:                 _logger.LogInformation(1, "User enabled two-factor authentication.");
  176:             }
  177:             return RedirectToAction(nameof(Index), "Manage");
  178:         }
  179:  
  180:         //
  181:         // POST: /Manage/DisableTwoFactorAuthentication
  182:         [HttpPost]
  183:         [ValidateAntiForgeryToken]
  184:         [Route("identity/manage/disable-two-factor-authentication")]
  185:         public async Task<IActionResult> DisableTwoFactorAuthentication()
  186:         {
  187:             var user = await GetCurrentUserAsync();
  188:             if (user != null)
  189:             {
  190:                 await _userManager.SetTwoFactorEnabledAsync(user, false);
  191:                 await _signInManager.SignInAsync(user, isPersistent: false);
  192:                 _logger.LogInformation(2, "User disabled two-factor authentication.");
  193:             }
  194:             return RedirectToAction(nameof(Index), "Manage");
  195:         }
  196:  
  197:         //
  198:         // GET: /Manage/VerifyPhoneNumber
  199:         [HttpGet]
  200:         [Route("identity/manage/verify-phone-number")]
  201:         public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
  202:         {
  203:             var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
  204:             // Send an SMS to verify the phone number
  205:             return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
  206:         }
  207:  
  208:         //
  209:         // POST: /Manage/VerifyPhoneNumber
  210:         [HttpPost]
  211:         [ValidateAntiForgeryToken]
  212:         [Route("identity/manage/verify-phone-number")]
  213:         public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
  214:         {
  215:             if (!ModelState.IsValid)
  216:             {
  217:                 return View(model);
  218:             }
  219:             var user = await GetCurrentUserAsync();
  220:             if (user != null)
  221:             {
  222:                 var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
  223:                 if (result.Succeeded)
  224:                 {
  225:                     await _signInManager.SignInAsync(user, isPersistent: false);
  226:                     return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
  227:                 }
  228:             }
  229:             // If we got this far, something failed, redisplay the form
  230:             ModelState.AddModelError(string.Empty, "Failed to verify phone number");
  231:             return View(model);
  232:         }
  233:  
  234:         //
  235:         // GET: /Manage/RemovePhoneNumber
  236:         [HttpPost]
  237:         [ValidateAntiForgeryToken]
  238:         [Route("identity/manage/remove-phone-number")]
  239:         public async Task<IActionResult> RemovePhoneNumber()
  240:         {
  241:             var user = await GetCurrentUserAsync();
  242:             if (user != null)
  243:             {
  244:                 var result = await _userManager.SetPhoneNumberAsync(user, null);
  245:                 if (result.Succeeded)
  246:                 {
  247:                     await _signInManager.SignInAsync(user, isPersistent: false);
  248:                     return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
  249:                 }
  250:             }
  251:             return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  252:         }
  253:  
  254:         //
  255:         // GET: /Manage/ChangePassword
  256:         [HttpGet]
  257:         [Route("identity/manage/change-password")]
  258:         public IActionResult ChangePassword()
  259:         {
  260:             return View();
  261:         }
  262:  
  263:         //
  264:         // POST: /Manage/ChangePassword
  265:         [HttpPost]
  266:         [ValidateAntiForgeryToken]
  267:         [Route("identity/manage/change-password")]
  268:         public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
  269:         {
  270:             if (!ModelState.IsValid)
  271:             {
  272:                 return View(model);
  273:             }
  274:             var user = await GetCurrentUserAsync();
  275:             if (user != null)
  276:             {
  277:                 var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
  278:                 if (result.Succeeded)
  279:                 {
  280:                     await _signInManager.SignInAsync(user, isPersistent: false);
  281:                     _logger.LogInformation(3, "User changed their password successfully.");
  282:                     return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
  283:                 }
  284:                 AddErrors(result);
  285:                 return View(model);
  286:             }
  287:             return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  288:         }
  289:  
  290:         //
  291:         // GET: /Manage/SetPassword
  292:         [HttpGet]
  293:         [Route("identity/manage/set-password")]
  294:         public IActionResult SetPassword()
  295:         {
  296:             return View();
  297:         }
  298:  
  299:         //
  300:         // POST: /Manage/SetPassword
  301:         [HttpPost]
  302:         [ValidateAntiForgeryToken]
  303:         [Route("identity/manage/set-password")]
  304:         public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
  305:         {
  306:             if (!ModelState.IsValid)
  307:             {
  308:                 return View(model);
  309:             }
  310:  
  311:             var user = await GetCurrentUserAsync();
  312:             if (user != null)
  313:             {
  314:                 var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
  315:                 if (result.Succeeded)
  316:                 {
  317:                     await _signInManager.SignInAsync(user, isPersistent: false);
  318:                     return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
  319:                 }
  320:                 AddErrors(result);
  321:                 return View(model);
  322:             }
  323:             return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  324:         }
  325:  
  326:         //GET: /Manage/ManageLogins
  327:         [HttpGet]
  328:         [Route("identity/manage/manage-logins")]
  329:         public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
  330:         {
  331:             ViewData["StatusMessage"] =
  332:                 message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
  333:                 : message == ManageMessageId.AddLoginSuccess ? "The external login was added."
  334:                 : message == ManageMessageId.Error ? "An error has occurred."
  335:                 : "";
  336:             var user = await GetCurrentUserAsync();
  337:             if (user == null)
  338:             {
  339:                 return View("Error");
  340:             }
  341:             var userLogins = await _userManager.GetLoginsAsync(user);
  342:             var schemes = await _signInManager.GetExternalAuthenticationSchemesAsync();
  343:             var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList();
  344:             ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
  345:             return View(new ManageLoginsViewModel
  346:             {
  347:                 CurrentLogins = userLogins,
  348:                 OtherLogins = otherLogins
  349:             });
  350:         }
  351:  
  352:         //
  353:         // POST: /Manage/LinkLogin
  354:         [HttpPost]
  355:         [ValidateAntiForgeryToken]
  356:         [Route("identity/manage/link-login")]
  357:         public IActionResult LinkLogin(string provider)
  358:         {
  359:             // Request a redirect to the external login provider to link a login for the current user
  360:             var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
  361:             var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
  362:             return Challenge(properties, provider);
  363:         }
  364:  
  365:         //
  366:         // GET: /Manage/LinkLoginCallback
  367:         [HttpGet]
  368:         [Route("identity/manage/link-login-callback")]
  369:         public async Task<ActionResult> LinkLoginCallback()
  370:         {
  371:             var user = await GetCurrentUserAsync();
  372:             if (user == null)
  373:             {
  374:                 return View("Error");
  375:             }
  376:             var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
  377:             if (info == null)
  378:             {
  379:                 return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
  380:             }
  381:             var result = await _userManager.AddLoginAsync(user, info);
  382:             var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
  383:             return RedirectToAction(nameof(ManageLogins), new { Message = message });
  384:         }
  385:  
  386:         #region Helpers
  387:  
  388:         private void AddErrors(IdentityResult result)
  389:         {
  390:             foreach (var error in result.Errors)
  391:             {
  392:                 ModelState.AddModelError(string.Empty, error.Description);
  393:             }
  394:         }
  395:  
  396:         public enum ManageMessageId
  397:         {
  398:             AddPhoneSuccess,
  399:             AddLoginSuccess,
  400:             ChangePasswordSuccess,
  401:             SetTwoFactorSuccess,
  402:             SetPasswordSuccess,
  403:             RemoveLoginSuccess,
  404:             RemovePhoneSuccess,
  405:             Error
  406:         }
  407:  
  408:         private Task<IdentityUser> GetCurrentUserAsync()
  409:         {
  410:             return _userManager.GetUserAsync(HttpContext.User);
  411:         }
  412:  
  413:         #endregion
  414:     }
  415: }