public Task <ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser) { if (resolvedUser == null) { throw new AuthenticationException("Specified user does not exist."); } bool success = false; // As long as jellyfin supports password-less users, we need this little block here to accommodate if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password)) { return(Task.FromResult(new ProviderAuthenticationResult { Username = username })); } // Handle the case when the stored password is null, but the user tried to login with a password if (resolvedUser.Password != null) { byte[] passwordBytes = Encoding.UTF8.GetBytes(password); PasswordHash readyHash = PasswordHash.Parse(resolvedUser.Password); if (_cryptographyProvider.GetSupportedHashMethods().Contains(readyHash.Id) || _cryptographyProvider.DefaultHashMethod == readyHash.Id) { byte[] calculatedHash = _cryptographyProvider.ComputeHash( readyHash.Id, passwordBytes, readyHash.Salt.ToArray()); if (readyHash.Hash.SequenceEqual(calculatedHash)) { success = true; } } else { throw new AuthenticationException($"Requested crypto method not available in provider: {readyHash.Id}"); } } if (!success) { throw new AuthenticationException("Invalid username or password"); } return(Task.FromResult(new ProviderAuthenticationResult { Username = username })); }
// This is the version that we need to use for local users. Because reasons. public Task <ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser) { bool success = false; if (resolvedUser == null) { throw new ArgumentNullException(nameof(resolvedUser)); } // As long as jellyfin supports passwordless users, we need this little block here to accommodate if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password)) { return(Task.FromResult(new ProviderAuthenticationResult { Username = username })); } ConvertPasswordFormat(resolvedUser); byte[] passwordbytes = Encoding.UTF8.GetBytes(password); PasswordHash readyHash = new PasswordHash(resolvedUser.Password); if (_cryptographyProvider.GetSupportedHashMethods().Contains(readyHash.Id) || _cryptographyProvider.DefaultHashMethod == readyHash.Id) { byte[] calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes, readyHash.Salt); if (calculatedHash.SequenceEqual(readyHash.Hash)) { success = true; } } else { throw new AuthenticationException($"Requested crypto method not available in provider: {readyHash.Id}"); } if (!success) { throw new AuthenticationException("Invalid username or password"); } return(Task.FromResult(new ProviderAuthenticationResult { Username = username })); }
// This is the verson that we need to use for local users. Because reasons. public Task <ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser) { bool success = false; if (resolvedUser == null) { throw new Exception("Invalid username or password"); } // As long as jellyfin supports passwordless users, we need this little block here to accomodate if (IsPasswordEmpty(resolvedUser, password)) { return(Task.FromResult(new ProviderAuthenticationResult { Username = username })); } ConvertPasswordFormat(resolvedUser); byte[] passwordbytes = Encoding.UTF8.GetBytes(password); PasswordHash readyHash = new PasswordHash(resolvedUser.Password); byte[] calculatedHash; string calculatedHashString; if (_cryptographyProvider.GetSupportedHashMethods().Contains(readyHash.Id)) { if (string.IsNullOrEmpty(readyHash.Salt)) { calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes); calculatedHashString = BitConverter.ToString(calculatedHash).Replace("-", string.Empty); } else { calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes, readyHash.SaltBytes); calculatedHashString = BitConverter.ToString(calculatedHash).Replace("-", string.Empty); } if (calculatedHashString == readyHash.Hash) { success = true; // throw new Exception("Invalid username or password"); } } else { throw new Exception(string.Format($"Requested crypto method not available in provider: {readyHash.Id}")); } // var success = string.Equals(GetPasswordHash(resolvedUser), GetHashedString(resolvedUser, password), StringComparison.OrdinalIgnoreCase); if (!success) { throw new Exception("Invalid username or password"); } return(Task.FromResult(new ProviderAuthenticationResult { Username = username })); }