/// <summary> /// Deletes IMAP folder. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what to delete. For example: Inbox,Public Folders/Documnets .</param> public void DeleteFolder(string accessingUser,string folderOwnerUser,string folder) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Don't allow to delete shared folders root folder. For BoundedUser root don't allow root folder only, for UsersShared root don't allow root + user name. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'c' permission. There is builtin user system, skip ACL for it. *) Create folder. */ // Don't allow to delete inbox if(folder.ToLower() == "inbox"){ throw new Exception("Can't delete inbox"); } //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; /* Don't allow to delete shared folders root folder. For BoundedUser root don't allow root folder only, for UsersShared root don't allow root + user name. */ // Main shared folder root. if(mappedFolder.SharedRootName.ToLower() == originalFolder.ToLower()){ throw new ArgumentException("Can't delete shared root folder '" + originalFolder + "' !"); } // Users shared folder: root/username -> no folder if(folder == ""){ throw new ArgumentException("Can't delete shared root folder '" + originalFolder + "' !"); } if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder doesn't exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'c' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.c) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Recycle bin handling ----------------------------------------------------------------------// if(Convert.ToBoolean(GetRecycleBinSettings().Rows[0]["DeleteToRecycleBin"])){ IMAP_MessageCollection messages = new IMAP_MessageCollection(); GetMessagesInfo("system",folderOwnerUser,folder,messages); foreach(IMAP_Message message in messages){ EmailMessageItems msgItems = new EmailMessageItems(message.ID,IMAP_MessageItems_enum.Message); GetMessageItems("system",folderOwnerUser,folder,msgItems); if(msgItems.MessageExists){ string subject = "<none>"; try{ subject = MimeUtils.ParseHeaderField("Subject:",msgItems.MessageStream); subject = subject.Replace("\r",""); subject = subject.Replace("\n",""); } catch{ } msgItems.MessageStream.Position = 0; byte[] data = new byte[msgItems.MessageStream.Length]; msgItems.MessageStream.Read(data,0,data.Length); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreRecycleBinMessage")){ sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,Guid.NewGuid().ToString()); sqlCmd.AddParameter("_user" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_subject" ,NpgsqlDbType.Varchar,subject); sqlCmd.AddParameter("_data" ,NpgsqlDbType.Bytea ,data); DataSet ds = sqlCmd.Execute(); } } } } //----------------------------------------------------------------------------------------------// //--- Delete folder using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteFolder")){ sqlCmd.AddParameter("_folderOwnerUser",NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folderName" ,NpgsqlDbType.Varchar,folder); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Gets message header + number of specified lines. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message top lines to get. For example: Inbox,Public Folders/Documnets .</param> /// <param name="msgID">MessageID.</param> /// <param name="nrLines">Number of lines to retrieve. NOTE: line counting starts at the end of header.</param> /// <returns>Returns message header + number of specified lines.</returns> public byte[] GetMessageTopLines(string accessingUser,string folderOwnerUser,string folder,string msgID,int nrLines) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Get message top lines. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(msgID); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message top lines if(nrLines < 50){ using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessageTopLines")){ sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,msgID); return GetTopLines(new MemoryStream((byte[])sqlCmd.ExecuteScalar()),nrLines); } } else{ EmailMessageItems msgItems = new EmailMessageItems(msgID,IMAP_MessageItems_enum.Message); GetMessageItems(accessingUser,folderOwnerUser,folder,msgItems); byte[] topLines = GetTopLines(msgItems.MessageStream,nrLines); msgItems.MessageStream.Dispose(); return topLines; } }
/// <summary> /// Creates copy of message to destination IMAP folder. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what contains message to copy. For example: Inbox,Public Folders/Documnets .</param> /// <param name="destFolderUser">Destination IMAP folder owner user name.</param> /// <param name="destFolder">Destination IMAP folder name.</param> /// <param name="message">IMAP message which to copy.</param> public void CopyMessage(string accessingUser,string folderOwnerUser,string folder,string destFolderUser,string destFolder,LumiSoft.Net.IMAP.Server.IMAP_Message message) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) We don't need to map shared folder, check security, it done by GetMessage and StoreMessage methods. *) Copy message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateUserName(destFolderUser); ArgsValidator.ValidateFolder(destFolder); ArgsValidator.ValidateNotNull(message); //---------------------------------------// //--- Copy message //--- Copy message EmailMessageItems msgItems = new EmailMessageItems(message.ID,IMAP_MessageItems_enum.Message); GetMessageItems(accessingUser,folderOwnerUser,folder,msgItems); StoreMessage("system",destFolderUser,destFolder,msgItems.MessageStream,message.InternalDate,message.Flags); msgItems.MessageStream.Dispose(); }
/// <summary> /// Deletes message from mailbox. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="messageID">Message ID.</param> /// <param name="uid">Message UID value.</param> public void DeleteMessage(string accessingUser,string folderOwnerUser,string folder,string messageID,int uid) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'd' permission. There is builtin user system, skip ACL for it. *) Fill messages info. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(messageID); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'd' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.d) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Recycle bin handling ----------------------------------------------------------------------// if(Convert.ToBoolean(GetRecycleBinSettings().Rows[0]["DeleteToRecycleBin"])){ EmailMessageItems msgItems = new EmailMessageItems(messageID,IMAP_MessageItems_enum.Message | IMAP_MessageItems_enum.Envelope); GetMessageItems("system",folderOwnerUser,folder,msgItems); if(msgItems.MessageExists){ byte[] data = new byte[msgItems.MessageStream.Length]; msgItems.MessageStream.Read(data,0,data.Length); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreRecycleBinMessage")){ sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,Guid.NewGuid().ToString()); sqlCmd.AddParameter("_user" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_size" ,NpgsqlDbType.Bigint ,data.Length); sqlCmd.AddParameter("_envelope" ,NpgsqlDbType.Varchar,msgItems.Envelope); sqlCmd.AddParameter("_data" ,NpgsqlDbType.Bytea ,data); DataSet ds = sqlCmd.Execute(); } } } //----------------------------------------------------------------------------------------------// //--- Delete message using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteMessage")){ sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,messageID); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Gets specified message specified items. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="e">MessageItems info.</param> public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessagesItems")){ sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,e.MessageID); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "lsMailStore"; if((e.MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0){ e.BodyStructure = System.Text.Encoding.Default.GetString((byte[])ds.Tables["lsMailStore"].Rows[0]["ImapBody"]).Substring(5); } if((e.MessageItems & IMAP_MessageItems_enum.Envelope) != 0){ e.Envelope = System.Text.Encoding.Default.GetString((byte[])ds.Tables["lsMailStore"].Rows[0]["ImapEnvelope"]); } if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){ e.Header = GetTopLines(new MemoryStream((byte[])ds.Tables["lsMailStore"].Rows[0]["TopLines"]),0); } if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){ using(WSqlCommand sqlCmd2 = new WSqlCommand(m_ConStr,"lspr_GetMessage")){ sqlCmd2.AddParameter("_userName" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd2.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd2.AddParameter("_messageID" ,NpgsqlDbType.Varchar,e.MessageID); DataSet ds2 = sqlCmd2.Execute(); ds2.Tables[0].TableName = "lsMailStore"; e.MessageStream = new MemoryStream((byte[])ds2.Tables["lsMailStore"].Rows[0]["Data"]); } } } }
public void GetMessageItems(string accessingUser, string folderOwnerUser, string folder, EmailMessageItems e) { ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); if (!this.UserExists(folderOwnerUser)) { throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } folder = API_Utlis.NormalizeFolder(folder); string text = folder; xml_API.SharedFolderMapInfo sharedFolderMapInfo = this.MapSharedFolder(text); if (sharedFolderMapInfo.IsSharedFolder) { folderOwnerUser = sharedFolderMapInfo.FolderOnwer; folder = sharedFolderMapInfo.Folder; if (folderOwnerUser == "" || folder == "") { throw new ArgumentException("Specified root folder '" + text + "' isn't accessible !"); } } if (!this.FolderExists(folderOwnerUser + "/" + folder)) { throw new Exception("Folder '" + folder + "' doesn't exist !"); } if (accessingUser.ToLower() != "system") { IMAP_ACL_Flags userACL = this.GetUserACL(folderOwnerUser, folder, accessingUser); if ((userACL & IMAP_ACL_Flags.r) == IMAP_ACL_Flags.None) { throw new InsufficientPermissionsException(string.Concat(new string[] { "Insufficient permissions for folder '", accessingUser, "/", folder, "' !" })); } } string str = API_Utlis.DirectoryExists(API_Utlis.PathFix(string.Concat(new string[] { this.m_MailStorePath, "Mailboxes\\", folderOwnerUser, "\\", IMAP_Utils.Encode_IMAP_UTF7_String(folder) }))); string text2 = API_Utlis.FileExists(API_Utlis.PathFix(str + "\\" + e.MessageID + ".eml")); if (text2 != null) { if ((e.MessageItems & (IMAP_MessageItems_enum)18) != IMAP_MessageItems_enum.None) { bool flag = true; FileStream fileStream = File.Open(text2, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); new _InternalHeader(fileStream); long position = fileStream.Position; if ((e.MessageItems & IMAP_MessageItems_enum.Header) != IMAP_MessageItems_enum.None) { fileStream.Position = position; e.Header = this.GetTopLines(fileStream, 0); } if ((e.MessageItems & IMAP_MessageItems_enum.Message) != IMAP_MessageItems_enum.None) { fileStream.Position = position; e.MessageStream = fileStream; flag = false; } if (flag) { fileStream.Dispose(); return; } } } else { e.MessageExists = false; } }
public void CopyMessage(string accessingUser, string folderOwnerUser, string folder, string destFolderUser, string destFolder, IMAP_MessageInfo messageInfo) { ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateUserName(destFolderUser); ArgsValidator.ValidateFolder(destFolder); ArgsValidator.ValidateNotNull(messageInfo); EmailMessageItems emailMessageItems = new EmailMessageItems(messageInfo.ID, IMAP_MessageItems_enum.Message); this.GetMessageItems(accessingUser, folderOwnerUser, folder, emailMessageItems); this.StoreMessage("system", destFolderUser, destFolder, emailMessageItems.MessageStream, messageInfo.InternalDate, messageInfo.Flags); emailMessageItems.MessageStream.Dispose(); }
/// <summary> /// Gets specified message specified items. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="e">MessageItems info.</param> public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message string folderPath = API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + Core.Encode_IMAP_UTF7_String(folder))); string msgFile = API_Utlis.FileExists(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".eml")); // Check if file exists if(msgFile != null){ if((e.MessageItems & (IMAP_MessageItems_enum.BodyStructure | IMAP_MessageItems_enum.Envelope)) != 0){ // Using OpenOrCreateFile ensures that multiple .info files constructions won't happen at same time. // This can happen if multiple sessions want same message at same time. using(FileStream fs = OpenOrCreateFile(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".info"),10000)){ DataSet dsMessageInfo = new DataSet("dsMessageInfo"); dsMessageInfo.Tables.Add("MessageInfo"); dsMessageInfo.Tables["MessageInfo"].Columns.Add("ImapEnvelope"); dsMessageInfo.Tables["MessageInfo"].Columns.Add("ImapBody"); // Message info file doesn't exist, create it if(fs.Length == 0){ Mime m = null; try{ m = Mime.Parse(msgFile); } // Invalid message, parsing failed catch{ m = Mime.CreateSimple(new AddressList(),new AddressList(),"BAD Message","This is BAD message, mail server failed to parse it !",""); } DataRow dr = dsMessageInfo.Tables["MessageInfo"].NewRow(); dr["ImapEnvelope"] = IMAP_Envelope.ConstructEnvelope(m.MainEntity); dr["ImapBody"] = IMAP_BODY.ConstructBodyStructure(m,false); dsMessageInfo.Tables["MessageInfo"].Rows.Add(dr); dsMessageInfo.WriteXml(fs); } // Load message info else{ dsMessageInfo.ReadXml(fs); } e.Envelope = dsMessageInfo.Tables["MessageInfo"].Rows[0]["ImapEnvelope"].ToString(); // Remove word BODY, currently internal header adds it. e.BodyStructure = dsMessageInfo.Tables["MessageInfo"].Rows[0]["ImapBody"].ToString().Substring(5); } } if((e.MessageItems & (IMAP_MessageItems_enum.Header | IMAP_MessageItems_enum.Message)) != 0){ bool closeStream = true; // TODO: Cheage to FileAccess.Read in next versions FileStream fs = File.Open(msgFile,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite); // Just skip internal header _InternalHeader internalHeader = new _InternalHeader(fs); long initialPosition = fs.Position; if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){ fs.Position = initialPosition; e.Header = GetTopLines(fs,0); } if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){ fs.Position = initialPosition; e.MessageStream = fs; // Don't close stream, it will be closed by IMAP server when all done. closeStream = false; } if(closeStream){ fs.Dispose(); } } } else{ e.MessageExists = false; } }
/// <summary> /// Gets specified message specified items. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="e">MessageItems info.</param> public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message string folderPath = API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + IMAP_Utils.Encode_IMAP_UTF7_String(folder))); string msgFile = API_Utlis.FileExists(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".eml")); // Check if file exists if(msgFile != null){ if((e.MessageItems & (IMAP_MessageItems_enum.Header | IMAP_MessageItems_enum.Message)) != 0){ bool closeStream = true; // TODO: Change to FileAccess.Read in next versions FileStream fs = File.Open(msgFile,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite); // Just skip internal header _InternalHeader internalHeader = new _InternalHeader(fs); long initialPosition = fs.Position; if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){ fs.Position = initialPosition; e.Header = GetTopLines(fs,0); } if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){ fs.Position = initialPosition; e.MessageStream = fs; // Don't close stream, it will be closed by POP3/IMAP server when all done. closeStream = false; } if(closeStream){ fs.Dispose(); } } } else{ e.MessageExists = false; } }
/// <summary> /// Gets specified message specified items. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="e">MessageItems info.</param> public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessage")){ sqlCmd.AddParameter("@MessageID" ,SqlDbType.NVarChar,e.MessageID); sqlCmd.AddParameter("@Mailbox" ,SqlDbType.NVarChar,folderOwnerUser); sqlCmd.AddParameter("@Folder" ,SqlDbType.NVarChar,folder); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "lsMailStore"; byte[] data = (byte[])ds.Tables["lsMailStore"].Rows[0]["Data"]; Mime m = null; if((e.MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0 || (e.MessageItems & IMAP_MessageItems_enum.Envelope) != 0){ try{ m = Mime.Parse(data); } catch(Exception x){ m = LumiSoft.Net.Mime.Mime.CreateSimple(new AddressList(),new AddressList(),"[BAD MESSAGE] Bad message, message parsing failed !","NOTE: Bad message, message parsing failed !\r\n\r\n" + x.Message,""); } } if((e.MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0){ e.BodyStructure = IMAP_BODY.ConstructBodyStructure(m,false).Substring(5); } if((e.MessageItems & IMAP_MessageItems_enum.Envelope) != 0){ e.Envelope = IMAP_Envelope.ConstructEnvelope(m.MainEntity); } if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){ e.Header = GetTopLines(new MemoryStream(data),0); } if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){ e.MessageStream = new MemoryStream(data); } } }
private void IMAP_Server_GetMessageItems(object sender,IMAP_eArgs_MessageItems e) { string userName = e.Session.UserName; string folder = e.Session.SelectedMailbox; EmailMessageItems eArgs = new EmailMessageItems(e.MessageInfo.ID,e.MessageItems); m_pApi.GetMessageItems(userName,userName,folder,eArgs); eArgs.CopyTo(e); }
private void POP3_Server_GetMessageStream(object sender,POP3_eArgs_GetMessageStream e) { try{ EmailMessageItems eArgs = new EmailMessageItems(e.MessageInfo.ID,IMAP_MessageItems_enum.Message); m_pApi.GetMessageItems(e.Session.UserName,e.Session.UserName,"Inbox",eArgs); e.MessageExists = eArgs.MessageExists; if(eArgs.MessageStream != null){ e.MessageStream = eArgs.MessageStream; } } catch(Exception x){ Error.DumpError(this.Name,x,new System.Diagnostics.StackTrace()); } }
private void m_pPop3Server_Session_GetMessageStream(object sender,POP3_e_GetMessageStream e) { try{ string userName = ((POP3_Session)sender).AuthenticatedUserIdentity.Name; EmailMessageItems eArgs = new EmailMessageItems(e.Message.Tag.ToString(),IMAP_MessageItems_enum.Message); m_pApi.GetMessageItems(userName,userName,"Inbox",eArgs); if(eArgs.MessageStream != null){ e.MessageStream = eArgs.MessageStream; } } catch(Exception x){ Error.DumpError(this.Name,x,new System.Diagnostics.StackTrace()); } }
private void m_pImapServer_Session_Fetch(object sender,IMAP_e_Fetch e) { try{ IMAP_Session ses = (IMAP_Session)sender; foreach(IMAP_MessageInfo msgInfo in e.MessagesInfo){ if(e.FetchDataType == IMAP_Fetch_DataType.MessageHeader){ EmailMessageItems eArgs = new EmailMessageItems(msgInfo.ID,IMAP_MessageItems_enum.Header); m_pApi.GetMessageItems(ses.AuthenticatedUserIdentity.Name,ses.AuthenticatedUserIdentity.Name,ses.SelectedFolderName,eArgs); Mail_Message msg = null; try{ if(eArgs.MessageExists){ msg = Mail_Message.ParseFromByte(eArgs.Header); } else{ msg = GenerateMessageMissing(); } } catch{ msg = API_Utlis.GenerateBadMessage(new MemoryStream(eArgs.Header)); } e.AddData(msgInfo,msg); } else if(e.FetchDataType == IMAP_Fetch_DataType.MessageStructure){ EmailMessageItems eArgs = new EmailMessageItems(msgInfo.ID,IMAP_MessageItems_enum.Message); m_pApi.GetMessageItems(ses.AuthenticatedUserIdentity.Name,ses.AuthenticatedUserIdentity.Name,ses.SelectedFolderName,eArgs); Mail_Message msg = null; try{ if(eArgs.MessageExists){ msg = Mail_Message.ParseFromStream(eArgs.MessageStream); } else{ msg = GenerateMessageMissing(); MemoryStream ms = new MemoryStream(msg.ToByte(new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q,Encoding.UTF8),Encoding.UTF8)); eArgs.MessageStream = ms; } } catch{ msg = API_Utlis.GenerateBadMessage(eArgs.MessageStream); } e.AddData(msgInfo,msg); eArgs.MessageStream.Close(); } else{ EmailMessageItems eArgs = new EmailMessageItems(msgInfo.ID,IMAP_MessageItems_enum.Message); m_pApi.GetMessageItems(ses.AuthenticatedUserIdentity.Name,ses.AuthenticatedUserIdentity.Name,ses.SelectedFolderName,eArgs); Mail_Message msg = null; try{ if(eArgs.MessageExists){ msg = Mail_Message.ParseFromStream(eArgs.MessageStream); } else{ msg = GenerateMessageMissing(); MemoryStream ms = new MemoryStream(msg.ToByte(new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q,Encoding.UTF8),Encoding.UTF8)); eArgs.MessageStream = ms; } } catch{ msg = API_Utlis.GenerateBadMessage(eArgs.MessageStream); } e.AddData(msgInfo,msg); eArgs.MessageStream.Close(); } } } catch(Exception x){ e.Response = new IMAP_r_ServerStatus(e.Response.CommandTag,"NO","Error: " + x.Message); } }