public string StoreMailEml(int tenant, string user, string streamId, MimeMessage message, ILogger log)
        {
            if (message == null)
            {
                return(string.Empty);
            }

            // Using id_user as domain in S3 Storage - allows not to add quota to tenant.
            var savePath = MailStoragePathCombiner.GetEmlKey(user, streamId);
            var storage  = MailDataStore.GetDataStore(tenant);

            try
            {
                using (var stream = new MemoryStream())
                {
                    message.WriteTo(stream);

                    var res = storage.Save(savePath, stream, MailStoragePathCombiner.EML_FILE_NAME).ToString();

                    log.Debug("StoreMailEml() tenant='{0}', user_id='{1}', save_eml_path='{2}' Result: {3}", tenant, user, savePath, res);

                    return(res);
                }
            }
            catch (Exception ex)
            {
                log.Error("StoreMailEml Exception: {0}", ex.ToString());
            }

            return(string.Empty);
        }
Esempio n. 2
0
        public bool RemoveLongDeadTenantGarbageMailData(int tenant)
        {
            if (!IsPortalClosed(tenant))
            {
                return(false);
            }

            _log.Info(
                "Portal is long dead. All mail's data for this tenant = {0} will be removed!",
                tenant);

            try
            {
                var dataStorage = MailDataStore.GetDataStore(tenant);

                if (dataStorage.IsDirectory(string.Empty, string.Empty))
                {
                    _log.Debug("Trying remove all long dead tenant mail's files from storage");
                    dataStorage.DeleteDirectory(string.Empty, string.Empty);
                }
            }
            catch (Exception ex)
            {
                _log.Error("Can't remove all stored mail data for tenant {0}\r\nException: {1}", tenant, ex.ToString());
                return(false);
            }

            _garbageManager.ClearTenantMailData(tenant);

            return(true);
        }
        public string StoreMailEml(int tenant, string user, string streamId, Message message)
        {
            // Using id_user as domain in S3 Storage - allows not to add quota to tenant.
            var savePath = MailStoragePathCombiner.GetEmlKey(user, streamId);
            var storage  = MailDataStore.GetDataStore(tenant);

            try
            {
                using (var reader = new MemoryStream(message.OriginalData))
                {
                    var res = storage
                              .UploadWithoutQuota(string.Empty, savePath, reader, "message/rfc822", string.Empty)
                              .ToString();

                    _log.Debug("StoreMailEml() tenant='{0}', user_id='{1}', save_eml_path='{2}' Result: {3}",
                               tenant, user, savePath, res);

                    return(res);
                }
            }
            catch (Exception)
            {
                storage.Delete(string.Empty, savePath);
                throw;
            }
        }
        public string StoreMailBody(int id_tenant, string id_user, MailMessageItem mail)
        {
            if (string.IsNullOrEmpty(mail.HtmlBody))
            {
                return(string.Empty);
            }

            // Using id_user as domain in S3 Storage - allows not to add quota to tenant.
            var save_path = MailStoragePathCombiner.GetBodyKey(id_user, mail.StreamId);
            var storage   = MailDataStore.GetDataStore(id_tenant);

            try
            {
                var safe_body = ReplaceEmbeddedImages(mail);

                using (var reader = new MemoryStream(Encoding.UTF8.GetBytes(safe_body)))
                {
                    var res = storage
                              .UploadWithoutQuota(string.Empty, save_path, reader, "text/html", string.Empty)
                              .ToString();

                    _log.Debug("StoreMailBody() tenant='{0}', user_id='{1}', save_body_path='{2}' Result: {3}",
                               id_tenant, id_user, save_path, res);

                    return(res);
                }
            }
            catch (Exception)
            {
                storage.Delete(string.Empty, save_path);
                _log.Debug(String.Format("StoreMailBody() Problems with message saving in messageId={0}. Body was deleted.", mail.MimeMessageId));
                throw;
            }
        }
        public string StoreMailBody(int tenant, string user, MailMessage messageItem)
        {
            if (string.IsNullOrEmpty(messageItem.HtmlBody))
            {
                return(string.Empty);
            }

            // Using id_user as domain in S3 Storage - allows not to add quota to tenant.
            var savePath = MailStoragePathCombiner.GetBodyKey(user, messageItem.StreamId);
            var storage  = MailDataStore.GetDataStore(tenant);

            try
            {
                using (var reader = new MemoryStream(Encoding.UTF8.GetBytes(messageItem.HtmlBody)))
                {
                    var res = storage
                              .UploadWithoutQuota(string.Empty, savePath, reader, "text/html", string.Empty)
                              .ToString();

                    _log.Debug("StoreMailBody() tenant='{0}', user_id='{1}', save_body_path='{2}' Result: {3}",
                               tenant, user, savePath, res);

                    return(res);
                }
            }
            catch (Exception ex)
            {
                _log.Debug(
                    "StoreMailBody() Problems with message saving in messageId={0}. \r\n Exception: \r\n {0}\r\n",
                    messageItem.MimeMessageId, ex.ToString());

                storage.Delete(string.Empty, savePath);
                throw;
            }
        }
Esempio n. 6
0
        public void StoreAttachmentCopy(int tenant, string user, MailAttachmentData attachment, string streamId)
        {
            try
            {
                if (attachment.streamId.Equals(streamId) && !attachment.isTemp)
                {
                    return;
                }

                string s3Key;

                var dataClient = MailDataStore.GetDataStore(tenant);

                if (attachment.needSaveToTemp || attachment.isTemp)
                {
                    s3Key = MailStoragePathCombiner.GetTempStoredFilePath(attachment);
                }
                else
                {
                    s3Key = MailStoragePathCombiner.GerStoredFilePath(attachment);
                }

                if (!dataClient.IsFile(s3Key))
                {
                    return;
                }

                attachment.fileNumber =
                    !string.IsNullOrEmpty(attachment.contentId) //Upload hack: embedded attachment have to be saved in 0 folder
                        ? 0
                        : attachment.fileNumber;

                var newS3Key = MailStoragePathCombiner.GetFileKey(user, streamId, attachment.fileNumber,
                                                                  attachment.storedName);

                var copyS3Url = dataClient.Copy(s3Key, string.Empty, newS3Key);

                attachment.storedFileUrl = MailStoragePathCombiner.GetStoredUrl(copyS3Url);

                attachment.streamId = streamId;

                attachment.tempStoredUrl = null;

                Log.DebugFormat("StoreAttachmentCopy() tenant='{0}', user_id='{1}', stream_id='{2}', new_s3_key='{3}', copy_s3_url='{4}', storedFileUrl='{5}',  filename='{6}'",
                                tenant, user, streamId, newS3Key, copyS3Url, attachment.storedFileUrl, attachment.fileName);
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("CopyAttachment(). filename='{0}', ctype='{1}' Exception:\r\n{2}\r\n",
                                attachment.fileName,
                                attachment.contentType,
                                ex.ToString());

                throw;
            }
        }
Esempio n. 7
0
        public void StoreAttachments(MailBoxData mailBoxData, List <MailAttachmentData> attachments, string streamId)
        {
            if (!attachments.Any() || string.IsNullOrEmpty(streamId))
            {
                return;
            }

            try
            {
                var quotaAddSize = attachments.Sum(a => a.data != null ? a.data.LongLength : a.dataStream.Length);

                var storageManager = new StorageManager(mailBoxData.TenantId, mailBoxData.UserId);

                foreach (var attachment in attachments)
                {
                    var isAttachmentNameHasBadName = string.IsNullOrEmpty(attachment.fileName) ||
                                                     attachment.fileName.IndexOfAny(Path.GetInvalidPathChars()) != -1 ||
                                                     attachment.fileName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1;
                    if (isAttachmentNameHasBadName)
                    {
                        attachment.fileName = string.Format("attacment{0}{1}", attachment.fileNumber,
                                                            MimeMapping.GetExtention(attachment.contentType));
                    }

                    attachment.streamId = streamId;
                    attachment.tenant   = mailBoxData.TenantId;
                    attachment.user     = mailBoxData.UserId;

                    storageManager.StoreAttachmentWithoutQuota(attachment);
                }

                var engine = new EngineFactory(mailBoxData.TenantId);
                engine.QuotaEngine.QuotaUsedAdd(quotaAddSize);
            }
            catch
            {
                var storedAttachmentsKeys = attachments
                                            .Where(a => !string.IsNullOrEmpty(a.storedFileUrl))
                                            .Select(MailStoragePathCombiner.GerStoredFilePath)
                                            .ToList();

                if (storedAttachmentsKeys.Any())
                {
                    var storage = MailDataStore.GetDataStore(mailBoxData.TenantId);

                    storedAttachmentsKeys.ForEach(key => storage.Delete(string.Empty, key));
                }

                Log.InfoFormat("[Failed] StoreAttachments(mailboxId={0}). All message attachments were deleted.", mailBoxData.MailBoxId);

                throw;
            }
        }
Esempio n. 8
0
        public bool RemoveGarbageMailboxData(MailBox mailbox)
        {
            if (!mailbox.IsRemoved)
            {
                return(false);
            }

            _log.Info(
                "Mailbox is removed. All mail's data for this mailboxId = {0} will be removed!",
                mailbox.MailBoxId);

            try
            {
                var dataStorage = MailDataStore.GetDataStore(mailbox.TenantId);

                var mailboxMessagesIterator = new MailboxMessagesIterator(mailbox, _mailBoxManager);

                var message = mailboxMessagesIterator.First();
                while (!mailboxMessagesIterator.IsDone)
                {
                    var path = MailStoragePathCombiner.GetMessageDirectory(mailbox.UserId, message.StreamId);

                    try
                    {
                        if (dataStorage.IsDirectory(string.Empty, path))
                        {
                            _log.Debug("Trying remove files on path '{0}'", path);
                            dataStorage.DeleteDirectory(string.Empty, path);
                        }
                    }
                    catch (Exception)
                    {
                        _log.Error("Can't remove stored mail data in path = '{0}' for mailboxId = {0} on tenant {1}",
                                   path, mailbox.MailBoxId, mailbox.TenantId);
                    }

                    _log.Info("Clear MessageId = {1}", mailbox.MailBoxId, message.Id);
                    message = mailboxMessagesIterator.Next();
                }

                _log.Debug("Trying remove garbage from db");
                _garbageManager.ClearMailboxData(mailbox);
            }
            catch (Exception)
            {
                _log.Error("Can't remove all stored mail data for mailboxId = {0} on tenant {1}", mailbox.MailBoxId, mailbox.TenantId);
                return(false);
            }

            return(true);
        }
        public string StoreMailBody(MailBox mailBox, MailMessage messageItem)
        {
            if (string.IsNullOrEmpty(messageItem.HtmlBody) && (messageItem.HtmlBodyStream == null || messageItem.HtmlBodyStream.Length == 0))
            {
                return(string.Empty);
            }

            // Using id_user as domain in S3 Storage - allows not to add quota to tenant.
            var savePath = MailStoragePathCombiner.GetBodyKey(mailBox.UserId, messageItem.StreamId);
            var storage  = MailDataStore.GetDataStore(mailBox.TenantId);

            storage.QuotaController = null;

            try
            {
                string response;

                if (messageItem.HtmlBodyStream != null && messageItem.HtmlBodyStream.Length > 0)
                {
                    messageItem.HtmlBodyStream.Seek(0, SeekOrigin.Begin);

                    response = storage
                               .Save(savePath, messageItem.HtmlBodyStream, MailStoragePathCombiner.BODY_FILE_NAME)
                               .ToString();
                }
                else
                {
                    using (var reader = new MemoryStream(Encoding.UTF8.GetBytes(messageItem.HtmlBody)))
                    {
                        response = storage
                                   .Save(savePath, reader, MailStoragePathCombiner.BODY_FILE_NAME)
                                   .ToString();
                    }
                }

                _log.Debug("StoreMailBody() tenant='{0}', user_id='{1}', save_body_path='{2}' Result: {3}",
                           mailBox.TenantId, mailBox.UserId, savePath, response);

                return(response);
            }
            catch (Exception ex)
            {
                _log.Debug(
                    "StoreMailBody() Problems with message saving in messageId={0}. \r\n Exception: \r\n {0}\r\n",
                    messageItem.MimeMessageId, ex.ToString());

                storage.Delete(string.Empty, savePath);
                throw;
            }
        }
        public void StoreAttachmentCopy(int id_tenant, string id_user, MailAttachment attachment, string stream_id)
        {
            try
            {
                if (attachment.streamId.Equals(stream_id))
                {
                    return;
                }

                var s3_key = MailStoragePathCombiner.GerStoredFilePath(attachment);

                var data_client = MailDataStore.GetDataStore(id_tenant);

                if (!data_client.IsFile(s3_key))
                {
                    return;
                }

                attachment.fileNumber =
                    !string.IsNullOrEmpty(attachment.contentId) //Upload hack: embedded attachment have to be saved in 0 folder
                        ? 0
                        : attachment.fileNumber;

                var new_s3_key = MailStoragePathCombiner.GetFileKey(id_user, stream_id, attachment.fileNumber,
                                                                    attachment.storedName);

                var copy_s3_url = data_client.Copy(s3_key, string.Empty, new_s3_key);

                attachment.storedFileUrl = MailStoragePathCombiner.GetStoredUrl(copy_s3_url);

                attachment.streamId = stream_id;

                _log.Debug("StoreAttachmentCopy() tenant='{0}', user_id='{1}', stream_id='{2}', new_s3_key='{3}', copy_s3_url='{4}', storedFileUrl='{5}',  filename='{6}'",
                           id_tenant, id_user, stream_id, new_s3_key, copy_s3_url, attachment.storedFileUrl, attachment.fileName);
            }
            catch (Exception ex)
            {
                _log.Error("CopyAttachment(). filename='{0}', ctype='{1}' Exception:\r\n{2}\r\n",
                           attachment.fileName,
                           attachment.contentType,
                           ex.ToString());

                throw;
            }
        }
Esempio n. 11
0
        private static void RemoveUserMailDirectory(int tenant, string userId, ILogger log)
        {
            log.Debug("MailDataStore.GetDataStore(Tenant = {0})", tenant);

            var dataStorage = MailDataStore.GetDataStore(tenant);

            var userMailDir = MailStoragePathCombiner.GetUserMailsDirectory(userId);

            try
            {
                log.Info("RemoveUserMailDirectory(Path: {0}, Tenant = {1} User = '******')", userMailDir, tenant, userId);

                dataStorage.DeleteDirectory(userMailDir);
            }
            catch (Exception ex)
            {
                log.Error("MailDataStore.DeleteDirectory(path: {0}) failed. Error: {1}", userMailDir, ex.ToString());
            }
        }
        public string GetMailEmlUrl(int tenant, string user, string streamId)
        {
            // Using id_user as domain in S3 Storage - allows not to add quota to tenant.
            var emlPath   = MailStoragePathCombiner.GetEmlKey(user, streamId);
            var dataStore = MailDataStore.GetDataStore(tenant);

            try
            {
                var emlUri = dataStore.GetUri(string.Empty, emlPath);
                var url    = MailStoragePathCombiner.GetStoredUrl(emlUri);

                return(url);
            }
            catch (Exception ex)
            {
                _log.Error("GetMailEmlUrl() tenant='{0}', user_id='{1}', save_eml_path='{2}' Exception: {3}",
                           tenant, user, emlPath, ex.ToString());
            }

            return("");
        }
Esempio n. 13
0
        public bool RemoveTerminatedUserGarbageMailData(int tenant, string user)
        {
            var userInfo = GetUserInfo(tenant, user);

            if (userInfo == null || userInfo.Status != EmployeeStatus.Terminated)
            {
                return(false);
            }

            _log.Info(
                "User is terminated. All mail's data for this user = '******' (Tenant={1}) will be removed!",
                user, tenant);

            try
            {
                var dataStorage = MailDataStore.GetDataStore(tenant);

                var path = MailStoragePathCombiner.GetUserMailsDirectory(userInfo.ID.ToString());

                if (dataStorage.IsDirectory(string.Empty, path))
                {
                    _log.Debug("Trying remove all user mail's files from storage '{0}' on path '{1}'",
                               Defines.MODULE_NAME, path);
                    dataStorage.DeleteDirectory(string.Empty, path);
                }
            }
            catch (Exception ex)
            {
                _log.Error("Can't remove all stored mail data for user '{0}' on tenant {1}\r\nException: {2}", user,
                           tenant, ex.ToString());
                return(false);
            }

            _log.Debug("Trying remove garbage from db");
            _garbageManager.ClearUserMailData(tenant, userInfo);

            return(true);
        }
Esempio n. 14
0
        private static void RemoveMailboxData(MailBoxData mailbox, bool totalMailRemove, ILog log)
        {
            log.InfoFormat("RemoveMailboxData(id: {0} address: {1})", mailbox.MailBoxId, mailbox.EMail.ToString());

            try
            {
                if (!mailbox.IsRemoved)
                {
                    log.Info("Mailbox is't removed.");

                    var needRecalculateFolders = !totalMailRemove;

                    if (mailbox.IsTeamlab)
                    {
                        log.Info("RemoveTeamlabMailbox()");

                        CoreContext.TenantManager.SetCurrentTenant(mailbox.TenantId);
                        SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem);

                        RemoveTeamlabMailbox(mailbox, log);
                    }

                    log.Info("SetMailboxRemoved()");
                    var engine = new EngineFactory(mailbox.TenantId, mailbox.UserId);
                    engine.MailboxEngine.RemoveMailBox(mailbox, needRecalculateFolders);

                    mailbox.IsRemoved = true;
                }

                log.DebugFormat("MailDataStore.GetDataStore(Tenant = {0})", mailbox.TenantId);

                var dataStorage = MailDataStore.GetDataStore(mailbox.TenantId);

                dataStorage.QuotaController = null;

                log.Debug("GetMailboxAttachsCount()");

                var mailGarbageDao = new MailGarbageDao();

                var countAttachs = mailGarbageDao.GetMailboxAttachsCount(mailbox);

                log.InfoFormat("Found {0} garbage attachments", countAttachs);

                if (countAttachs > 0)
                {
                    var sumCount = 0;

                    log.DebugFormat("GetMailboxAttachsGarbage(limit = {0})", Config.MaxFilesToRemoveAtOnce);

                    var attachGrbgList = mailGarbageDao.GetMailboxAttachs(mailbox, Config.MaxFilesToRemoveAtOnce);

                    sumCount += attachGrbgList.Count;

                    log.InfoFormat("Clearing {0} garbage attachments ({1}/{2})", attachGrbgList.Count, sumCount, countAttachs);

                    while (attachGrbgList.Any())
                    {
                        foreach (var attachGrbg in attachGrbgList)
                        {
                            RemoveFile(dataStorage, attachGrbg.Path, log);
                        }

                        log.Debug("CleanupMailboxAttachs()");

                        mailGarbageDao.CleanupMailboxAttachs(attachGrbgList);

                        log.Debug("GetMailboxAttachs()");

                        attachGrbgList = mailGarbageDao.GetMailboxAttachs(mailbox, Config.MaxFilesToRemoveAtOnce);

                        if (!attachGrbgList.Any())
                        {
                            continue;
                        }

                        sumCount += attachGrbgList.Count;

                        log.InfoFormat("Found {0} garbage attachments ({1}/{2})", attachGrbgList.Count, sumCount,
                                       countAttachs);
                    }
                }

                log.Debug("GetMailboxMessagesCount()");

                var countMessages = mailGarbageDao.GetMailboxMessagesCount(mailbox);

                log.InfoFormat("Found {0} garbage messages", countMessages);

                if (countMessages > 0)
                {
                    var sumCount = 0;

                    log.DebugFormat("GetMailboxMessagesGarbage(limit = {0})", Config.MaxFilesToRemoveAtOnce);

                    var messageGrbgList = mailGarbageDao.GetMailboxMessages(mailbox, Config.MaxFilesToRemoveAtOnce);

                    sumCount += messageGrbgList.Count;

                    log.InfoFormat("Clearing {0} garbage messages ({1}/{2})", messageGrbgList.Count, sumCount, countMessages);

                    while (messageGrbgList.Any())
                    {
                        foreach (var mailMessageGarbage in messageGrbgList)
                        {
                            RemoveFile(dataStorage, mailMessageGarbage.Path, log);
                        }

                        log.Debug("CleanupMailboxMessages()");

                        mailGarbageDao.CleanupMailboxMessages(messageGrbgList);

                        log.Debug("GetMailboxMessages()");

                        messageGrbgList = mailGarbageDao.GetMailboxMessages(mailbox, Config.MaxFilesToRemoveAtOnce);

                        if (!messageGrbgList.Any())
                        {
                            continue;
                        }

                        sumCount += messageGrbgList.Count;

                        log.InfoFormat("Found {0} garbage messages ({1}/{2})", messageGrbgList.Count, sumCount,
                                       countMessages);
                    }
                }

                log.Debug("ClearMailboxData()");

                mailGarbageDao.CleanupMailboxData(mailbox, totalMailRemove);

                log.DebugFormat("Garbage mailbox '{0}' was totaly removed.", mailbox.EMail.Address);
            }
            catch (Exception ex)
            {
                log.ErrorFormat("RemoveMailboxData(mailboxId = {0}) Failure\r\nException: {1}", mailbox.MailBoxId, ex.ToString());

                throw;
            }
        }
        public void StoreAttachments(int tenant, string user, List <MailAttachment> attachments, string streamId, int mailboxId)
        {
            if (!attachments.Any() || string.IsNullOrEmpty(streamId))
            {
                return;
            }

            var storage = MailDataStore.GetDataStore(tenant);

            if (storage == null)
            {
                throw new NullReferenceException("GetDataStore has returned null reference.");
            }

            var quotaAddSize = attachments.Sum(a => a.data.LongLength);

            QuotaUsedAdd(tenant, quotaAddSize);

            try
            {
                foreach (var attachment in attachments)
                {
                    var isAttachmentNameHasBadName = string.IsNullOrEmpty(attachment.fileName) ||
                                                     attachment.fileName.IndexOfAny(Path.GetInvalidPathChars()) != -1 ||
                                                     attachment.fileName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1;
                    if (isAttachmentNameHasBadName)
                    {
                        attachment.fileName = string.Format("attacment{0}{1}", attachment.fileNumber,
                                                            MimeMapping.GetExtention(attachment.contentType));
                    }

                    attachment.streamId = streamId;
                    attachment.tenant   = tenant;
                    attachment.user     = user;
                    StoreAttachmentWithoutQuota(tenant, user, attachment, storage);

                    //This is dirty hack needed for mailbox updating on attachment processing. If we doesn't update mailbox checktime, it will be reset.
                    if (mailboxId > 0)
                    {
                        LockMailbox(mailboxId);
                    }
                }
            }
            catch
            {
                var storedAttachmentsKeys = attachments
                                            .Where(a => !string.IsNullOrEmpty(a.storedFileUrl))
                                            .Select(MailStoragePathCombiner.GerStoredFilePath)
                                            .ToList();

                //Todo: Rewrite this ugly code
                var isQuotaCleaned = false;
                if (storedAttachmentsKeys.Any())
                {
                    var s3Storage = storage as S3Storage;
                    if (s3Storage != null)
                    {
                        // ToDo: Delete with quota argument needs to be moved to IDataStore!
                        storedAttachmentsKeys
                        .ForEach(key => s3Storage.Delete(string.Empty, key, false));
                    }
                    else
                    {
                        isQuotaCleaned = true;
                        storedAttachmentsKeys.ForEach(key => storage.Delete(string.Empty, key));
                    }
                }

                if (!isQuotaCleaned)
                {
                    QuotaUsedDelete(tenant, quotaAddSize);
                }

                _log.Debug(String.Format("Problems with attachment saving in mailboxId={0}. All message attachments was deleted.", mailboxId));
                throw;
            }
        }
 public void StoreAttachmentWithoutQuota(int id_tenant, string id_user, MailAttachment attachment)
 {
     StoreAttachmentWithoutQuota(id_tenant, id_user, attachment, MailDataStore.GetDataStore(id_tenant));
 }
Esempio n. 17
0
        private void RemoveMailboxData(MailBox mailbox, bool totalMailRemove, ILogger log)
        {
            log.Info("RemoveMailboxData(id: {0} address: {1})", mailbox.MailBoxId, mailbox.EMail.ToString());

            try
            {
                if (!mailbox.IsRemoved)
                {
                    log.Info("Mailbox is't removed.");

                    var needRecalculateFolders = !totalMailRemove;

                    if (!mailbox.IsTeamlab)
                    {
                        log.Info("RemoveMailBox()");

                        _mailBoxManager.RemoveMailBox(mailbox, needRecalculateFolders);
                    }
                    else
                    {
                        log.Info("RemoveTeamlabMailbox()");

                        CoreContext.TenantManager.SetCurrentTenant(mailbox.TenantId);

                        SecurityContext.AuthenticateMe(Core.Configuration.Constants.CoreSystem);

                        RemoveTeamlabMailbox(mailbox);

                        _mailBoxManager.RemoveMailBox(mailbox, needRecalculateFolders);
                    }

                    mailbox.IsRemoved = true;
                }

                log.Debug("MailDataStore.GetDataStore(Tenant = {0})", mailbox.TenantId);

                var dataStorage = MailDataStore.GetDataStore(mailbox.TenantId);

                log.Debug("GetMailboxAttachsCount()");

                var countAttachs = _garbageManager.GetMailboxAttachsCount(mailbox);

                log.Info("Found {0} garbage attachments", countAttachs);

                if (countAttachs > 0)
                {
                    var sumCount = 0;

                    log.Debug("GetMailboxAttachsGarbage(limit = {0})", Config.MaxFilesToRemoveAtOnce);

                    var attachGrbgList = _garbageManager.GetMailboxAttachs(mailbox, Config.MaxFilesToRemoveAtOnce);

                    sumCount += attachGrbgList.Count;

                    log.Info("Clearing {0} garbage attachments ({1}/{2})", attachGrbgList.Count, sumCount, countAttachs);

                    while (attachGrbgList.Any())
                    {
                        dataStorage.QuotaController = null;

                        log.Debug("dataStorage.DeleteFiles()");

                        foreach (var attachGrbg in attachGrbgList)
                        {
                            try
                            {
                                dataStorage.Delete(string.Empty, attachGrbg.Path);
                            }
                            catch (Exception ex)
                            {
                                _log.Error("dataStorage.DeleteFiles(path: {0}) failed. Error: {1}", attachGrbg.Path, ex.ToString());
                            }
                        }

                        log.Debug("RemoveMailboxAttachsGarbage()");

                        _garbageManager.CleanupMailboxAttachs(attachGrbgList);

                        log.Debug("GetMailboxAttachsGarbage()");

                        attachGrbgList = _garbageManager.GetMailboxAttachs(mailbox, Config.MaxFilesToRemoveAtOnce);

                        if (!attachGrbgList.Any())
                        {
                            continue;
                        }

                        sumCount += attachGrbgList.Count;

                        log.Info("Found {0} garbage attachments ({1}/{2})", attachGrbgList.Count, sumCount,
                                 countAttachs);
                    }
                }

                log.Debug("GetMailboxMessagesCount()");

                var countMessages = _garbageManager.GetMailboxMessagesCount(mailbox);

                log.Info("Found {0} garbage messages", countMessages);

                if (countMessages > 0)
                {
                    var sumCount = 0;

                    log.Debug("GetMailboxMessagesGarbage(limit = {0})", Config.MaxFilesToRemoveAtOnce);

                    var messageGrbgList = _garbageManager.GetMailboxMessages(mailbox, Config.MaxFilesToRemoveAtOnce);

                    sumCount += messageGrbgList.Count;

                    log.Info("Clearing {0} garbage messages ({1}/{2})", messageGrbgList.Count, sumCount, countMessages);

                    while (messageGrbgList.Any())
                    {
                        dataStorage.QuotaController = null;

                        log.Debug("dataStorage.DeleteFiles()");

                        foreach (var mailMessageGarbage in messageGrbgList)
                        {
                            try
                            {
                                dataStorage.Delete(string.Empty, mailMessageGarbage.Path);
                            }
                            catch (Exception ex)
                            {
                                _log.Error("dataStorage.DeleteFiles(path: {0}) failed. Error: {1}", mailMessageGarbage.Path, ex.ToString());
                            }
                        }

                        log.Debug("RemoveMailboxMessagesGarbage()");

                        _garbageManager.CleanupMailboxMessages(messageGrbgList);

                        log.Debug("GetMailboxMessagesGarbage()");

                        messageGrbgList = _garbageManager.GetMailboxMessages(mailbox, Config.MaxFilesToRemoveAtOnce);

                        if (!messageGrbgList.Any())
                        {
                            continue;
                        }

                        sumCount += messageGrbgList.Count;

                        log.Info("Found {0} garbage messages ({1}/{2})", messageGrbgList.Count, sumCount,
                                 countMessages);
                    }
                }

                log.Debug("ClearMailboxData()");

                _garbageManager.CleanupMailboxData(mailbox, totalMailRemove);

                log.Debug("Garbage mailbox '{0}' was totaly removed.", mailbox.EMail.Address);
            }
            catch (Exception ex)
            {
                log.Error("RemoveMailboxData(mailboxId = {0}) Failure\r\nException: {1}", mailbox.MailBoxId, ex.ToString());
            }
        }
        public MailMessage Save(MailComposeBase compose)
        {
            var embededAttachmentsForSaving = FixHtmlBodyWithEmbeddedAttachments(compose);

            var message = compose.ToMailMessage();

            var engine = new EngineFactory(compose.Mailbox.TenantId, compose.Mailbox.UserId);

            var addIndex = compose.Id == 0;

            var attachmentsToRestore = message.Attachments.Where(att => att.streamId != message.StreamId || att.isTemp).ToList();

            var needRestoreAttachments = attachmentsToRestore.Any();

            if (needRestoreAttachments)
            {
                message.Attachments.ForEach(
                    attachment =>
                    engine.AttachmentEngine.StoreAttachmentCopy(compose.Mailbox.TenantId, compose.Mailbox.UserId,
                                                                attachment, compose.StreamId));
            }

            MessageEngine.StoreMailBody(compose.Mailbox, message, Log);

            long usedQuota;

            using (var daoFactory = new DaoFactory())
            {
                var db = daoFactory.DbManager;

                using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted))
                {
                    compose.Id = engine.MessageEngine.MailSave(daoFactory, compose.Mailbox, message, compose.Id, message.Folder, message.Folder, null,
                                                               string.Empty, string.Empty, false, out usedQuota);

                    message.Id = compose.Id;

                    if (compose.AccountChanged)
                    {
                        engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, compose.PreviousMailboxId,
                                                       compose.Mailbox.TenantId, compose.Mailbox.UserId);
                    }

                    var daoMailInfo = daoFactory.CreateMailInfoDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);

                    if (compose.Id > 0 && needRestoreAttachments)
                    {
                        var daoAttachment       = daoFactory.CreateAttachmentDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);
                        var existingAttachments = daoAttachment.GetAttachments(
                            new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                        foreach (var attachment in message.Attachments)
                        {
                            if (existingAttachments.Any(x => x.Id == attachment.fileId))
                            {
                                continue;
                            }

                            var attach = attachment.ToAttachmnet(compose.Id);
                            attach.Id = 0;

                            var newId = daoAttachment.SaveAttachment(attach);
                            attachment.fileId = newId;
                        }

                        if (message.Attachments.Any())
                        {
                            var count = daoAttachment.GetAttachmentsCount(
                                new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                            daoMailInfo.SetFieldValue(
                                SimpleMessagesExp.CreateBuilder(compose.Mailbox.TenantId, compose.Mailbox.UserId)
                                .SetMessageId(compose.Id)
                                .Build(),
                                MailTable.Columns.AttachCount,
                                count);
                        }
                    }

                    if (compose.Id > 0 && embededAttachmentsForSaving.Any())
                    {
                        var daoAttachment = daoFactory.CreateAttachmentDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);

                        foreach (var attachment in embededAttachmentsForSaving)
                        {
                            var newId = daoAttachment.SaveAttachment(attachment.ToAttachmnet(compose.Id));
                            attachment.fileId = newId;
                        }

                        if (message.Attachments.Any())
                        {
                            var count = daoAttachment.GetAttachmentsCount(
                                new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                            daoMailInfo.SetFieldValue(
                                SimpleMessagesExp.CreateBuilder(compose.Mailbox.TenantId, compose.Mailbox.UserId)
                                .SetMessageId(compose.Id)
                                .Build(),
                                MailTable.Columns.AttachCount,
                                count);
                        }
                    }

                    engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, compose.Mailbox.MailBoxId, compose.Mailbox.TenantId,
                                                   compose.Mailbox.UserId);

                    if (compose.AccountChanged)
                    {
                        var daoCrmLink = daoFactory.CreateCrmLinkDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);

                        daoCrmLink.UpdateCrmLinkedMailboxId(message.ChainId, compose.PreviousMailboxId,
                                                            compose.Mailbox.MailBoxId);
                    }

                    tx.Commit();
                }
            }

            if (usedQuota > 0)
            {
                engine.QuotaEngine.QuotaUsedDelete(usedQuota);
            }

            if (addIndex)
            {
                engine.IndexEngine.Add(message.ToMailWrapper(compose.Mailbox.TenantId, new Guid(compose.Mailbox.UserId)));
            }
            else
            {
                engine.IndexEngine.Update(new List <MailWrapper>
                {
                    message.ToMailWrapper(compose.Mailbox.TenantId,
                                          new Guid(compose.Mailbox.UserId))
                });
            }

            try
            {
                var tempStorage = MailDataStore.GetDataStore(compose.Mailbox.TenantId);

                tempStorage.DeleteDirectory("attachments_temp", compose.Mailbox.UserId + "/" + compose.StreamId + "/");
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("Clearing temp storage failed with exception: {0}", ex.ToString());
            }

            return(message);
        }
 public void StoreAttachmentWithoutQuota(int tenant, string user, MailAttachment attachment)
 {
     StoreAttachmentWithoutQuota(tenant, user, attachment, MailDataStore.GetDataStore(tenant));
 }