160 lines
6.1 KiB
C#
160 lines
6.1 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Umbraco.Cms.Core.Cache;
|
|
using Umbraco.Cms.Core.Logging;
|
|
using Umbraco.Cms.Core.Models;
|
|
using Umbraco.Cms.Core.Routing;
|
|
using Umbraco.Cms.Core.Security;
|
|
using Umbraco.Cms.Core.Services;
|
|
using Umbraco.Cms.Core.Web;
|
|
using Umbraco.Cms.Infrastructure.Persistence;
|
|
using Umbraco.Cms.Web.Common.Filters;
|
|
using Umbraco.Cms.Web.Common.Security;
|
|
using Umbraco.Cms.Web.Website.Models;
|
|
using Umbraco.Extensions;
|
|
|
|
namespace Umbraco.Cms.Web.Website.Controllers
|
|
{
|
|
public class UmbRegisterController : SurfaceController
|
|
{
|
|
private readonly IMemberManager _memberManager;
|
|
private readonly IMemberService _memberService;
|
|
private readonly IMemberSignInManager _memberSignInManager;
|
|
|
|
public UmbRegisterController(
|
|
IMemberManager memberManager,
|
|
IMemberService memberService,
|
|
IUmbracoContextAccessor umbracoContextAccessor,
|
|
IUmbracoDatabaseFactory databaseFactory,
|
|
ServiceContext services,
|
|
AppCaches appCaches,
|
|
IProfilingLogger profilingLogger,
|
|
IPublishedUrlProvider publishedUrlProvider,
|
|
IMemberSignInManager memberSignInManager)
|
|
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
|
|
{
|
|
_memberManager = memberManager;
|
|
_memberService = memberService;
|
|
_memberSignInManager = memberSignInManager;
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
[ValidateUmbracoFormRouteString]
|
|
public async Task<IActionResult> HandleRegisterMember([Bind(Prefix = "registerModel")]RegisterModel model)
|
|
{
|
|
if (ModelState.IsValid == false)
|
|
{
|
|
return CurrentUmbracoPage();
|
|
}
|
|
|
|
MergeRouteValuesToModel(model);
|
|
|
|
// U4-10762 Server error with "Register Member" snippet (Cannot save member with empty name)
|
|
// If name field is empty, add the email address instead.
|
|
if (string.IsNullOrEmpty(model.Name) && string.IsNullOrEmpty(model.Email) == false)
|
|
{
|
|
model.Name = model.Email;
|
|
}
|
|
|
|
IdentityResult result = await RegisterMemberAsync(model, true);
|
|
if (result.Succeeded)
|
|
{
|
|
TempData["FormSuccess"] = true;
|
|
|
|
// If there is a specified path to redirect to then use it.
|
|
if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
|
|
{
|
|
return Redirect(model.RedirectUrl);
|
|
}
|
|
|
|
// Redirect to current page by default.
|
|
return RedirectToCurrentUmbracoPage();
|
|
}
|
|
else
|
|
{
|
|
AddErrors(result);
|
|
return CurrentUmbracoPage();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// We pass in values via encrypted route values so they cannot be tampered with and merge them into the model for use
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
private void MergeRouteValuesToModel(RegisterModel model)
|
|
{
|
|
if (RouteData.Values.TryGetValue(nameof(RegisterModel.RedirectUrl), out var redirectUrl) && redirectUrl != null)
|
|
{
|
|
model.RedirectUrl = redirectUrl.ToString();
|
|
}
|
|
|
|
if (RouteData.Values.TryGetValue(nameof(RegisterModel.MemberTypeAlias), out var memberTypeAlias) && memberTypeAlias != null)
|
|
{
|
|
model.MemberTypeAlias = memberTypeAlias.ToString();
|
|
}
|
|
|
|
if (RouteData.Values.TryGetValue(nameof(RegisterModel.UsernameIsEmail), out var usernameIsEmail) && usernameIsEmail != null)
|
|
{
|
|
model.UsernameIsEmail = usernameIsEmail.ToString() == "True";
|
|
}
|
|
}
|
|
|
|
private void AddErrors(IdentityResult result)
|
|
{
|
|
foreach (var error in result.Errors)
|
|
{
|
|
ModelState.AddModelError("registerModel", error.Description);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers a new member.
|
|
/// </summary>
|
|
/// <param name="model">Register member model.</param>
|
|
/// <param name="logMemberIn">Flag for whether to log the member in upon successful registration.</param>
|
|
/// <returns>Result of registration operation.</returns>
|
|
private async Task<IdentityResult> RegisterMemberAsync(RegisterModel model, bool logMemberIn = true)
|
|
{
|
|
model.Username = (model.UsernameIsEmail || model.Username == null) ? model.Email : model.Username;
|
|
|
|
var identityUser = MemberIdentityUser.CreateNew(model.Username, model.Email, model.MemberTypeAlias, model.Name);
|
|
IdentityResult identityResult = await _memberManager.CreateAsync(
|
|
identityUser,
|
|
model.Password);
|
|
|
|
if (identityResult.Succeeded)
|
|
{
|
|
// Update the custom properties
|
|
// TODO: See TODO in MembersIdentityUser, Should we support custom member properties for persistence/retrieval?
|
|
IMember member = _memberService.GetByKey(identityUser.Key);
|
|
if (member == null)
|
|
{
|
|
// should never happen
|
|
throw new InvalidOperationException($"Could not find a member with key: {member.Key}.");
|
|
}
|
|
if (model.MemberProperties != null)
|
|
{
|
|
foreach (MemberPropertyModel property in model.MemberProperties.Where(p => p.Value != null)
|
|
.Where(property => member.Properties.Contains(property.Alias)))
|
|
{
|
|
member.Properties[property.Alias].SetValue(property.Value);
|
|
}
|
|
}
|
|
_memberService.Save(member);
|
|
|
|
if (logMemberIn)
|
|
{
|
|
await _memberSignInManager.SignInAsync(identityUser, false);
|
|
}
|
|
}
|
|
|
|
return identityResult;
|
|
|
|
}
|
|
}
|
|
}
|