private bool ExecuteAccountEdit(string email, SingleAccountEdit editOperation) { switch (editOperation.Flag) { case EditType.New: _logger.LogInformation("Creating user for email {} with permission {}", email, editOperation.Permission.ToString()); var emailCreated = _accountManager.CreateUser(email); var user = _accountManager.GetAccountInfoByEmail(email); editOperation.VersionStamp = user.LastUpdate; var emailSending = _emailService.SendMessage(email, _configuration.GetValue <string>("WelcomeEmail:Subject", ""), _configuration.GetValue <string>("WelcomeEmail:Text", "")); if (!emailSending.IsSuccessful) { _logger.LogError($"Tried to send an email to {email}, but it failed with {emailSending.ErrorMessage}"); } return(emailCreated && _accountManager.SetUserRole(email, editOperation)); case EditType.Update: _logger.LogInformation("Setting role of user {} to {}", email, editOperation.Permission.ToString()); return(_accountManager.SetUserRole(email, editOperation)); case EditType.Delete: _logger.LogInformation("Removing user with email {}", email); return(_accountManager.RemoveUserByEmail(email)); default: throw new Exception("Unsupported operation"); } }
public bool SetUserRole(string userEmail, SingleAccountEdit edit) { var user = _userManager.FindByEmailAsync(userEmail).Result; if (user == null) { throw new ArgumentException($"Cannot set role for non existing user '{userEmail}'"); } if (user.LastUpdate.Value.CompareTo(edit.VersionStamp.Value) != 0) { _logger.LogWarning("Invalid timestamp when editing role of user {}", userEmail); _logger.LogDebug("Most recent: {}; attempted: {}", user.LastUpdate.Value.Ticks, edit.VersionStamp.Value.Ticks); return(false); } var succeededClearing = ClearUserRoles(user); var aspNetRoles = GetAspNetRolesForUiRole(edit.Permission); var hadErrorAddingRoles = aspNetRoles.Select(r => AddAspNetRoleToUser(r, user)).Where(b => !b).Any(); user.LastUpdate = DateTime.UtcNow; _userManager.UpdateSecurityStampAsync(user).Wait(); return(succeededClearing && !hadErrorAddingRoles && _userManager.UpdateAsync(user).Result.Succeeded); }
public async Task <IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) { if (remoteError != null) { _logger.LogError($"Error from external provider: {remoteError}"); return(Redirect(AccessDeniedPath)); } var info = await _signInManager.GetExternalLoginInfoAsync(); if (info == null) { _logger.LogWarning("External provider returned no info"); return(Redirect(AccessDeniedPath)); } // Sign in the user with this external login provider if the user already has a login. var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent : false, bypassTwoFactor : true); var email = info.Principal.FindFirstValue(ClaimTypes.Email); var user = _userManager.FindByEmailAsync(email).Result; if (result.Succeeded) { _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider); user.LastLoginTime = DateTime.UtcNow; _userManager.UpdateAsync(user).Wait(); return(RedirectToLocal(returnUrl)); } if (result.IsLockedOut) { _logger.LogWarning($"User {email} is locked out"); return(Redirect(AccessDeniedPath)); } // if the user doesn't exist but his email is @fee.org, create the user var emailCreated = true; if (user == null && email.EndsWith(FeeEmailDomain)) { _logger.LogInformation($"Creating read-only user for email {email}"); emailCreated = _accountManager.CreateUser(email); user = _userManager.FindByEmailAsync(email).Result; var editOperation = new SingleAccountEdit() { Permission = YearApPermissionLevels.ReadOnly, VersionStamp = user.LastUpdate, Flag = EditType.New, }; emailCreated = emailCreated && _accountManager.SetUserRole(email, editOperation); var emailSending = _emailService.SendMessage(email, _configuration.GetValue <string>("WelcomeEmail:Subject", ""), _configuration.GetValue <string>("WelcomeEmail:Text", "")); if (!emailSending.IsSuccessful) { _logger.LogError($"Tried to send an email to {email}, but it failed with {emailSending.ErrorMessage}"); } } // if the user exists but didn't succeed, associate his account to the new provider if (user != null && emailCreated) { _logger.LogInformation($"Associating {email} with external provider"); var associate = await _userManager.AddLoginAsync(user, info); if (associate.Succeeded) { await _signInManager.SignInAsync(user, isPersistent : false); _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider); user.LastLoginTime = DateTime.UtcNow; _userManager.UpdateAsync(user).Wait(); return(RedirectToLocal(returnUrl)); } } _logger.LogWarning("User doesn't exist"); // if the user doesn't exist, his access is denied return(Redirect(AccessDeniedPath)); }