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

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

    1: using Ia.Ftn.Wa.Models.Application;
    2: using Microsoft.AspNetCore.Authorization;
    3: using Microsoft.AspNetCore.Identity;
    4: using Microsoft.AspNetCore.Mvc;
    5: using System.Diagnostics;
    6: using System.Net;
    7:  
    8: namespace Ia.Ftn.Wa.Controllers
    9: {
   10:     ////////////////////////////////////////////////////////////////////////////
   11:  
   12:     /// <summary publish="true">
   13:     ///
   14:     /// </summary>
   15:     /// 
   16:     /// <remarks> 
   17:     /// Copyright � 2006-2025 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   18:     ///
   19:     /// 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
   20:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   21:     ///
   22:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   23:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   24:     /// 
   25:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   26:     /// 
   27:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   28:     /// </remarks> 
   29:     [Authorize]
   30:     public class IdentityController : Controller
   31:     {
   32:         private static bool oneTimeCalled = false;
   33:         private readonly UserManager<Ia.Ftn.Cl.Models.StaffIdentityUser> userManager;
   34:         private readonly SignInManager<Ia.Ftn.Cl.Models.StaffIdentityUser> signInManager;
   35:         private readonly RoleManager<IdentityRole> roleManager;
   36:         private readonly ILogger logger;
   37:  
   38:         private static IdentityViewModel currentIdentityViewModel = new Ia.Ftn.Wa.Models.Application.IdentityViewModel();
   39:  
   40:         /////////////////////////////////////////////////////////////////////////////////
   41:  
   42:         /// <summary>
   43:         ///
   44:         /// </summary>
   45:         public IdentityController(UserManager<Ia.Ftn.Cl.Models.StaffIdentityUser> _userManager, SignInManager<Ia.Ftn.Cl.Models.StaffIdentityUser> _signInManager, RoleManager<IdentityRole> _roleManager, ILoggerFactory _loggerFactory)
   46:         {
   47:             userManager = _userManager;
   48:             signInManager = _signInManager;
   49:             roleManager = _roleManager;
   50:             logger = _loggerFactory.CreateLogger<IdentityController>();
   51:         }
   52:  
   53:         /////////////////////////////////////////////////////////////////////////////////
   54:  
   55:         /// <summary>
   56:         ///
   57:         /// </summary>
   58:         [Route("identity")]
   59:         public IActionResult Index()
   60:         {
   61:             return View();
   62:         }
   63:  
   64:         /////////////////////////////////////////////////////////////////////////////////
   65:  
   66:         /// <summary>
   67:         ///
   68:         /// </summary>
   69:         [HttpGet]
   70:         [AllowAnonymous]
   71:         [Route("identity/login")]
   72:         public IActionResult Login(string returnUrl = null)
   73:         {
   74:             ViewData["ReturnUrl"] = returnUrl;
   75:  
   76:             if (!oneTimeCalled)
   77:             {
   78:                 Ia.Ftn.Cl.Models.Data.Administration.CreateFrameworkIdentityRolesIfTheyDoNotExist(roleManager); // order important: role then user-role
   79:  
   80:                 Ia.Ftn.Cl.Models.Data.Administration.CreateApplicationUserAndStaffIfDoesNotExist(roleManager, userManager);
   81:  
   82:                 oneTimeCalled = true;
   83:             }
   84:  
   85:             return View();
   86:         }
   87:  
   88:         /////////////////////////////////////////////////////////////////////////////////
   89:  
   90:         /// <summary>
   91:         ///
   92:         /// </summary>
   93:         [HttpPost]
   94:         [AllowAnonymous]
   95:         [ValidateAntiForgeryToken]
   96:         [Route("identity/login")]
   97:         public async Task<IActionResult> Login(Ia.Ftn.Wa.Models.Identity.LoginViewModel loginViewModel, string returnUrl = null)
   98:         {
   99:             ViewData["ReturnUrl"] = returnUrl;
  100:  
  101:             if (ModelState.IsValid)
  102:             {
  103:                 // This doesn't count login failures towards account lockout
  104:                 // To enable password failures to trigger account lockout, set lockoutOnFailure: true
  105:                 var result = await signInManager.PasswordSignInAsync(loginViewModel.UserName, loginViewModel.Password, loginViewModel.RememberMe, lockoutOnFailure: false);
  106:                 if (result.Succeeded)
  107:                 {
  108:                     logger.LogInformation(1, "User logged in.");
  109:                     return RedirectToLocal(returnUrl);
  110:                 }
  111:                 /*
  112:                 if (result.RequiresTwoFactor)
  113:                 {
  114:                     return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
  115:                 }*/
  116:                 if (result.IsLockedOut)
  117:                 {
  118:                     logger.LogWarning(2, "User account locked out.");
  119:                     return View("Lockout");
  120:                 }
  121:                 else
  122:                 {
  123:                     ModelState.AddModelError(string.Empty, "Invalid login attempt.");
  124:                     return View(loginViewModel);
  125:                 }
  126:             }
  127:  
  128:             // If we got this far, something failed, redisplay form
  129:             return View(loginViewModel);
  130:         }
  131:  
  132:         /////////////////////////////////////////////////////////////////////////////////
  133:  
  134:         /// <summary>
  135:         ///
  136:         /// </summary>
  137:         [HttpPost]
  138:         [ValidateAntiForgeryToken]
  139:         [Route("identity/logoff")]
  140:         public async Task<IActionResult> LogOff()
  141:         {
  142:             await signInManager.SignOutAsync();
  143:  
  144:             logger.LogInformation(4, "User logged out.");
  145:  
  146:             return RedirectToAction(nameof(HomeController.Index), "Home");
  147:         }
  148:  
  149:         /////////////////////////////////////////////////////////////////////////////////
  150:  
  151:         /// <summary>
  152:         ///
  153:         /// </summary>
  154:         [Route("identity/profile")]
  155:         public IActionResult Profile()
  156:         {
  157:             return View();
  158:         }
  159:  
  160:         /////////////////////////////////////////////////////////////////////////////////
  161:  
  162:         /// <summary>
  163:         ///
  164:         /// </summary>
  165:         [HttpGet]
  166:         [Route("identity/change-password")]
  167:         public IActionResult ChangePassword()
  168:         {
  169:             return View();
  170:         }
  171:  
  172:         /////////////////////////////////////////////////////////////////////////////////
  173:  
  174:         /// <summary>
  175:         ///
  176:         /// </summary>
  177:         [HttpPost]
  178:         [ValidateAntiForgeryToken]
  179:         [Route("identity/change-password")]
  180:         public async Task<IActionResult> ChangePassword(Ia.Ftn.Wa.Models.IdentityViewModels.ChangePasswordViewModel model)
  181:         {
  182:             if (!ModelState.IsValid)
  183:             {
  184:                 return View(model);
  185:             }
  186:             var user = await GetCurrentUserAsync();
  187:             if (user != null)
  188:             {
  189:                 var result = await userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
  190:                 if (result.Succeeded)
  191:                 {
  192:                     await signInManager.SignInAsync(user, isPersistent: false);
  193:                     logger.LogInformation(3, "User changed their password successfully.");
  194:                     return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
  195:                 }
  196:                 AddErrors(result);
  197:                 return View(model);
  198:             }
  199:             return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
  200:         }
  201:  
  202:         /////////////////////////////////////////////////////////////////////////////////
  203:  
  204:         /// <summary>
  205:         ///
  206:         /// </summary>
  207:         [HttpGet]
  208:         [AllowAnonymous]
  209:         [Route("identity/reset-password")]
  210:         public IActionResult ResetPassword(string code = null)
  211:         {
  212:             return code == null ? View("Error") : View();
  213:         }
  214:  
  215:         /////////////////////////////////////////////////////////////////////////////////
  216:  
  217:         /// <summary>
  218:         ///
  219:         /// </summary>
  220:         [HttpPost]
  221:         [AllowAnonymous]
  222:         [ValidateAntiForgeryToken]
  223:         [Route("identity/reset-password")]
  224:         public async Task<IActionResult> ResetPassword(Ia.Ftn.Wa.Models.IdentityViewModels.ResetPasswordViewModel model)
  225:         {
  226:             if (!ModelState.IsValid)
  227:             {
  228:                 return View(model);
  229:             }
  230:  
  231:             var user = await userManager.FindByEmailAsync(model.Email);
  232:  
  233:             if (user == null)
  234:             {
  235:                 // Don't reveal that the user does not exist
  236:                 return RedirectToAction(nameof(IdentityController.ResetPasswordConfirmation), "Identity");
  237:             }
  238:  
  239:             var result = await userManager.ResetPasswordAsync(user, model.Code, model.Password);
  240:  
  241:             if (result.Succeeded)
  242:             {
  243:                 return RedirectToAction(nameof(IdentityController.ResetPasswordConfirmation), "Identity");
  244:             }
  245:  
  246:             AddErrors(result);
  247:  
  248:             return View();
  249:         }
  250:  
  251:         /////////////////////////////////////////////////////////////////////////////////
  252:  
  253:         /// <summary>
  254:         ///
  255:         /// </summary>
  256:         [HttpGet]
  257:         [AllowAnonymous]
  258:         [Route("identity/reset-password-confirmation")]
  259:         public IActionResult ResetPasswordConfirmation()
  260:         {
  261:             return View();
  262:         }
  263:  
  264:         /////////////////////////////////////////////////////////////////////////////////
  265:         /////////////////////////////////////////////////////////////////////////////////
  266:  
  267:         /// <summary>
  268:         ///
  269:         /// </summary>
  270:         [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
  271:         public IActionResult Error()
  272:         {
  273:             return View(new Ia.Ftn.Wa.Models.ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
  274:         }
  275:  
  276:         /////////////////////////////////////////////////////////////////////////////////
  277:         /////////////////////////////////////////////////////////////////////////////////
  278:  
  279:         #region Helpers
  280:  
  281:         private void AddErrors(IdentityResult result)
  282:         {
  283:             foreach (var error in result.Errors)
  284:             {
  285:                 ModelState.AddModelError(string.Empty, error.Description);
  286:             }
  287:         }
  288:  
  289:         public enum ManageMessageId
  290:         {
  291:             AddPhoneSuccess,
  292:             AddLoginSuccess,
  293:             ChangePasswordSuccess,
  294:             SetTwoFactorSuccess,
  295:             SetPasswordSuccess,
  296:             RemoveLoginSuccess,
  297:             RemovePhoneSuccess,
  298:             Error
  299:         }
  300:  
  301:         private Task<Ia.Ftn.Cl.Models.StaffIdentityUser> GetCurrentUserAsync()
  302:         {
  303:             return userManager.GetUserAsync(HttpContext.User);
  304:         }
  305:  
  306:         private IActionResult RedirectToLocal(string returnUrl)
  307:         {
  308:             if (Url.IsLocalUrl(returnUrl))
  309:             {
  310:                 return Redirect(returnUrl);
  311:             }
  312:             else
  313:             {
  314:                 return RedirectToAction(nameof(HomeController.Index), "Home");
  315:             }
  316:         }
  317:  
  318:         #endregion
  319:  
  320:         /////////////////////////////////////////////////////////////////////////////////
  321:         /////////////////////////////////////////////////////////////////////////////////
  322:     }
  323: }