Esempio n. 1
0
        public async Task TestConnectionCachingForStoreUserOperation()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ITeamsUserStore>().To <ImapStore>().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var factory     = kernel.Get <ImapConnectionFactory>();
            var factoryWrap = A.Fake <ImapConnectionFactory>(a => a.Wrapping(factory));

            kernel.Rebind <ImapConnectionFactory>().ToConstant(factoryWrap);

            var imapStore = kernel.Get <ITeamsUserStore>();
            var user      = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)"test.fakeuserid");

            user.RegisterAlternateDisplayName("Heinrich Ulbricht", DateTime.UtcNow);
            user.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow);
            var user2 = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)"test.fakeuserid");

            user2.RegisterAlternateDisplayName("Heinrich Ulbricht", DateTime.UtcNow);
            user2.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow);
            await Task.Run(() =>
            {
                imapStore.PersistUserAsync(fakeContext, user).Wait();
                imapStore.PersistUserAsync(fakeContext, user2).Wait();
            });

            A.CallTo(() => factoryWrap.GetImapConnectionAsync()).MustHaveHappenedOnceExactly();
        }
Esempio n. 2
0
        public async Task TestUpdateLock()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();

            var imapFac    = kernel.Get <ImapConnectionFactory>();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();

            remoteLock.LockTimeOut = TimeSpan.FromSeconds(5);

            using var connection = await imapFac.GetImapConnectionAsync();

            var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path);

            await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1);

            var lockResult = await remoteLock.AcquireLock(parentFolder, "resourcelock");

            Assert.IsTrue(lockResult.IsSuccess);
            Assert.IsNotNull(lockResult.ResultingLockCookie);
            var lockResult2 = await remoteLock.AcquireLock(parentFolder, "resourcelock", lockResult.ResultingLockCookie);

            Assert.IsTrue(lockResult2.IsSuccess);
            Assert.IsNotNull(lockResult2.ResultingLockCookie);
            Assert.AreEqual(lockResult.ResultingLockCookie, lockResult2.ResultingLockCookie);

            var unlockResult = await remoteLock.ReleaseLock(parentFolder, "resourcelock", lockResult.ResultingLockCookie.Value);

            Assert.IsTrue(unlockResult);
        }
Esempio n. 3
0
        public async Task TestConcurrentLockAcquisition()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();

            var imapFac    = kernel.Get <ImapConnectionFactory>();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();

            remoteLock.LockTimeOut = TimeSpan.FromSeconds(5);

            using var connection = await imapFac.GetImapConnectionAsync();

            var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path);

            await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1);

            connection.Disconnect(true);

            var tasks = new List <Task>();

            for (var i = 0; i < 10; i++)
            {
                tasks.Add(Task.Run(async() =>
                {
                    using var connection = await imapFac.GetImapConnectionAsync();
                    var parentFolder     = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path);
                    var lockResult       = await remoteLock.AcquireLock(parentFolder, "resourcelock");
                    connection.Disconnect(true);
                    while (!lockResult.IsSuccess)
                    {
                        await Task.Delay(lockResult.TryAgainIn);
                        using var connection2 = await imapFac.GetImapConnectionAsync();
                        var parentFolder2     = await connection2.GetFolderAsync(connection2.PersonalNamespaces[0].Path);
                        lockResult            = await remoteLock.AcquireLock(parentFolder2, "resourcelock");
                        connection2.Disconnect(true);
                    }
                    await Task.Delay(100);
                    using var connection3 = await imapFac.GetImapConnectionAsync();
                    var parentFolder3     = await connection3.GetFolderAsync(connection3.PersonalNamespaces[0].Path);
                    var unlockResult      = await remoteLock.ReleaseLock(parentFolder3, "resourcelock", lockResult.ResultingLockCookie.Value);
                    connection3.Disconnect(true);
                    Assert.IsTrue(unlockResult);
                }));
            }
            await Task.WhenAll(tasks);

            using var connection2 = await imapFac.GetImapConnectionAsync();

            var parentFolder2 = await connection2.GetFolderAsync(connection2.PersonalNamespaces[0].Path);

            var hasLock = await remoteLock.HasLockAsync(parentFolder2, "resourcelock");

            connection2.Disconnect(true);
            Assert.IsFalse(hasLock);
            Assert.AreEqual(0, remoteLock.TimeoutCount, "Unexpected number of timeouts");
        }
Esempio n. 4
0
        public async Task TestVisitMessages()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope();
            var conFac    = kernel.Get <ImapConnectionFactory>();
            var logger    = kernel.Get <ILogger>();
            var imapStore = kernel.Get <ITeamsChatStore>();


            var imapClient = await conFac.GetImapConnectionAsync();

            var rootFolder = await imapClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path);

            var mainUserFolder = await rootFolder.CreateAsync(fakeContext.MainUserId.Id.MakeSafeFolderName(rootFolder.DirectorySeparator), false);

            var tenantFolder = await mainUserFolder.CreateAsync("Fake Tenant", false);

            var chatsFolder = await tenantFolder.CreateAsync(Constants.TenantChatsFolderName, false);

            var chatFolder = await chatsFolder.CreateAsync("chat title or someting", false);

            await chatFolder.OpenAsync(MailKit.FolderAccess.ReadWrite);

            var message = new MimeMessage();

            message.From.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail));
            message.To.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail));
            message.Subject = "Delete me User {{00000000-0000-beef-0000-000000000000}}";

            var kvStore = new EmailBackedKeyValueStore(logger, message);

            kvStore.Set("originalMessage", new Message()
            {
                version = "123", content = "message content"
            });

            var id = await chatFolder.AppendAsync(message);

            await imapStore.VisitMissingUserDisplayNames(fakeContext, async message =>
            {
                message.MessageSubject = "Delete me - Changed subject";
                message.TextContent    = "new text content";
                message.HtmlContent    = "new html content";
                return(await Task.FromResult((true, new List <string>())));
            });

            var newId          = (await chatFolder.SearchAsync(SearchQuery.All)).First();
            var changedMessage = await chatFolder.GetMessageAsync(newId);

            Assert.AreEqual("Delete me - Changed subject", changedMessage.Subject);

            await chatFolder.SetFlagsAsync(newId, MailKit.MessageFlags.Deleted, true);

            await chatFolder.ExpungeAsync();
        }
Esempio n. 5
0
        public async Task TestHandlingOfConnectionErrors()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var conFac = kernel.Get <ImapConnectionFactory>();

            // note: for docker-imap-devel the connection limit per IP is 10, for Google it is 15 according to their documentation
            var connectionCount = 30;
            var tasks           = new List <Task>();
            var counter         = 0;
            var rand            = new Random();

            for (var i = 0; i < connectionCount; i++)
            {
                var task = Task.Run(async() =>
                {
                    await Task.Delay(rand.Next(500));
                    var imapClient = await conFac.GetImapConnectionAsync();
                    var folder     = await imapClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path);
                    await Task.Delay(rand.Next(1000, 3000));
                    await imapClient.DisconnectAsync(true);
                    lock (tasks)
                    {
                        counter++;
                    }
                });
                tasks.Add(task);
            }

            await Task.WhenAll(tasks);

            Assert.AreEqual(connectionCount, counter);
        }
Esempio n. 6
0
        public static void RemoveFolder(string folderName, Configuration config)
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var imapFac = kernel.Get <ImapConnectionFactory>();

            using var connection = imapFac.GetImapConnectionAsync().Result;
            var         parentFolder = connection.GetFolder(connection.PersonalNamespaces[0].Path);
            IMailFolder mailFolder;

            try
            {
                mailFolder = parentFolder.GetSubfolder(folderName);
            }
            catch
            {
                // most likely folder not found
                return;
            }
            RemoveFolder(mailFolder, config);
            connection.Disconnect(true);
        }
Esempio n. 7
0
        public static void RemoveFolder(IMailFolder folder, Configuration config)
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var imapFac = kernel.Get <ImapConnectionFactory>();

            using var connection = imapFac.GetImapConnectionAsync().Result;

            var subFolders = folder.GetSubfolders();

            foreach (var subFolder in subFolders)
            {
                RemoveFolder(subFolder, config);
            }

            folder.Open(FolderAccess.ReadWrite);
            var allMessages = folder.Search(SearchQuery.All);

            folder.SetFlags(allMessages, MessageFlags.Deleted, true);
            folder.Expunge();
            folder.Close();
            try
            {
                folder.Delete();
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while deleting folder: " + e.ToString());
            }
            connection.Disconnect(true);
        }
Esempio n. 8
0
        public async Task TestModifyingExistingMessage()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var conFac = kernel.Get <ImapConnectionFactory>();
            var logger = kernel.Get <ILogger>();

            var imapClient = await conFac.GetImapConnectionAsync();

            var folder = imapClient.Inbox;
            await folder.OpenAsync(MailKit.FolderAccess.ReadWrite);

            var message = new MimeMessage();

            message.From.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail));
            message.To.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail));
            message.Subject = "Delete me";

            var id = await folder.AppendAsync(message);

            var readMessage = await folder.GetMessageAsync(id.Value);

            var kvStore = new EmailBackedKeyValueStore(logger, readMessage);

            kvStore.SetTextContent("test text");
            kvStore.SetHtmlContent("<div>test html</div>");
            kvStore.SetJson("jsonValue", "{}");
            kvStore.Set("object", new { Data = "test data" });

            var newId = await folder.ReplaceAsync(id.Value, readMessage);

            Assert.IsTrue(newId.HasValue);

            await folder.SetFlagsAsync(newId.Value, MailKit.MessageFlags.Deleted, true);

            await folder.ExpungeAsync();
        }
Esempio n. 9
0
        public async Task TestMimeMessageGenerationForMessageThatOnceFailed()
        {
            var fakeUserRegistry = A.Fake <ITeamsUserRegistry>();

            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            kernel.Rebind <ITeamsUserRegistry>().ToConstant(fakeUserRegistry);
            var imapStore = kernel.Get <ImapStore>();

            var json             = "{\"id\":\"1111111111111\",\"sequenceId\":1111,\"clientmessageid\":\"1111111111111111111\",\"version\":\"1111111111111\",\"conversationid\":\"19:meeting_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@thread.v2\",\"conversationLink\":\"https://emea.ng.msg.teams.microsoft.com/v1/users/ME/conversations/19:meeting_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@thread.v2\",\"type\":\"Message\",\"messagetype\":\"Text\",\"contenttype\":\"text\",\"content\":\"aaa, aaaaaaaaaa aaaaaaaaaaa! \",\"amsreferences\":[],\"from\":\"https://emea.ng.msg.teams.microsoft.com/v1/users/ME/contacts/8:teamsvisitor:a111a1a111aa111a1aa1aa1a11aaaaa1\",\"imdisplayname\":\"aaa aaaaaaa (aaaa)\",\"composetime\":\"2000-01-01T01:01:01.111Z\",\"originalarrivaltime\":\"2000-01-01T01:01:01.111Z\",\"properties\":{}}";
            var message          = JsonConvert.DeserializeObject <Message>(json);
            var processedMessage = kernel.Get <ProcessedMessage>();
            await processedMessage.InitFromMessageAsync(fakeContext, message.conversationid, message);

            // about "PrivateObject" see here: https://github.com/Microsoft/testfx/issues/366#issuecomment-580147403
            var imapStorePrivate = new PrivateObject(imapStore);
            var result           = (Task <MimeMessage>)imapStorePrivate.Invoke("CreateMimeMessageFromChatMessageAsync", processedMessage, null);
            var realResult       = result.Result;
        }
Esempio n. 10
0
        public async Task TestResolveParticipantPlaceholders()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <ITeamsUserStore>().ToConstant(A.Fake <ITeamsUserStore>()).InSingletonScope();
            kernel.Rebind <ITeamsUserRegistry>().To <TeamsUserRegistry>().InSingletonScope();
            var userRegistry = kernel.Get <ITeamsUserRegistry>();
            var logger       = kernel.Get <ILogger>();

            var fakeContext = new TeamsDataContext((TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant()
            {
                tenantId = "Tenant ID", userId = "8:orgid:00000000-0000-beef-0000-000000000000", tenantName = "Fake User"
            }, DateTime.UtcNow));
            await userRegistry.RegisterDisplayNameForUserIdAsync(fakeContext, (TeamsParticipant)"12300000-0000-beef-0000-000000000000", "Test Name", DateTime.UtcNow);

            var message = A.Fake <IMutableChatMessage>();

            message.MessageSubject = "User {{12300000-0000-beef-0000-000000000000}} added: User {{12300000-0000-beef-0000-000000000000}}, Heinrich Ulbricht";
            await TeamsChatRetriever.ResolveParticipantPlaceholders(logger, userRegistry, fakeContext, message);

            Assert.AreEqual("Test Name added: Test Name, Heinrich Ulbricht", message.MessageSubject);
        }
Esempio n. 11
0
        public async Task TestModifyingExistingMessage2()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var conFac = kernel.Get <ImapConnectionFactory>();
            var logger = kernel.Get <ILogger>();

            var imapClient = await conFac.GetImapConnectionAsync();

            var folder = imapClient.Inbox;
            await folder.OpenAsync(MailKit.FolderAccess.ReadWrite);

            var message = new MimeMessage();

            message.From.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail));
            message.To.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail));
            message.Subject = "Delete me";

            var id = await folder.AppendAsync(message);

            var readMessage = await folder.GetMessageAsync(id.Value);

            var wrap = new MimeMessageWrapper(logger, readMessage);

            wrap.TextContent    = "test text";
            wrap.HtmlContent    = "HTML content";
            wrap.MessageSubject = "Delete me - changed subject";

            var newId = await folder.ReplaceAsync(id.Value, readMessage);

            Assert.IsTrue(newId.HasValue);

            await folder.SetFlagsAsync(newId.Value, MailKit.MessageFlags.Deleted, true);

            await folder.ExpungeAsync();
        }
Esempio n. 12
0
        public async Task TestWriteAccess()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapBackedDatabase>().ToSelf().InSingletonScope();
            var logger     = kernel.Get <ILogger>();
            var fac        = kernel.Get <ImapConnectionFactory>();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();

            var db         = new ImapBackedDatabase(logger, fac, remoteLock);
            var folderName = "TestEmailBackedDatabase_TestWriteAccess";

            ImapTestUtils.RemoveFolder(folderName, config);
            ImapTestUtils.CreateFolder(folderName, config);

            var imapClient = await fac.GetImapConnectionAsync();

            try
            {
                int dbValue = rand.Next();
                var(kvStore, lockResult) = await db.LockStoreForWriting(folderName, "Fictional Store");

                kvStore.Set("dbkey", dbValue);
                var uid = await db.WriteAndUnlockStore(folderName, kvStore, lockResult);

                Assert.IsTrue(uid.HasValue && uid.Value.IsValid);

                var readOnlyStore = await db.GetStoreForReading(folderName, "Fictional Store");

                var prevValue = readOnlyStore.GetOrCreateEmpty <int>("dbkey");
                Assert.AreEqual(dbValue, prevValue.AsObject);
            }
            finally
            {
                await imapClient.DisconnectAsync(true);
            }
        }
Esempio n. 13
0
        public async Task TestWaitForLockTimeout()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();

            var imapFac    = kernel.Get <ImapConnectionFactory>();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();

            remoteLock.LockTimeOut = TimeSpan.FromSeconds(3);

            using var connection = await imapFac.GetImapConnectionAsync();

            var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path);

            await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1);


            var successfulLock = await remoteLock.AcquireLock(parentFolder, "resourcelock");

            var unsuccessfulLock = await remoteLock.AcquireLock(parentFolder, "resourcelock");

            Assert.IsFalse(unsuccessfulLock.IsSuccess);
            Assert.IsTrue(unsuccessfulLock.TryAgainIn.TotalSeconds >= 1 && unsuccessfulLock.TryAgainIn.TotalSeconds < 3);
            await Task.Delay(unsuccessfulLock.TryAgainIn);

            var secondSuccessfulLock = await remoteLock.AcquireLock(parentFolder, "resourcelock");

            Assert.IsTrue(secondSuccessfulLock.IsSuccess);
            // got new cookie?
            Assert.AreNotEqual(successfulLock.ResultingLockCookie, secondSuccessfulLock.ResultingLockCookie);

            var unlockResult = await remoteLock.ReleaseLock(parentFolder, "resourcelock", secondSuccessfulLock.ResultingLockCookie.Value);

            Assert.IsTrue(unlockResult);
        }
Esempio n. 14
0
        public async Task TestReleaseWithoutAcquisition()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();

            var imapFac    = kernel.Get <ImapConnectionFactory>();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();

            remoteLock.LockTimeOut = TimeSpan.FromSeconds(5);

            using var connection = await imapFac.GetImapConnectionAsync();

            var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path);

            await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1);

            var result = await remoteLock.ReleaseLock(parentFolder, "resourcelock", 1234);

            Assert.IsTrue(result);
        }
Esempio n. 15
0
        public async Task TestReadOnlyAccess()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapBackedDatabase>().ToSelf().InSingletonScope();
            var logger     = kernel.Get <ILogger>();
            var fac        = kernel.Get <ImapConnectionFactory>();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();

            var db         = new ImapBackedDatabase(logger, fac, remoteLock);
            var folderName = "TestEmailBackedDatabase_TestReadOnlyAccess";

            ImapTestUtils.RemoveFolder(folderName, config);
            ImapTestUtils.CreateFolder(folderName, config);

            var imapClient = await fac.GetImapConnectionAsync();

            try
            {
                var testheadervalue = rand.Next().ToString();
                var store           = await db.GetStoreForReading(folderName, "Fictional Store", message => { message.Subject = "[META] Fictional Store"; message.Headers.Add("testheaderkey", testheadervalue); });

                var folder = await imapClient.GetFolderAsync(folderName);

                folder.Open(FolderAccess.ReadOnly);
                var metaMessage = await folder.GetMessageAsync(store.MessageAndId.UniqueId);

                Assert.IsTrue(metaMessage.Headers.Contains("testheaderkey"));
                Assert.AreEqual(testheadervalue, metaMessage.Headers["testheaderkey"]);
            }
            finally
            {
                await imapClient.DisconnectAsync(true);
            }
        }
Esempio n. 16
0
        public async Task TestImapServerFolderDuplicateBehavior()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var imapFac = kernel.Get <ImapConnectionFactory>();

            var failures      = 0;
            var otherFailures = 0;
            var tasks         = new List <Task>();
            var taskCount     = 9;

            for (var i = 0; i < taskCount; i++)
            {
                tasks.Add(Task.Run(async() =>
                {
                    using var connection = await imapFac.GetImapConnectionAsync();
                    var parentFolder     = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path);
                    try
                    {
                        var mailFolder = parentFolder.Create(testFolderName, true);
                        var id         = mailFolder.UidNext;
                    }
                    catch (Exception e) {
                        if (e.Message.Contains("mailbox already exists", StringComparison.OrdinalIgnoreCase))
                        {
                            lock (this)
                            {
                                failures++;
                            }
                        }
                        else
                        {
                            otherFailures++;
                        }
                    }
                    connection.Disconnect(true);
                }));
            }
            await Task.WhenAll(tasks);

            Assert.AreEqual(0, otherFailures, "Unexpected number of OTHER failures");
            // Greenmail fails for duplicates, Dovecot succeeds
            Assert.IsTrue(taskCount == failures || failures == 0, "Unexpected number of failures");
        }
Esempio n. 17
0
        public async Task TestWriteAndReadUser()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ITeamsUserStore>().To <ImapStore>().InSingletonScope();
            var imapStore = kernel.Get <ITeamsUserStore>();

            var userName = new Random().Next().ToString();
            var user     = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)"test.fakeuserid");

            user.RegisterAlternateDisplayName(userName, DateTime.UtcNow);
            user.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow);
            await imapStore.PersistUserAsync(fakeContext, user);

            var users = await imapStore.RetrieveUsersAsync(fakeContext);

            Assert.AreEqual(1, users.Where(u => u.DisplayName == userName).Count(), "Cannot find previously saved user");
        }
Esempio n. 18
0
        public async Task TestStoreAndRetrieveChat()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope();
            var chatStore = kernel.Get <ITeamsChatStore>();

            var chatId = $"chatId-{rand.Next()}";
            var chat1  = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat()
            {
                id = chatId, version = 10, threadVersion = 1000
            });
            await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_1", chat1, null);

            var metadata = await chatStore.GetChatMetadataAsync(fakeContext, false, chatId);

            Assert.IsNotNull(metadata);
        }
Esempio n. 19
0
        public static void CreateFolder(string testFolderName, Configuration config)
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var imapFac = kernel.Get <ImapConnectionFactory>();

            using var connection = imapFac.GetImapConnectionAsync().Result;
            var parentFolder = connection.GetFolder(connection.PersonalNamespaces[0].Path);
            var mailFolder   = parentFolder.Create(testFolderName, true);

            mailFolder.Open(FolderAccess.ReadWrite);
            if (!mailFolder.PermanentFlags.HasFlag(MessageFlags.UserDefined))
            {
                //throw new TeasmCompanionException("Folder does not support user defined flags");
            }
            connection.Disconnect(true);
        }
Esempio n. 20
0
        public async Task TestBotAndChatReplacement()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <ITeamsUserStore>().ToConstant(A.Fake <ITeamsUserStore>()).InSingletonScope();
            kernel.Rebind <ITeamsUserRegistry>().To <TeamsUserRegistry>().InSingletonScope();
            var userRegistry = kernel.Get <ITeamsUserRegistry>();

            var fakeContext = new TeamsDataContext((TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant()
            {
                tenantId = "Tenant ID", userId = "8:orgid:00000000-0000-beef-0000-000000000000", tenantName = "Fake User"
            }, DateTime.UtcNow));

            await userRegistry.RecognizeUserIdAsync(fakeContext, (TeamsParticipant)"817c2506-de4a-4795-971e-371ea75a03ed");                                                        // polly

            await userRegistry.RecognizeUserIdAsync(fakeContext, (TeamsParticipant)"19:00000000-0000-beef-0000-000000000000_00000000-0000-beef-0000-000000000000@unq.gbl.spaces"); // a chat

            string s;

            s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "817c2506-de4a-4795-971e-371ea75a03ed, 19:00000000-0000-beef-0000-000000000000_00000000-0000-beef-0000-000000000000@unq.gbl.spaces");

            Assert.AreEqual("Polly, Microsoft Teams Chat", s);
        }
Esempio n. 21
0
        public async Task TestWriteAndReadManyUsers()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ITeamsUserStore>().To <ImapStore>().InSingletonScope();
            var imapStore = kernel.Get <ITeamsUserStore>();

            var sw = new Stopwatch();

            sw.Start();
            for (var i = 0; i < 10; i++)
            {
                var user = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)i.ToString());
                user.RegisterAlternateDisplayName("Massentest", DateTime.UtcNow);
                user.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow);
                await imapStore.PersistUserAsync(fakeContext, user);
            }
            var users = await imapStore.RetrieveUsersAsync(fakeContext);

            sw.Stop();
            Assert.IsTrue(sw.ElapsedMilliseconds < 10000, "Needing quite a lot of time to store users");
        }
Esempio n. 22
0
        public async Task TestMriReplacement()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <ITeamsUserStore>().ToConstant(A.Fake <ITeamsUserStore>()).InSingletonScope();
            kernel.Rebind <ITeamsUserRegistry>().To <TeamsUserRegistry>().InSingletonScope();
            var userRegistry = kernel.Get <ITeamsUserRegistry>();

            var fakeContext = new TeamsDataContext((TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant()
            {
                tenantId = "Tenant ID", userId = "8:orgid:00000000-0000-beef-0000-000000000000", tenantName = "Fake User"
            }, DateTime.UtcNow));

            var userId = (TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000";
            await userRegistry.RecognizeUserIdAsync(fakeContext, userId);

            await userRegistry.RegisterDisplayNameForUserIdAsync(fakeContext, userId, "User Name", DateTime.UtcNow);

            var user = await userRegistry.GetUserByIdAsync(fakeContext, userId, false);

            Assert.AreEqual("User Name", user.DisplayName);

            string s;

            s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "8:orgid:00000000-0000-beef-0000-000000000000");

            Assert.AreEqual("User Name", s);
            s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "00000000-0000-beef-0000-000000000000");

            Assert.AreEqual("User Name", s);
            s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "00000000-0000-beef-0000-000000000000, 00000000-0000-beef-0000-000000000000");

            Assert.AreEqual("User Name, User Name", s);
            s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "8:00000000-0000-beef-0000-000000000000");

            Assert.AreEqual("User Name", s);
        }
Esempio n. 23
0
        public async Task TestStoreAndGetAllChatMetadata()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope();
            var chatStore = kernel.Get <ITeamsChatStore>();

            var chat1 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat()
            {
                id = "chat1", version = 10, threadVersion = 1000
            });
            await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_1", chat1, null);

            var chat2 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat()
            {
                id = "chat2", version = 20, threadVersion = 2000
            });
            await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_2", chat2, null);

            //await chatStore.GetAllChatMetadataRecursivelyAsync(fakeContext);

            //Assert.IsTrue(sw.ElapsedMilliseconds < 10000, "Needing quite a lot of time to store users");
        }
Esempio n. 24
0
        public async Task TestModSeqBasedLockingInGeneral()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var imapFac = kernel.Get <ImapConnectionFactory>();
            var logger  = kernel.Get <ILogger>();

            logger.Debug("=====> START");

            using var con1 = await imapFac.GetImapConnectionAsync();

            var parentFolder = await con1.GetFolderAsync(con1.PersonalNamespaces[0].Path);

            var mailFolder = parentFolder.GetSubfolder(testFolderName);

            mailFolder.Open(FolderAccess.ReadWrite);

            var id = mailFolder.Append(GetMessage("Lock", "0"));

            mailFolder.Fetch(new List <UniqueId>()
            {
                id.Value
            }, MessageSummaryItems.ModSeq);
            mailFolder.Append(GetMessage("Counter inside", "0"));
            con1.Disconnect(true);

            var taskCount = 9;
            var loopCount = 20;

            for (var loop = 0; loop < loopCount; loop++)
            {
                var tasks = new List <Task>();
                for (var i = 0; i < taskCount; i++)
                {
                    CreateTask createTask = (int index) => Task.Run(() =>
                    {
                        var taskIndex = index;
                        logger.Debug("{0:00} Starting task", taskIndex);
                        int cookie;
                        lock (rand)
                        {
                            cookie = rand.Next();
                        }

#pragma warning disable CS0618 // Type or member is obsolete
                        var cookiestring = $"{taskIndex}-{AppDomain.GetCurrentThreadId()}-{cookie}";
#pragma warning restore CS0618 // Type or member is obsolete
                        logger.Debug("{0:00} Cookiestring: {1}", taskIndex, cookiestring);
                        using var con2   = imapFac.GetImapConnectionAsync().Result;
                        var parentFolder = con2.GetFolder(con2.PersonalNamespaces[0].Path);
                        var mailFolder   = parentFolder.GetSubfolder(testFolderName);
                        mailFolder.UidValidityChanged += (a, b) => { logger.Warning("0:00 UI VALIDITY changed!", taskIndex); };
                        mailFolder.Open(FolderAccess.ReadWrite);
                        var idOfLockEmail = mailFolder.Search(SearchQuery.SubjectContains("Lock")).Single();
                        logger.Debug("{0:00} Lock email ID: {1}", taskIndex, idOfLockEmail);

                        try
                        {
                            IMessageSummary summary;
                            IList <UniqueId> failList;
                            var keywords = new HashSet <string>()
                            {
                                cookiestring, DateTime.UtcNow.ToFileTimeUtc().ToString()
                            };
                            ulong modSeqMax;
                            do
                            {
                                // might return multiple unrelated summaries...
                                var summaries = mailFolder.Fetch(new List <UniqueId>()
                                {
                                    idOfLockEmail
                                }, MessageSummaryItems.Flags | MessageSummaryItems.UniqueId | MessageSummaryItems.ModSeq);

                                if (summaries.Where(s => s.UniqueId == idOfLockEmail && s.Keywords?.Count > 0).Any())
                                {
                                    logger.Debug("{0:00} Got summary with keywords, need to wait", taskIndex);
                                    Task.Delay(rand.Next(100, 2000)).Wait();
                                    continue;
                                }
                                logger.Debug("{0:00} Got summary without keywords - trying to set them", taskIndex);

                                summary   = summaries.Where(s => s.UniqueId == idOfLockEmail).Single();
                                modSeqMax = summary.ModSeq.Value;
                                //summary = mailFolder.Fetch(indizes, MessageSummaryItems.ModSeq | MessageSummaryItems.UniqueId);
                                failList = mailFolder.SetFlags(new List <UniqueId>()
                                {
                                    idOfLockEmail
                                }, modSeqMax, MessageFlags.UserDefined, keywords, false);
                                if (failList.Count > 0)
                                {
                                    logger.Debug("{0:00} Could not set keywords with modSeq {1}, starting over", taskIndex, modSeqMax);
                                    Task.Delay(rand.Next(100, 2000)).Wait();
                                    continue;
                                }
                                else
                                {
                                    logger.Debug("{0:00} Successfully set keywords, modSeq was {1}", taskIndex, modSeqMax);
                                    // really?? check this...

                                    var lockMessageSummary = mailFolder
                                                             .Fetch(new List <UniqueId>()
                                    {
                                        idOfLockEmail
                                    }, MessageSummaryItems.Flags | MessageSummaryItems.UniqueId | MessageSummaryItems.ModSeq)
                                                             .Where(s => s.UniqueId == idOfLockEmail)
                                                             .SingleOrDefault();
                                    if (lockMessageSummary == null)
                                    {
                                        logger.Error("{0:00} Could not fetch lock message summary!", taskIndex);
                                    }
                                    logger.Debug("{0:00} Got lock messgage keywords: {1}", taskIndex, lockMessageSummary.Keywords);
                                    if (lockMessageSummary.Keywords.Count > 2)
                                    {
                                        cookie = rand.Next();
#pragma warning disable CS0618 // Type or member is obsolete
                                        cookiestring = $"{taskIndex}-{AppDomain.GetCurrentThreadId()}-{cookie}";
#pragma warning restore CS0618 // Type or member is obsolete
                                        keywords = new HashSet <string>()
                                        {
                                            cookiestring, DateTime.UtcNow.ToFileTimeUtc().ToString()
                                        };
                                        // with Dovecot it sometimes happened that two threads succeed in setting their keywords although only one should succeed (as both use the same modSeq number)
                                        logger.Warning("{0:00} Got wrong number of keywords, starting over with new keywords for thread: {1}", taskIndex, keywords);
                                        mailFolder.RemoveFlags(new List <UniqueId>()
                                        {
                                            idOfLockEmail
                                        }, MessageFlags.UserDefined, lockMessageSummary.Keywords, true);
                                        continue;
                                    }
                                    if (!lockMessageSummary.Keywords.Contains(cookiestring))
                                    {
                                        // with Dovecot it sometimes happened that sometimes the keywords cannot be set but failList nevertheless is empty
                                        logger.Warning("{0:00} Control keyword f-up: {1} (expected cookiestring {2}); starting over", lockMessageSummary.Keywords, cookiestring);
                                        continue;
                                    }
                                    Assert.AreEqual(2, lockMessageSummary.Keywords.Count);

                                    break;
                                }
                            } while (true);
                            logger.Debug("{0:00} Increasing count section", taskIndex);

                            summary = mailFolder
                                      .Fetch(new List <UniqueId>()
                            {
                                idOfLockEmail
                            }, MessageSummaryItems.ModSeq)
                                      .Where(s => s.UniqueId == idOfLockEmail)
                                      .Single();

                            var idOfCounterEmail = mailFolder.Search(SearchQuery.SubjectContains("Counter inside")).Single();
                            // increase count
                            var loadedMessage = mailFolder.GetMessage(idOfCounterEmail);
                            var count         = int.Parse(loadedMessage.TextBody);
                            logger.Debug("{0:00} Got old count: {1}", taskIndex, count);
                            var newBody = $"{count + 1}";
                            // note: the UniqueId does change
                            logger.Debug("{0:00} Updating count mail", taskIndex);
                            idOfCounterEmail = mailFolder.Replace(idOfCounterEmail, GetMessage("Counter inside", newBody), MessageFlags.None).Value;
                            Assert.IsNotNull(idOfCounterEmail);
                            Assert.IsTrue(idOfCounterEmail.IsValid);

                            //Assert.AreEqual(modSeqMax + 4, mailFolder.HighestModSeq);
                            logger.Debug("{0:00} Removing keywords", taskIndex);
                            mailFolder.RemoveFlags(new List <UniqueId>()
                            {
                                idOfLockEmail
                            }, MessageFlags.UserDefined, keywords, true);
                            //Assert.AreEqual(0, failList.Count, "Somebody removed keywords in parallel which must not happen");
                            logger.Debug("{0:00} DONE", taskIndex);
                        }
                        catch
                        {
                            Debugger.Break();
                        }
                        finally
                        {
                            con2.Disconnect(true);
                        }
                        logger.Debug("Exiting task {0}", taskIndex);
                    });
                    tasks.Add(createTask(i));
                }
                await Task.WhenAll(tasks);
            }

            using var con3 = await imapFac.GetImapConnectionAsync();

            var parentFolder2 = await con3.GetFolderAsync(con3.PersonalNamespaces[0].Path);

            var mailFolder2 = parentFolder2.GetSubfolder(testFolderName);

            mailFolder2.Open(FolderAccess.ReadWrite);
            var idOfCounterEmail = mailFolder2.Search(SearchQuery.SubjectContains("Counter inside")).Single();
            var msg = mailFolder2.GetMessage(idOfCounterEmail);

            con3.Disconnect(true);
            Assert.AreEqual(taskCount * loopCount, int.Parse(msg.TextBody));
        }
Esempio n. 25
0
        public async Task TestLockingWithEmailBackedRemoteLockImplementation()
        {
            using var kernel = new FakeItEasyMockingKernel();
            kernel.Rebind <ILogger>().ToConstant(Log.Logger);
            kernel.Rebind <Configuration>().ToConstant(config);
            kernel.Rebind <ImapStore>().ToSelf().InSingletonScope();
            kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope();
            var remoteLock = kernel.Get <ImapBackedRemoteLock>();
            var imapFac    = kernel.Get <ImapConnectionFactory>();
            var logger     = kernel.Get <ILogger>();

            logger.Debug("=====> START");

            using var con1 = await imapFac.GetImapConnectionAsync();

            var parentFolder = await con1.GetFolderAsync(con1.PersonalNamespaces[0].Path);

            var lockFolder = parentFolder.GetSubfolder(testFolderName);

            lockFolder.Open(FolderAccess.ReadWrite);
            lockFolder.Append(GetMessage("Counter inside", "0"));

            var lockFolderName = "locktest";
            // release any old lock
            await remoteLock.ReleaseLock(lockFolder, lockFolderName, -1);

            con1.Disconnect(true);
            var taskCount = 2;
            var loopCount = 20;

            for (var loop = 0; loop < loopCount; loop++)
            {
                var tasks = new List <Task>();
                for (var i = 0; i < taskCount; i++)
                {
                    CreateTask createTask = (int index) => Task.Run(async() =>
                    {
                        var taskIndex = index;
                        logger.Debug("{0:00} Starting task", taskIndex);

                        using var con2   = imapFac.GetImapConnectionAsync().Result;
                        var parentFolder = con2.GetFolder(con2.PersonalNamespaces[0].Path);
                        var lockFolder   = parentFolder.GetSubfolder(testFolderName);
                        var lockResult   = await remoteLock.AcquireLockRetry(lockFolder, lockFolderName, agressiveMode: true);
                        Assert.IsTrue(lockResult.IsSuccess);
                        Assert.IsNotNull(lockResult.ResultingLockCookie);


                        logger.Debug("{0:00} Increasing count section", taskIndex);
                        lockFolder.Open(FolderAccess.ReadWrite);
                        var idOfCounterEmail = lockFolder.Search(SearchQuery.SubjectContains("Counter inside")).Single();
                        // increase count
                        var loadedMessage = lockFolder.GetMessage(idOfCounterEmail);
                        var count         = int.Parse(loadedMessage.TextBody);
                        logger.Debug("{0:00} Got old count: {1}", taskIndex, count);
                        var newBody = $"{count + 1}";
                        // note: the UniqueId does change
                        logger.Debug("{0:00} Updating count mail", taskIndex);
                        idOfCounterEmail = lockFolder.Replace(idOfCounterEmail, GetMessage("Counter inside", newBody), MessageFlags.None).Value;
                        Assert.IsNotNull(idOfCounterEmail);
                        Assert.IsTrue(idOfCounterEmail.IsValid);

                        await remoteLock.ReleaseLock(lockFolder, lockFolderName, lockResult.ResultingLockCookie.Value);

                        con2.Disconnect(true);
                    });
                    tasks.Add(createTask(i));
                }
                await Task.WhenAll(tasks);
            }

            using var con3 = await imapFac.GetImapConnectionAsync();

            var parentFolder2 = await con3.GetFolderAsync(con3.PersonalNamespaces[0].Path);

            var mailFolder2 = parentFolder2.GetSubfolder(testFolderName);

            mailFolder2.Open(FolderAccess.ReadWrite);
            var idOfCounterEmail = mailFolder2.Search(SearchQuery.SubjectContains("Counter inside")).Single();
            var msg = mailFolder2.GetMessage(idOfCounterEmail);

            con3.Disconnect(true);
            Assert.AreEqual(taskCount * loopCount, int.Parse(msg.TextBody));
        }