Пример #1
0
        public async Task <(string, bool)> IsHealthy(HttpContext context, LivenessExecutionContext livenessContext, CancellationToken cancellationToken = default)
        {
            try
            {
                _imapConnection = new ImapConnection(_options);

                if (await _imapConnection.ConnectAsync())
                {
                    if (_options.AccountOptions.login)
                    {
                        return(await ExecuteAuthenticatedUserActions());
                    }
                }
                else
                {
                    return($"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}", false);
                }

                return(BeatPulseKeys.BEATPULSE_HEALTHCHECK_DEFAULT_OK_MESSAGE, true);
            }
            catch (Exception ex)
            {
                var message = !livenessContext.IsDevelopment ? string.Format(BeatPulseKeys.BEATPULSE_HEALTHCHECK_DEFAULT_ERROR_MESSAGE, livenessContext.Name)
                   : $"Exception {ex.GetType().Name} with message ('{ex.Message}')";

                return(message, false);
            }
            finally
            {
                _imapConnection.Dispose();
            }
        }
        public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            try
            {
                _imapConnection = new ImapConnection(_options);

                if (await _imapConnection.ConnectAsync())
                {
                    if (_options.AccountOptions.Login)
                    {
                        return(await ExecuteAuthenticatedUserActions(context));
                    }
                }
                else
                {
                    return(new HealthCheckResult(context.Registration.FailureStatus, description: $"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}"));
                }

                return(HealthCheckResult.Healthy());
            }
            catch (Exception ex)
            {
                return(new HealthCheckResult(context.Registration.FailureStatus, exception: ex));
            }
            finally
            {
                _imapConnection.Dispose();
            }
        }
Пример #3
0
        /// <summary>
        /// Moves messages from the trash mailbox back to the inbox.
        /// </summary>
        /// <param name="messages">The messages to move.</param>
        internal async Task RestoreMessagesAsync(MailMessageContext[] messages)
        {
            try {
                if (messages.Length < 1)
                {
                    return;
                }

                var inbox = messages.First().Mailbox.Account.GetInbox();
                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            var mailbox = await session.SelectAsync(Name);

                            if (IsTrash)
                            {
                                await mailbox.MoveMailsAsync(messages.Select(x => x.Uid).ToArray(), inbox.Name);
                            }
                        }
                    }
                }

                await DeleteMessagesAsync(messages, _account.GetTrashMailbox().Name);

                App.Context.NotifyMessagesRemoved(messages);
            } catch (Exception ex) {
                Logger.Error(ex);
            }
        }
Пример #4
0
        internal async Task MarkAsSeenAsync(MailMessageContext[] messages)
        {
            Application.Current.AssertBackgroundThread();

            try {
                messages.ForEach(x => x.IsSeen = true);
                var uids = messages.Select(x => x.Uid).ToArray();

                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            var folder = await session.SelectAsync(Name);

                            await folder.MarkAsSeenAsync(uids);
                        }
                    }
                }

                await CountNotSeenAsync();
            } catch (Exception ex) {
                messages.ForEach(x => x.IsSeen = false);
                Logger.Error(ex);
            }
        }
Пример #5
0
        internal async Task IdleAsync()
        {
            try {
                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            if (!connection.CanIdle)
                            {
                                return;
                            }
                            var mailbox = await session.SelectAsync(Name);

                            try {
                                IsIdling = true;
                                mailbox.ChangeNotificationReceived += OnChangeNotificationReceived;
                                await mailbox.IdleAsync();
                            } finally {
                                mailbox.ChangeNotificationReceived -= OnChangeNotificationReceived;
                                IsIdling = false;
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                Logger.Error(ex);
            }
        }
Пример #6
0
        internal async Task DeleteMessagesAsync(MailMessageContext[] messages, string trashFolder)
        {
            var uids = messages.Select(x => x.Uid).ToArray();

            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        var mailbox = await session.SelectAsync(Name);

                        if (IsTrash)
                        {
                            await mailbox.DeleteMailsAsync(uids);
                        }
                        else
                        {
                            await mailbox.MoveMailsAsync(uids, trashFolder);
                        }
                    }
                }
            }

            using (var context = new DatabaseContext()) {
                await context.Database.Connection.OpenAsync();

                foreach (var message in messages)
                {
                    var id = message.Id;
                    using (var transaction = context.Database.BeginTransaction()) {
                        try {
                            var mime = await context.MimeMessages
                                       .FirstOrDefaultAsync(x => x.MessageId == id);

                            context.MimeMessages.Remove(mime);
                            await context.SaveChangesAsync();

                            var model = new MailMessageModel {
                                Id        = message.Id,
                                MailboxId = Id
                            };

                            context.MailMessages.Attach(model);
                            context.MailMessages.Remove(model);

                            await context.SaveChangesAsync();

                            transaction.Commit();

                            App.Context.NotifyMessageRemoved(message);
                        } catch (Exception) {
                            transaction.Rollback();
                        }
                    }
                }
            }
        }
Пример #7
0
 internal async Task <List <ImapMailboxInfo> > ListSubscribedMailboxesAsync(string pattern = "")
 {
     using (var connection = new ImapConnection {
         Security = ImapSecurity
     }) {
         connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
         using (var auth = await connection.ConnectAsync(ImapHost, ImapPort)) {
             using (var session = await auth.LoginAsync(ImapUsername, ImapPassword)) {
                 var wildcard = string.IsNullOrEmpty(pattern) ? "%" : pattern;
                 return(await session.LSubAsync("", ImapMailbox.EncodeName(wildcard)));
             }
         }
     }
 }
Пример #8
0
        private async Task DeleteAsync()
        {
            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        await session.DeleteMailboxAsync(Name);
                    }
                }
            }

            await DeleteLocalAsync();

            _account.NotifyMailboxRemoved(this);
        }
Пример #9
0
        private async Task UnsubscribeAsync()
        {
            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        await session.UnsubscribeAsync(Name);
                    }
                }
            }

            using (var database = new DatabaseContext()) {
                var mailbox = await database.Mailboxes.FindAsync(_mailbox.Id);

                mailbox.IsSubscribed = false;
                await database.SaveChangesAsync();
            }
        }
Пример #10
0
        public async Task CreateMailboxAsync(string mailbox)
        {
            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        var name = string.Format("{0}{1}{2}", Name, Delimiter, mailbox);
                        await session.CreateMailboxAsync(name);
                    }
                }
            }

            // Reset to allow new mailboxes to be discovered.
            _isSyncedInitially = false;
            await Task.Run(() => SyncMailboxesAsync());

            IsExpanded = true;
        }
Пример #11
0
        internal async Task RestoreMessagesAsync(ICollection <MailMessageContext> messages)
        {
            try {
                var inbox = GetInbox();
                var trash = GetTrashMailbox();
                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            var mailbox = await session.SelectAsync(trash.Name);

                            await mailbox.MoveMailsAsync(messages.Select(x => x.Uid).ToArray(), inbox.Name);
                        }
                    }
                }

                using (var database = new DatabaseContext()) {
                    foreach (var message in messages)
                    {
                        try {
                            var model = new MailMessageModel {
                                Id        = message.Id,
                                MailboxId = Id
                            };

                            database.MailMessages.Attach(model);
                            database.MailMessages.Remove(model);
                        } catch (Exception ex) {
                            Logger.Error(ex);
                            throw;
                        }
                    }
                    await database.SaveChangesAsync();
                }

                App.Context.NotifyMessagesRemoved(messages);
            } catch (Exception ex) {
                Logger.Error(ex);
            }
        }
Пример #12
0
        private async Task TestImapSettingsAsync()
        {
            Testing = new TestingContext {
                Message = Resources.TestingImapStatus
            };

            try {
                using (var connection = new ImapConnection {
                    Security = ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(ImapHost, ImapPort)) {
                        await auth.LoginAsync(ImapUsername, ImapPassword);
                    }
                }
            } catch (Exception ex) {
                Testing = new TestingContext {
                    IsFaulted = true,
                    Message   = ex.Message
                };
                Logger.Error(ex);
            }
        }
Пример #13
0
        public async Task <LivenessResult> IsHealthy(LivenessExecutionContext context, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.LogInformation($"{nameof(ImapLiveness)} is checking IMAP entries.");

                _imapConnection = new ImapConnection(_options);

                if (await _imapConnection.ConnectAsync())
                {
                    if (_options.AccountOptions.Login)
                    {
                        return(await ExecuteAuthenticatedUserActions());
                    }
                }
                else
                {
                    _logger?.LogWarning($"{nameof(ImapLiveness)} fail connect to server {_options.Host}- SSL Enabled : {_options.ConnectionType}.");

                    return(LivenessResult.UnHealthy($"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}"));
                }

                _logger?.LogInformation($"The {nameof(ImapLiveness)} check success.");

                return(LivenessResult.Healthy());
            }
            catch (Exception ex)
            {
                _logger?.LogWarning($"The {nameof(ImapLiveness)} check fail with the exception {ex.ToString()}.");

                return(LivenessResult.UnHealthy(ex));
            }
            finally
            {
                _imapConnection.Dispose();
            }
        }
Пример #14
0
        private async Task <byte[]> FetchMimeAsync()
        {
            var mailbox = await GetMailboxAsync();

            var account = await GetAccountAsync(mailbox);

            using (var connection = new ImapConnection {
                Security = account.ImapSecurity
            }) {
                connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
                using (var auth = await connection.ConnectAsync(account.ImapHost, account.ImapPort)) {
                    using (var session = await auth.LoginAsync(account.ImapUsername, account.ImapPassword)) {
                        var folder = await session.SelectAsync(mailbox.Name);

                        folder.ByteCountChanged += OnByteCountChanged;
                        var mime = await folder.FetchMessageBodyAsync(Uid);

                        folder.ByteCountChanged -= OnByteCountChanged;

                        return(mime);
                    }
                }
            }
        }
Пример #15
0
        internal async Task <ICollection <MailMessageContext> > SyncMessagesAsync()
        {
            ICollection <MailMessageContext> contexts;

            lock (_syncMessagesMutex) {
                if (IsSyncingMessages)
                {
                    return(new MailMessageContext[0]);
                }

                IsSyncingMessages = true;
            }

            try {
                var name   = _mailbox.Name;
                var maxUid = await GetMaxUidAsync();

                var account = await GetAccountAsync();

                var messages = new List <MailMessageModel>();

                using (var connection = new ImapConnection {
                    Security = account.ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(account.ImapHost, account.ImapPort)) {
                        using (var session = await auth.LoginAsync(account.ImapUsername, account.ImapPassword)) {
                            var mailbox = await session.SelectAsync(name);

                            messages.AddRange(await SyncChallengesAsync(mailbox, maxUid));
                            messages.AddRange(await SyncNonChallengesAsync(mailbox, maxUid));
                        }
                    }
                }

                if (messages.Count == 0)
                {
                    FetchedEnvelopeCount = 0;

                    lock (_syncMessagesMutex) {
                        IsSyncingMessages = false;
                    }

                    return(new MailMessageContext[0]);
                }

                await SaveContactsAsync(messages);
                await SaveMessagesAsync(messages);

                contexts = messages.Where(x => x.Type == MailType.Message)
                           .Select(x => new MailMessageContext(this, x)).ToArray();

                FetchedEnvelopeCount = 0;

                await Application.Current.Dispatcher
                .InvokeAsync(() => App.Context.NotifyMessagesAdded(contexts));

                await CountNotSeenAsync();
            } finally {
                lock (_syncMessagesMutex) {
                    IsSyncingMessages = false;
                }
            }

            return(contexts);
        }