Skip to content

Commit

Permalink
feat(Users): added default services to retrieve user to link to login…
Browse files Browse the repository at this point in the history
… data

feat(Users): changed account controller code to use new services
feat(Users): load all services in reversed enum to ret last registered services
feat(Users): updated view code

resolve OrchardCMS#16026
  • Loading branch information
PiemP committed May 20, 2024
1 parent 0f57494 commit aa734f1
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using OrchardCore.Modules;
using OrchardCore.Mvc.Core.Utilities;
using OrchardCore.Settings;
using OrchardCore.Users.Abstractions;
using OrchardCore.Users.Events;
using OrchardCore.Users.Handlers;
using OrchardCore.Users.Models;
Expand Down Expand Up @@ -47,6 +48,7 @@ public class AccountController : AccountBaseController
private readonly IClock _clock;
private readonly IDistributedCache _distributedCache;
private readonly IEnumerable<IExternalLoginEventHandler> _externalLoginHandlers;
private readonly IEnumerable<IExternalLoginUserToRelateFinder> _externalLoginUsrFinder;

protected readonly IHtmlLocalizer H;
protected readonly IStringLocalizer S;
Expand All @@ -67,7 +69,8 @@ public class AccountController : AccountBaseController
IShellFeaturesManager shellFeaturesManager,
IDisplayManager<LoginForm> loginFormDisplayManager,
IUpdateModelAccessor updateModelAccessor,
IEnumerable<IExternalLoginEventHandler> externalLoginHandlers)
IEnumerable<IExternalLoginEventHandler> externalLoginHandlers,
IEnumerable<IExternalLoginUserToRelateFinder> externalLoginUsrFinder)
{
_signInManager = signInManager;
_userManager = userManager;
Expand All @@ -83,6 +86,7 @@ public class AccountController : AccountBaseController
_loginFormDisplayManager = loginFormDisplayManager;
_updateModelAccessor = updateModelAccessor;
_externalLoginHandlers = externalLoginHandlers;
_externalLoginUsrFinder = externalLoginUsrFinder.Reverse();

H = htmlLocalizer;
S = stringLocalizer;
Expand Down Expand Up @@ -384,12 +388,9 @@ public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null,
}
else
{
var email = info.Principal.FindFirstValue(ClaimTypes.Email) ?? info.Principal.FindFirstValue("email");

if (!string.IsNullOrWhiteSpace(email))
{
iUser = await _userManager.FindByEmailAsync(email);
}
//really important the order of the services registration in the dependency injection context
var usrFinder = _externalLoginUsrFinder.Where(x => x.CanManageThis(info.LoginProvider)).FirstOrDefault();
iUser = await usrFinder?.FindUserToRelateAsync(info) ?? null;

ViewData["ReturnUrl"] = returnUrl;
ViewData["LoginProvider"] = info.LoginProvider;
Expand All @@ -409,7 +410,7 @@ public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null,

// Link external login to an existing user
ViewData["UserName"] = iUser.UserName;
ViewData["Email"] = email;
ViewData["LinkParameterValue"] = usrFinder?.GetValueThatLinkAccount(info);

return View(nameof(LinkExternalLogin));
}
Expand All @@ -423,6 +424,8 @@ public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null,
}
else
{
var email = info.Principal.FindFirstValue(ClaimTypes.Email) ?? info.Principal.FindFirstValue("email");

var externalLoginViewModel = new RegisterExternalLoginViewModel
{
NoPassword = registrationSettings.NoPasswordForExternalUsers,
Expand Down Expand Up @@ -630,9 +633,9 @@ public async Task<IActionResult> LinkExternalLogin(LinkExternalLoginViewModel mo

return NotFound();
}
var email = info.Principal.FindFirstValue(ClaimTypes.Email) ?? info.Principal.FindFirstValue("email");

var user = await _userManager.FindByEmailAsync(email);
//really important the order of the services registration in the dependency injection context
var usrFinder = _externalLoginUsrFinder.Where(x => x.CanManageThis(info.LoginProvider)).FirstOrDefault();
var user = await usrFinder?.FindUserToRelateAsync(info) ?? null;

if (user == null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using OrchardCore.Users.Abstractions;

namespace OrchardCore.Users.Services;

public class DefaultExternalLoginUserToRelateFinder : IExternalLoginUserToRelateFinder
{
private readonly UserManager<IUser> _userManager;

public DefaultExternalLoginUserToRelateFinder(UserManager<IUser> userManager)
{
_userManager = userManager;
}

public bool CanManageThis(string extLoginKind)
{
return true;
}

public async Task<IUser> FindUserToRelateAsync(ExternalLoginInfo info)
{
//the default behavior previously used in OrchardCore
var email = info.Principal.FindFirstValue(ClaimTypes.Email) ?? info.Principal.FindFirstValue("email");

IUser iUser = null;
if (!string.IsNullOrWhiteSpace(email))
{
iUser = await _userManager.FindByEmailAsync(email);
}

return iUser;
}

public string GetValueThatLinkAccount(ExternalLoginInfo info)
{
return info.Principal.FindFirstValue(ClaimTypes.Email) ?? info.Principal.FindFirstValue("email");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<form asp-controller="Account" asp-action="LinkExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal no-multisubmit">
<h4>@T["Link your account."]</h4>
<p class="text-info">
@T["You've successfully authenticated with <strong>{0}</strong>. You already have an account with this email address. Enter your local account password and click the Register button to link the accounts and finish logging in.", ViewData["LoginProvider"]]
@T["You've successfully authenticated with <strong>{0}</strong>. Seems already exist an account identificable by this information: <strong>{1}</strong>. Enter your local account password and click the Register button to link the accounts and finish logging in.", ViewData["LoginProvider"], ViewData["LinkParameterData"]]
</p>
<hr />
<div asp-validation-summary="ModelOnly"></div>
Expand All @@ -20,9 +20,9 @@
</div>

<div class="mb-3">
<label for="Email" class="col-md-3 form-label">@T["Email"]</label>
<label for="LinkParameterData" class="col-md-3 form-label">@T["Parameter that identify an existing account"]</label>
<div class="col-md-9">
<input id="Email" value="@ViewData["Email"]" class="form-control" disabled />
<input id="LinkParameterData" value="@ViewData["LinkParameterData"]" class="form-control" disabled />
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace OrchardCore.Users.Abstractions;

public interface IExternalLoginUserToRelateFinder
{
bool CanManageThis(string extLoginKind);

Task<IUser> FindUserToRelateAsync(ExternalLoginInfo info);

string GetValueThatLinkAccount(ExternalLoginInfo info);
}

0 comments on commit aa734f1

Please sign in to comment.