public async Task <IActionResult> ExternalLogin([FromBody] Core.CSharp.Models.ExternalLoginInfo externalLoginInfo) { try { if (!TryValidateModel(externalLoginInfo)) { AppFunc.ExtractErrors(ModelState, ref ErrorsList); return(UnprocessableEntity(ErrorsList)); } User returnedUser = new User(); switch (externalLoginInfo.Type) { case CoreConst.RegistrationTypes.Google: returnedUser = await GetGoogleUserInfo(externalLoginInfo).ConfigureAwait(false); break; case CoreConst.RegistrationTypes.Facebook: returnedUser = await GetFacebookUserInfo(externalLoginInfo).ConfigureAwait(false); break; case CoreConst.RegistrationTypes.Github: returnedUser = await GetGithubUserInfo(externalLoginInfo).ConfigureAwait(false); break; } // Try to retrieve the user information from App database User newUser = await _DbContext.Users .Include(u => u.Role) .Include(u => u.RegistrationMethod) .SingleOrDefaultAsync(u => u.RegistrationMethod.Type == externalLoginInfo.Type && u.RegistrationMethod.ExternalLinkedId == returnedUser.RegistrationMethod.ExternalLinkedId) .ConfigureAwait(false); // if the user is already registered if (newUser != null) { // sign the user in without any password await _AuthManager.SignInAsync(newUser, externalLoginInfo.RememberMe).ConfigureAwait(false); var test = User; return(Ok(newUser)); } // else if the user is not registered // else return 206 partial content return(StatusCode(206, returnedUser)); } catch (Exception ee) { AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
// [Authorize(AppConst.AccessPolicies.Secret)] /// Done public async Task <IActionResult> Post([FromBody] Role newRole) { try { int langId = AppFunc.GetLanguageId(); /// if model validation failed if (!TryValidateModel(newRole)) { AppFunc.ExtractErrors(ModelState, ref ErrorsList); /// return Unprocessable Entity with all the errors return(UnprocessableEntity(ErrorsList)); } /// check the database to see if a role with the same name exists if (await AppDbContext.Roles.Include(r => r.RoleTranslates).Select(p => new Role { Name = p.RoleTranslates.FirstOrDefault(e => e.LangId == langId).Name, AccessClaim = p.AccessClaim, Id = p.Id }).AnyAsync(d => d.Name.Equals(newRole.Name) && d.AccessClaim.Equals(newRole.AccessClaim)).ConfigureAwait(false)) { /// extract the errors and return bad request containing the errors AppFunc.Error(ref ErrorsList, _localizer["Role already exists."].Value); return(StatusCode(412, ErrorsList)); } foreach (string lang in AppConst.SupportLanguages) { newRole.RoleTranslates.Add(new RoleTranslate() { LangId = AppFunc.GetLanguageId(lang), Name = newRole.Name }); } /// else role object is made without any errors /// Add the new role to the EF context await AppDbContext.Roles.AddAsync(newRole).ConfigureAwait(false); /// save the changes to the data base await AppDbContext.SaveChangesAsync().ConfigureAwait(false); /// return 201 created status with the new object /// and success message return(Created(_localizer["Success"].Value, newRole)); } catch (Exception) // DbUpdateException, DbUpdateConcurrencyException { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
//[Authorize(AppConst.AccessPolicies.Secret)] /// First Level Test Pass public async Task <IActionResult> Put([FromBody] User modifiedUser) { try { int langId = AppFunc.GetLanguageId(); /// Try to validate the model TryValidateModel(modifiedUser); /// remove the passwordHash and confrimPassword since /// the password update gets handled by another method in this class ModelState.Remove("PasswordHash"); if (!ModelState.IsValid) { /// extract the errors and return bad request containing the errors AppFunc.ExtractErrors(ModelState, ref ErrorsList); return(UnprocessableEntity(ErrorsList)); } /// if the user record with the same id is not found if (!AppDbContext.Users.Any(u => u.Id == modifiedUser.Id)) { AppFunc.Error(ref ErrorsList, _localizer["User not found."].Value); return(StatusCode(412, ErrorsList)); } /// find the current user details from the database User userDetails = AppDbContext.Users.Find(modifiedUser.Id); userDetails.UserTranslates = await AppDbContext.UserTranslate.AsTracking().Where(ut => ut.User.Id == userDetails.Id) .ToListAsync().ConfigureAwait(false); UserTranslate userTranslate = userDetails.UserTranslates.SingleOrDefault(ut => ut.LangId == langId); /// update the user details with the new details userTranslate.FirstName = modifiedUser.FirstName; userTranslate.Surname = modifiedUser.Surname; userDetails.Email = modifiedUser.Email; userDetails.PhoneNumber = modifiedUser.PhoneNumber; userDetails.Role = modifiedUser.Role; /// thus update user in the context AppDbContext.Users.Update(userDetails); /// save the changes to the database await AppDbContext.SaveChangesAsync().ConfigureAwait(false); /// thus return 200 ok status with the updated object return(Ok(userDetails)); } catch (Exception) // DbUpdateException, DbUpdateConcurrencyException { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
// [Authorize(AppConst.AccessPolicies.Secret)] /// Done public async Task <IActionResult> Put([FromBody] Role modifiedRole) { try { int langId = AppFunc.GetLanguageId(); /// if model validation failed if (!TryValidateModel(modifiedRole)) { AppFunc.ExtractErrors(ModelState, ref ErrorsList); /// return Unprocessable Entity with all the errors return(UnprocessableEntity(ErrorsList)); } /// check the database to see if a Category with the same name exists if (await AppDbContext.Roles.Include(r => r.RoleTranslates).Select(p => new Role { Name = p.RoleTranslates.FirstOrDefault(e => e.LangId == langId).Name, AccessClaim = p.AccessClaim, Id = p.Id }).AnyAsync(d => d.Name == modifiedRole.Name && d.AccessClaim.Equals(modifiedRole.AccessClaim) && d.Id != modifiedRole.Id).ConfigureAwait(false)) { /// extract the errors and return bad request containing the errors AppFunc.Error(ref ErrorsList, _localizer["Role already exists."].Value); return(StatusCode(412, ErrorsList)); } modifiedRole.RoleTranslates = await AppDbContext.RolesTranslate .Where(rt => rt.Role.Id == modifiedRole.Id).ToListAsync().ConfigureAwait(false); modifiedRole.RoleTranslates.SingleOrDefault(rt => rt.LangId == langId).Name = modifiedRole.Name; /// else Role object is made without any errors /// Update the current Role on EF context AppDbContext.Roles.Update(modifiedRole); /// save the changes to the data base await AppDbContext.SaveChangesAsync().ConfigureAwait(false); /// return 200 OK (Update) status with the modified object /// and success message return(Ok(modifiedRole)); } catch (Exception) // DbUpdateException, DbUpdateConcurrencyException { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
[HttpPut("PutMyPassword/{currentPassword}/{password}")] /// Ready For Test public async Task <IActionResult> PutMyPassword(string currentPassword, string password) { try { int.TryParse(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value, out int userId); User user = AppDbContext.Users.Find(userId); IdentityResult result = await _UserManager.ChangePasswordAsync(user, currentPassword, password); if (!result.Succeeded) { AppFunc.ExtractErrors(result.Errors, ref ErrorsList); return(StatusCode(412, ErrorsList)); } return(Ok(result)); } catch (Exception) // DbUpdateException, DbUpdateConcurrencyException { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
/// <summary> /// Create a new User /// </summary> private async Task <IActionResult> CreateUser(User newUser) { try { newUser.PasswordHash = newUser.TempPassword; if (newUser.RegistrationMethod.Type != CoreConst.RegistrationTypes.Application) { newUser.PasswordHash = CoreFunc.PasswordGenerator(20, 5, 5, 5, 5); } ModelState.Clear(); /// if model validation failed if (!TryValidateModel(newUser)) { AppFunc.ExtractErrors(ModelState, ref ErrorsList); /// return bad request with all the errors return(UnprocessableEntity(ErrorsList)); } /// check the database to see if a user with the same email exists if (_DbContext.Users.Any(d => d.Email == newUser.Email)) { /// extract the errors and return bad request containing the errors AppFunc.Error(ref ErrorsList, "Email already exists."); return(StatusCode(412, ErrorsList)); } /// Create the new user IdentityResult newUserResult = await _UserManager.CreateAsync(newUser, newUser.PasswordHash) .ConfigureAwait(false); /// If result failed if (!newUserResult.Succeeded) { /// Add the error below to the error list and return bad request foreach (var error in newUserResult.Errors) { AppFunc.Error(ref ErrorsList, error.Description, error.Code); } return(StatusCode(417, ErrorsList)); } /// else result is successful the try to add the access claim for the user IdentityResult addedClaimResult = await _UserManager.AddClaimAsync( newUser, new Claim(AppConst.AccessClaims.Type, newUser.Role.AccessClaim) ).ConfigureAwait(false); /// if claim failed to be created if (!addedClaimResult.Succeeded) { /// remove the user account and return appropriate error _DbContext.Users.Remove(newUser); await _DbContext.SaveChangesAsync().ConfigureAwait(false); AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } isUserCreated = true; /// return 201 created status with the new object /// and success message return(Created("Success", newUser)); } catch (Exception ee) // DbUpdateException, DbUpdateConcurrencyException { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
public async Task <IActionResult> LoginAsync([FromBody] LoginInfo loginInfo) { try { ///// If email parameter is empty ///// return "unauthorized" response (stop code execution) //if (string.IsNullOrWhiteSpace(loginInfo.UserName)) // /// in the case any exceptions return the following error // AppFunc.Error(ref ErrorsList, "UserName is required!", "UserName"); //if (string.IsNullOrWhiteSpace(loginInfo.Password)) // AppFunc.Error(ref ErrorsList, "Password is required!", "Password"); //if (ErrorsList.Count > 0) // return BadRequest(ErrorsList); /// if model validation failed if (!TryValidateModel(loginInfo)) { AppFunc.ExtractErrors(ModelState, ref ErrorsList); /// return Unprocessable Entity with all the errors return(UnprocessableEntity(ErrorsList)); } /// Find the user with the provided email address User user = await _UserManager .FindByNameAsync(loginInfo.UserName).ConfigureAwait(false); /// if no user is found on the database // return "unauthorized" response (stop code execution) if (user == null) { /// in the case any exceptions return the following error AppFunc.Error(ref ErrorsList, "UserName not registered", "UserName"); return(BadRequest(ErrorsList)); } /// Check if user's account is locked if (user.LockoutEnabled) { /// get the current lockout end dateTime var currentLockoutDate = await _UserManager.GetLockoutEndDateAsync(user).ConfigureAwait(false); /// if the user's lockout is not expired (stop code execution) if (user.LockoutEnd > DateTimeOffset.UtcNow) { /// in the case any exceptions return the following error AppFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}" , AppFunc.CompareWithCurrentTime(user.LockoutEnd))); return(BadRequest(ErrorsList)); } /// else lockout time has expired // disable user lockout await _UserManager.SetLockoutEnabledAsync(user, false).ConfigureAwait(false); await _UserManager.ResetAccessFailedCountAsync(user).ConfigureAwait(false); } /// else user account is not locked // Attempt to sign in the user var SignInResult = await _SignInManager .PasswordSignInAsync(user, loginInfo.Password, loginInfo.RememberMe, false).ConfigureAwait(false); /// If password sign-in succeeds // responded ok 200 status code with //the user's role attached (stop code execution) if (!SignInResult.Succeeded) { /// else login attempt failed /// increase and update the user's failed login attempt by 1 await _UserManager.AccessFailedAsync(user).ConfigureAwait(false); /// if failed login attempt is less than/ equal to 5 (stop code execution) if (user.AccessFailedCount <= 5) { /// in the case any exceptions return the following error AppFunc.Error(ref ErrorsList, "Incorrect Password!", "password"); return(Unauthorized(ErrorsList)); } /// else user has tried their password more than 15 times // lock the user and ask them to reset their password user.LockoutEnabled = true; user.LockoutEnd = DateTimeOffset.UtcNow.AddMinutes(user.AccessFailedCount); /// in the case any exceptions return the following error AppFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}" , AppFunc.CompareWithCurrentTime(user.LockoutEnd))); return(Unauthorized(ErrorsList)); } user.Role = (await AppDbContext.Users.Include(u => u.Role) .FirstOrDefaultAsync(u => u.Id == user.Id) .ConfigureAwait(false)) ?.Role; return(Ok(user)); } catch (Exception) { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }
/// <summary> /// Create a new User /// </summary> private async Task <IActionResult> CreateUser(User newUser) { try { newUser.PasswordHash = newUser.TempPassword; newUser.TempPassword = string.Empty; ModelState.Clear(); TryValidateModel(newUser); ModelState.Remove("Role.Name"); /// if model validation failed if (!ModelState.IsValid) { AppFunc.ExtractErrors(ModelState, ref ErrorsList); /// return bad request with all the errors return(UnprocessableEntity(ErrorsList)); } /// check the database to see if a user with the same email exists if (AppDbContext.Users.AsNoTracking().Any(d => d.UserName == newUser.UserName)) { /// extract the errors and return bad request containing the errors AppFunc.Error(ref ErrorsList, _localizer["UserName already exists."].Value, "UserName"); return(StatusCode(412, ErrorsList)); } /// Create the new user IdentityResult newUserResult = await _UserManager.CreateAsync(newUser, newUser.PasswordHash) .ConfigureAwait(false); /// If result failed if (!newUserResult.Succeeded) { /// Add the error below to the error list and return bad request foreach (var error in newUserResult.Errors) { AppFunc.Error(ref ErrorsList, error.Description, error.Code); } return(StatusCode(417, ErrorsList)); } /// else result is successful the try to add the access claim for the user IdentityResult addedClaimResult = await _UserManager.AddClaimAsync( newUser, new Claim(AppConst.AccessClaimType, newUser.Role.AccessClaim) ).ConfigureAwait(false); /// if claim failed to be created if (!addedClaimResult.Succeeded) { /// remove the user account and return appropriate error AppDbContext.Users.Remove(newUser); await AppDbContext.SaveChangesAsync().ConfigureAwait(false); AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } foreach (string lang in AppConst.SupportLanguages) { await AppDbContext.UserTranslate.AddAsync(new UserTranslate() { LangId = AppFunc.GetLanguageId(lang), User = newUser, FirstName = newUser.FirstName, Surname = newUser.Surname }); } /// save the changes to the data base await AppDbContext.SaveChangesAsync().ConfigureAwait(false); isUserCreated = true; /// return 201 created status with the new object /// and success message return(Created(_localizer["Success"].Value, newUser)); } catch (Exception) // DbUpdateException, DbUpdateConcurrencyException { /// Add the error below to the error list and return bad request AppFunc.Error(ref ErrorsList, AppConst.CommonErrors.ServerError); return(StatusCode(417, ErrorsList)); } }