|
|
|
@ -277,24 +277,35 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
|
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
var success = false;
|
|
|
|
|
string updatedUsername = null;
|
|
|
|
|
IAuthenticationProvider authenticationProvider = null;
|
|
|
|
|
|
|
|
|
|
if (user != null)
|
|
|
|
|
{
|
|
|
|
|
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, user, remoteEndPoint).ConfigureAwait(false);
|
|
|
|
|
authenticationProvider = authResult.Item1;
|
|
|
|
|
success = authResult.Item2;
|
|
|
|
|
updatedUsername = authResult.Item2;
|
|
|
|
|
success = authResult.Item3;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// user is null
|
|
|
|
|
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, null, remoteEndPoint).ConfigureAwait(false);
|
|
|
|
|
authenticationProvider = authResult.Item1;
|
|
|
|
|
success = authResult.Item2;
|
|
|
|
|
updatedUsername = authResult.Item2;
|
|
|
|
|
success = authResult.Item3;
|
|
|
|
|
|
|
|
|
|
if (success && authenticationProvider != null && !(authenticationProvider is DefaultAuthenticationProvider))
|
|
|
|
|
{
|
|
|
|
|
user = await CreateUser(username).ConfigureAwait(false);
|
|
|
|
|
// We should trust the user that the authprovider says, not what was typed
|
|
|
|
|
if (updatedUsername != username)
|
|
|
|
|
{
|
|
|
|
|
username = updatedUsername;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search the database for the user again; the authprovider might have created it
|
|
|
|
|
user = Users
|
|
|
|
|
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
var hasNewUserPolicy = authenticationProvider as IHasNewUserPolicy;
|
|
|
|
|
if (hasNewUserPolicy != null)
|
|
|
|
@ -414,32 +425,40 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
|
return providers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<bool> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
|
|
|
|
|
private async Task<Tuple<string, bool>> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var requiresResolvedUser = provider as IRequiresResolvedUser;
|
|
|
|
|
ProviderAuthenticationResult authenticationResult = null;
|
|
|
|
|
if (requiresResolvedUser != null)
|
|
|
|
|
{
|
|
|
|
|
await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
|
|
|
|
|
authenticationResult = await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await provider.Authenticate(username, password).ConfigureAwait(false);
|
|
|
|
|
authenticationResult = await provider.Authenticate(username, password).ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(authenticationResult.Username != username)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
|
|
|
|
|
username = authenticationResult.Username;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
return new Tuple<string, bool>(username, true);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "Error authenticating with provider {provider}", provider.Name);
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
return new Tuple<string, bool>(username, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<Tuple<IAuthenticationProvider, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
|
|
|
|
|
private async Task<Tuple<IAuthenticationProvider, string, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
|
|
|
|
|
{
|
|
|
|
|
string updatedUsername = null;
|
|
|
|
|
bool success = false;
|
|
|
|
|
IAuthenticationProvider authenticationProvider = null;
|
|
|
|
|
|
|
|
|
@ -458,11 +477,14 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
|
{
|
|
|
|
|
foreach (var provider in GetAuthenticationProviders(user))
|
|
|
|
|
{
|
|
|
|
|
success = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
|
|
|
|
|
var providerAuthResult = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
|
|
|
|
|
updatedUsername = providerAuthResult.Item1;
|
|
|
|
|
success = providerAuthResult.Item2;
|
|
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
|
{
|
|
|
|
|
authenticationProvider = provider;
|
|
|
|
|
username = updatedUsername;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -484,7 +506,7 @@ namespace Emby.Server.Implementations.Library
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Tuple<IAuthenticationProvider, bool>(authenticationProvider, success);
|
|
|
|
|
return new Tuple<IAuthenticationProvider, string, bool>(authenticationProvider, username, success);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
|
|
|
|
|