aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library/UserManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Library/UserManager.cs')
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs124
1 files changed, 67 insertions, 57 deletions
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 75c82ca71..1701ced42 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -79,6 +79,8 @@ namespace Emby.Server.Implementations.Library
private IAuthenticationProvider[] _authenticationProviders;
private DefaultAuthenticationProvider _defaultAuthenticationProvider;
+ private InvalidAuthProvider _invalidAuthProvider;
+
private IPasswordResetProvider[] _passwordResetProviders;
private DefaultPasswordResetProvider _defaultPasswordResetProvider;
@@ -141,6 +143,8 @@ namespace Emby.Server.Implementations.Library
_defaultAuthenticationProvider = _authenticationProviders.OfType<DefaultAuthenticationProvider>().First();
+ _invalidAuthProvider = _authenticationProviders.OfType<InvalidAuthProvider>().First();
+
_passwordResetProviders = passwordResetProviders.ToArray();
_defaultPasswordResetProvider = passwordResetProviders.OfType<DefaultPasswordResetProvider>().First();
@@ -218,9 +222,8 @@ namespace Emby.Server.Implementations.Library
public void Initialize()
{
- _users = LoadUsers();
-
- var users = Users.ToList();
+ var users = LoadUsers();
+ _users = users.ToArray();
// If there are no local users with admin rights, make them all admins
if (!users.Any(i => i.Policy.IsAdministrator))
@@ -277,27 +280,37 @@ 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)
+ if (authenticationProvider is IHasNewUserPolicy hasNewUserPolicy)
{
var policy = hasNewUserPolicy.GetNewUserPolicy();
UpdateUserPolicy(user, policy, true);
@@ -389,7 +402,9 @@ namespace Emby.Server.Implementations.Library
if (providers.Length == 0)
{
- providers = new IAuthenticationProvider[] { _defaultAuthenticationProvider };
+ // Assign the user to the InvalidAuthProvider since no configured auth provider was valid/found
+ _logger.LogWarning("User {UserName} was found with invalid/missing Authentication Provider {AuthenticationProviderId}. Assigning user to InvalidAuthProvider until this is corrected", user.Name, user.Policy.AuthenticationProviderId);
+ providers = new IAuthenticationProvider[] { _invalidAuthProvider };
}
return providers;
@@ -414,32 +429,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);
}
- return true;
+ if(authenticationResult.Username != username)
+ {
+ _logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
+ username = authenticationResult.Username;
+ }
+
+ 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;
@@ -452,17 +475,20 @@ namespace Emby.Server.Implementations.Library
if (password == null)
{
// legacy
- success = string.Equals(_defaultAuthenticationProvider.GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
+ success = string.Equals(GetAuthenticationProvider(user).GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
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;
}
}
@@ -475,16 +501,16 @@ namespace Emby.Server.Implementations.Library
if (password == null)
{
// legacy
- success = string.Equals(GetLocalPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
+ success = string.Equals(GetAuthenticationProvider(user).GetEasyPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
- success = string.Equals(GetLocalPasswordHash(user), _defaultAuthenticationProvider.GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
+ success = string.Equals(GetAuthenticationProvider(user).GetEasyPasswordHash(user), _defaultAuthenticationProvider.GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
}
}
}
- return new Tuple<IAuthenticationProvider, bool>(authenticationProvider, success);
+ return new Tuple<IAuthenticationProvider, string, bool>(authenticationProvider, username, success);
}
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
@@ -524,46 +550,40 @@ namespace Emby.Server.Implementations.Library
}
}
- private string GetLocalPasswordHash(User user)
- {
- return string.IsNullOrEmpty(user.EasyPassword)
- ? null
- : user.EasyPassword;
- }
-
/// <summary>
/// Loads the users from the repository
/// </summary>
/// <returns>IEnumerable{User}.</returns>
- private User[] LoadUsers()
+ private List<User> LoadUsers()
{
var users = UserRepository.RetrieveAllUsers();
// There always has to be at least one user.
- if (users.Count == 0)
+ if (users.Count != 0)
{
- var defaultName = Environment.UserName;
- if (string.IsNullOrWhiteSpace(defaultName))
- {
- defaultName = "MyJellyfinUser";
- }
- var name = MakeValidUsername(defaultName);
+ return users;
+ }
- var user = InstantiateNewUser(name);
+ var defaultName = Environment.UserName;
+ if (string.IsNullOrWhiteSpace(defaultName))
+ {
+ defaultName = "MyJellyfinUser";
+ }
- user.DateLastSaved = DateTime.UtcNow;
+ var name = MakeValidUsername(defaultName);
- UserRepository.CreateUser(user);
+ var user = InstantiateNewUser(name);
- users.Add(user);
+ user.DateLastSaved = DateTime.UtcNow;
- user.Policy.IsAdministrator = true;
- user.Policy.EnableContentDeletion = true;
- user.Policy.EnableRemoteControlOfOtherUsers = true;
- UpdateUserPolicy(user, user.Policy, false);
- }
+ UserRepository.CreateUser(user);
- return users.ToArray();
+ user.Policy.IsAdministrator = true;
+ user.Policy.EnableContentDeletion = true;
+ user.Policy.EnableRemoteControlOfOtherUsers = true;
+ UpdateUserPolicy(user, user.Policy, false);
+
+ return new List<User> { user };
}
public UserDto GetUserDto(User user, string remoteEndPoint = null)
@@ -574,7 +594,7 @@ namespace Emby.Server.Implementations.Library
}
bool hasConfiguredPassword = GetAuthenticationProvider(user).HasPassword(user).Result;
- bool hasConfiguredEasyPassword = string.IsNullOrEmpty(GetLocalPasswordHash(user));
+ bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(GetAuthenticationProvider(user).GetEasyPasswordHash(user));
bool hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
hasConfiguredEasyPassword :
@@ -862,17 +882,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentNullException(nameof(user));
}
- if (newPassword != null)
- {
- newPasswordHash = _defaultAuthenticationProvider.GetHashedString(user, newPassword);
- }
-
- if (string.IsNullOrWhiteSpace(newPasswordHash))
- {
- throw new ArgumentNullException(nameof(newPasswordHash));
- }
-
- user.EasyPassword = newPasswordHash;
+ GetAuthenticationProvider(user).ChangeEasyPassword(user, newPassword, newPasswordHash);
UpdateUser(user);