using Microsoft.AspNetCore.Identity; using Moq; using Moq.AutoMock; using NUnit.Framework; using Ombi.Api.Plex; using Ombi.Api.Plex.Models; using Ombi.Api.Plex.Models.Friends; using Ombi.Core.Authentication; using Ombi.Core.Engine; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Hubs; using Ombi.Schedule.Jobs.Plex; using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Test.Common; using Ombi.Tests; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Ombi.Schedule.Tests { [TestFixture] public class PlexUserImporterTests { private List _users = new List { new OmbiUser { Id = Guid.NewGuid().ToString("N"), UserName="abc", NormalizedUserName = "ABC", UserType = UserType.LocalUser}, new OmbiUser { Id = Guid.NewGuid().ToString("N"), UserName="sys", NormalizedUserName = "SYS", UserType = UserType.SystemUser}, new OmbiUser { Id = Guid.NewGuid().ToString("N"), UserName="plex", NormalizedUserName = "PLEX", UserType = UserType.PlexUser, ProviderUserId = "PLEX_ID", Email = "dupe"}, new OmbiUser { Id = Guid.NewGuid().ToString("N"), UserName="Admin", NormalizedUserName = "ADMIN", UserType = UserType.PlexUser, ProviderUserId = "ADMIN_ID", Email = "ADMIN@ADMIN.CO"}, }; private AutoMocker _mocker; private PlexUserImporter _subject; [SetUp] public void SetUp() { _mocker = new AutoMocker(); var um = MockHelper.MockUserManager(_users); var hub = SignalRHelper.MockHub(); _mocker.Use(um); _mocker.Use(hub); _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, Servers = new List { new PlexServers { Name = "Test", MachineIdentifier = "123", PlexAuthToken = "abc" } } }); _subject = _mocker.CreateInstance(); } [Test] public async Task Import_Exits_WhenNot_Enabled() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = false }); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); } [Test] public async Task Import_Exits_When_Plex_Not_Enabled() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = true }); _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = false }); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); } [Test] public async Task Import_Exits_When_Plex_No_AuthToken() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = true }); _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, Servers = new List { new PlexServers { Name = "Test", MachineIdentifier = "123", PlexAuthToken = null } } }); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); } [Test] public async Task Import_Only_Imports_Plex_Admin() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = false }); _mocker.Setup>(x => x.GetAccount(It.IsAny())).ReturnsAsync(new PlexAccount { user = new User { email = "email", authentication_token = "user_token", title = "user_title", username = "user_username", id = "user_id", } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "user_username" && x.Email == "email" && x.ProviderUserId == "user_id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "user_username"), It.Is(x => x == OmbiRoles.Admin))) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Once); } [Test] public async Task Import_Only_Imports_Plex_Admin_Already_Exists() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = false }); _mocker.Setup>(x => x.GetAccount(It.IsAny())).ReturnsAsync(new PlexAccount { user = new User { email = "email", authentication_token = "user_token", title = "user_title", username = "newUsername", id = "PLEX_ID", } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "user_username" && x.Email == "email" && x.ProviderUserId == "user_id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "user_username"), It.Is(x => x == OmbiRoles.Admin))) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); _mocker.Verify(x => x.UpdateAsync(It.Is(x => x.Email == "email" && x.UserName == "newUsername")), Times.Once); } [Test] public async Task Import_Only_Imports_Plex_Admin_Username_Clash() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = false }); _mocker.Setup>(x => x.GetAccount(It.IsAny())).ReturnsAsync(new PlexAccount { user = new User { email = "email", authentication_token = "user_token", title = "user_title", username = "abc", id = "nah", } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "user_username" && x.Email == "email" && x.ProviderUserId == "user_id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "user_username"), It.Is(x => x == OmbiRoles.Admin))) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); _mocker.Verify(x => x.UpdateAsync(It.IsAny()), Times.Never); } [Test] public async Task Import_Doesnt_Import_Banned_Users() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = true, BannedPlexUserIds = new List { "Banned" } }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { new UserFriends { Email = "email", Id = "Banned", Title = "title", Username = "username" } } }); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); } [Test] public async Task Import_Doesnt_Import_Managed_User() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = true }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { new UserFriends { Email = "email", Id = "id", Title = "title", HomeUser = true } } }); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); } [Test(Description = "You can have home users that are now unmanaged and can actually log into Plex")] public async Task Imports_Unmanaged_Home_User() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = true }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { new UserFriends { Email = "email", Id = "id", Title = "title", Username = "username", HomeUser = true } } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "username" && x.Email == "email" && x.ProviderUserId == "id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "plex"), OmbiRoles.RequestMovie)) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Once); } [Test] public async Task Import_Doesnt_Import_DuplicateEmail() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = true }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { new UserFriends { Email = "dupe", Id = "id", Title = "title", Username = "username" } } }); _mocker.Setup>(x => x.FindByEmailAsync("dupe")).ReturnsAsync(new OmbiUser()); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Never); } [Test] public async Task Import_Created_Plex_User() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = true, DefaultRoles = new List { OmbiRoles.RequestMovie } }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { new UserFriends { Email = "email", Id = "id", Username = "plex" } } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "plex" && x.Email == "email" && x.ProviderUserId == "id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "plex"), OmbiRoles.RequestMovie)) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.CreateAsync(It.IsAny()), Times.Once); } [Test] public async Task Import_Update_Plex_User() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = false, ImportPlexUsers = true, DefaultRoles = new List { OmbiRoles.RequestMovie } }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { new UserFriends { Email = "email", Id = "PLEX_ID", Username = "user" } } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "plex" && x.Email == "email" && x.ProviderUserId == "id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "plex"), OmbiRoles.RequestMovie)) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.UpdateAsync(It.Is(x => x.ProviderUserId == "PLEX_ID" && x.Email == "email" && x.UserName == "user")), Times.Once); } [Test] public async Task Import_Cleanup_Missing_Plex_Users() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = true, DefaultRoles = new List { OmbiRoles.RequestMovie }, CleanupPlexUsers = true, }); _mocker.Setup>(x => x.GetUsers(It.IsAny())).ReturnsAsync(new PlexUsers { User = new UserFriends[] { } }); _mocker.Setup>(x => x.GetAccount(It.IsAny())).ReturnsAsync(new PlexAccount { user = new User { email = "email", authentication_token = "user_token", title = "user_title", username = "user_username", id = "user_id", } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "user_username" && x.Email == "email" && x.ProviderUserId == "user_id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "user_username"), It.Is(x => x == OmbiRoles.Admin))) .ReturnsAsync(IdentityResult.Success); await _subject.Execute(null); _mocker.Verify(x => x.DeleteUser(It.Is(x => x.ProviderUserId == "PLEX_ID" && x.Email == "dupe" && x.UserName == "plex")), Times.Once); } [Test] public async Task Import_Cleanup_Missing_Plex_Admin_Dont_Delete() { _mocker.Setup, Task>(x => x.GetSettingsAsync()) .ReturnsAsync(new UserManagementSettings { ImportPlexAdmin = true, ImportPlexUsers = false, DefaultRoles = new List { OmbiRoles.RequestMovie }, CleanupPlexUsers = true, }); _mocker.Setup>(x => x.GetAccount(It.IsAny())).ReturnsAsync(new PlexAccount { user = new User { email = "ADMIN@ADMIN.CO", authentication_token = "Admin", title = "Admin", username = "Admin", id = "ADMIN_ID", } }); _mocker.Setup>(x => x.CreateAsync(It.Is(x => x.UserName == "diff_username" && x.Email == "diff_email" && x.ProviderUserId == "diff_user_id" && x.UserType == UserType.PlexUser))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.AddToRoleAsync(It.Is(x => x.UserName == "diff_username"), It.Is(x => x == OmbiRoles.Admin))) .ReturnsAsync(IdentityResult.Success); _mocker.Setup>(x => x.IsInRoleAsync(It.Is(x => x.UserName == "Admin"), OmbiRoles.Admin)).ReturnsAsync(true); await _subject.Execute(null); _mocker.Verify(x => x.DeleteUser(It.Is(x => x.ProviderUserId == "ADMIN_ID" && x.Email == "ADMIN@ADMIN.CO" && x.UserName == "Admin")), Times.Never); } } }