Updates the invite flow, we will always create a local user because we must do that due to the user groups being pre-determined.
This commit is contained in:
@@ -6,19 +6,16 @@ namespace Umbraco.Core.Models.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// The login provider for the login (i.e. Facebook, Google)
|
||||
///
|
||||
/// </summary>
|
||||
string LoginProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key representing the login for the provider
|
||||
///
|
||||
/// </summary>
|
||||
string ProviderKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User Id for the user who owns this login
|
||||
///
|
||||
/// </summary>
|
||||
int UserId { get; set; }
|
||||
}
|
||||
|
||||
@@ -361,38 +361,8 @@ namespace Umbraco.Web.Editors
|
||||
user = CheckUniqueEmail(userSave.Email, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);
|
||||
|
||||
var userMgr = TryGetOwinContext().Result.GetBackOfficeUserManager();
|
||||
var inviteArgs = new UserInviteEventArgs(
|
||||
Request.TryGetHttpContext().Result.GetCurrentRequestIpAddress(),
|
||||
performingUser: Security.GetUserId().Result,
|
||||
userSave);
|
||||
userMgr.RaiseSendingUserInvite(inviteArgs);
|
||||
|
||||
// If the event is handled then return the data
|
||||
if (inviteArgs.InviteHandled)
|
||||
{
|
||||
// if no local user was created then map the args manually for the UI
|
||||
if (inviteArgs.User == null)
|
||||
{
|
||||
return new UserDisplay
|
||||
{
|
||||
Name = userSave.Name,
|
||||
Email = userSave.Email,
|
||||
Username = userSave.Username
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
//map the save info over onto the user
|
||||
user = Mapper.Map(userSave, user);
|
||||
//ensure the invited date is set
|
||||
user.InvitedDate = DateTime.Now;
|
||||
//Save the updated user
|
||||
Services.UserService.Save(user);
|
||||
return Mapper.Map<UserDisplay>(user);
|
||||
}
|
||||
}
|
||||
|
||||
if (EmailSender.CanSendRequiredEmail == false)
|
||||
|
||||
if (!EmailSender.CanSendRequiredEmail && !userMgr.HasSendingUserInviteEventHandler)
|
||||
{
|
||||
throw new HttpResponseException(
|
||||
Request.CreateNotificationValidationErrorResponse("No Email server is configured"));
|
||||
@@ -430,16 +400,48 @@ namespace Umbraco.Web.Editors
|
||||
//ensure the invited date is set
|
||||
user.InvitedDate = DateTime.Now;
|
||||
|
||||
//Save the updated user
|
||||
//Save the updated user (which will process the user groups too)
|
||||
Services.UserService.Save(user);
|
||||
var display = Mapper.Map<UserDisplay>(user);
|
||||
|
||||
//send the email
|
||||
var inviteArgs = new UserInviteEventArgs(
|
||||
Request.TryGetHttpContext().Result.GetCurrentRequestIpAddress(),
|
||||
performingUser: Security.GetUserId().Result,
|
||||
userSave,
|
||||
user);
|
||||
|
||||
await SendUserInviteEmailAsync(display, Security.CurrentUser.Name, Security.CurrentUser.Email, user, userSave.Message);
|
||||
try
|
||||
{
|
||||
userMgr.RaiseSendingUserInvite(inviteArgs);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error<UsersController>(ex, "An error occured in a custom event handler while inviting the user");
|
||||
throw new HttpResponseException(
|
||||
Request.CreateNotificationValidationErrorResponse($"An error occured inviting the user (check logs for more info): {ex.Message}"));
|
||||
}
|
||||
|
||||
// If the event is handled then no need to send the email
|
||||
if (inviteArgs.InviteHandled)
|
||||
{
|
||||
// if no user result was created then map the minimum args manually for the UI
|
||||
if (!inviteArgs.ShowUserResult)
|
||||
{
|
||||
display = new UserDisplay
|
||||
{
|
||||
Name = userSave.Name,
|
||||
Email = userSave.Email,
|
||||
Username = userSave.Username
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//send the email
|
||||
await SendUserInviteEmailAsync(display, Security.CurrentUser.Name, Security.CurrentUser.Email, user, userSave.Message);
|
||||
}
|
||||
|
||||
display.AddSuccessNotification(Services.TextService.Localize("speechBubbles/resendInviteHeader"), Services.TextService.Localize("speechBubbles/resendInviteSuccess", new[] { user.Name }));
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Umbraco.Web
|
||||
{
|
||||
foreach (var error in externalLoginErrors.Errors)
|
||||
{
|
||||
sb.AppendFormat(@"errors.push(""{0}"");", error).AppendLine();
|
||||
sb.AppendFormat(@"errors.push(""{0}"");", error.ToSingleLine()).AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -634,6 +634,7 @@ namespace Umbraco.Web.Security
|
||||
}
|
||||
|
||||
internal void RaiseSendingUserInvite(UserInviteEventArgs args) => OnSendingUserInvite(args);
|
||||
internal bool HasSendingUserInviteEventHandler => SendingUserInvite != null;
|
||||
|
||||
// TODO: Not sure why these are not strongly typed events?? They should be in netcore!
|
||||
public static event EventHandler AccountLocked;
|
||||
|
||||
@@ -5,12 +5,16 @@ namespace Umbraco.Web.Security
|
||||
{
|
||||
public class UserInviteEventArgs : IdentityAuditEventArgs
|
||||
{
|
||||
public UserInviteEventArgs(string ipAddress, int performingUser, UserInvite invitedUser, string comment = null)
|
||||
public UserInviteEventArgs(string ipAddress, int performingUser, UserInvite invitedUser, IUser localUser, string comment = null)
|
||||
: base(AuditEvent.SendingUserInvite, ipAddress, comment, performingUser)
|
||||
{
|
||||
InvitedUser = invitedUser ?? throw new System.ArgumentNullException(nameof(invitedUser));
|
||||
User = localUser;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The model used to invite the user
|
||||
/// </summary>
|
||||
public UserInvite InvitedUser { get; }
|
||||
|
||||
/// <summary>
|
||||
@@ -19,12 +23,14 @@ namespace Umbraco.Web.Security
|
||||
public bool InviteHandled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the event handler has created a local user then this is the result which is used to return the details to the UI
|
||||
/// The local user that has been created that is pending the invite
|
||||
/// </summary>
|
||||
public IUser User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// if set to true will show the edit user button in the UI, else it will not be shown
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is optional to create a local user in this event. In many cases the custom invite flow will be for external logins and then local users will
|
||||
/// be created via the auto-linking process.
|
||||
/// </remarks>
|
||||
public IUser User { get; set; }
|
||||
public bool ShowUserResult { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user