/// <summary> /// Default constructor. /// </summary> /// <param name="onwer">Owner collection.</param> /// <param name="id">Message ID.</param> /// <param name="uid">Message IMAP UID value.</param> /// <param name="internalDate">Message store date.</param> /// <param name="size">Message size in bytes.</param> /// <param name="flags">Message flags.</param> internal IMAP_Message(IMAP_MessageCollection onwer,string id,long uid,DateTime internalDate,long size,IMAP_MessageFlags flags) { m_pOwner = onwer; m_ID = id; m_UID = uid; m_InternalDate = internalDate; m_Size = size; m_Flags = flags; }
/// <summary> /// Default constructor. /// </summary> /// <param name="onwer">Owner collection.</param> /// <param name="id">Message ID.</param> /// <param name="uid">Message IMAP UID value.</param> /// <param name="internalDate">Message store date.</param> /// <param name="size">Message size in bytes.</param> /// <param name="flags">Message flags.</param> internal IMAP_Message(IMAP_MessageCollection onwer, string id, long uid, DateTime internalDate, long size, IMAP_MessageFlags flags) { m_pOwner = onwer; m_ID = id; m_UID = uid; m_InternalDate = internalDate; m_Size = size; m_Flags = flags; }
/// <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 specified IMAP folder messages info. /// </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 messages info to get. For example: Inbox,Public Folders/Documnets .</param> /// <param name="messages">IMAP_Messages collection where to store folder messages info.</param> public void GetMessagesInfo(string accessingUser,string folderOwnerUser,string folder,IMAP_MessageCollection messages) { /* 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. *) Fill messages info. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(messages); //---------------------------------------// // 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 + "' !"); } } //--- Fill messages info using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessagesInfo")){ sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "lsMailStore"; foreach(DataRow dr in ds.Tables["lsMailStore"].Rows){ string messageID = dr["MessageID"].ToString(); int size = Convert.ToInt32(dr["Size"]); DateTime date = Convert.ToDateTime(dr["Date"]); int flags = Convert.ToInt32(dr["MessageFlags"]); int uid = Convert.ToInt32(dr["UID"]); messages.Add( messageID, uid, date, size, (IMAP_MessageFlags)flags ); } } }
/// <summary> /// Default constructor. /// </summary> /// <param name="folder">Folder name.</param> internal IMAP_SelectedFolder(string folder) { m_Folder = folder; m_pMessages = new IMAP_MessageCollection(); }
/// <summary> /// Gets specified IMAP folder messages info. /// </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 messages info to get. For example: Inbox,Public Folders/Documnets .</param> /// <param name="messages">IMAP_Messages collection where to store folder messages info.</param> public void GetMessagesInfo(string accessingUser,string folderOwnerUser,string folder,IMAP_MessageCollection messages) { /* 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. *) Fill messages info. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(messages); //---------------------------------------// // 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 info from messages info db file ----------------------------------------------------// string userID = GetUserID(folderOwnerUser); string folderFullPath = API_Utlis.PathFix(API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + Core.Encode_IMAP_UTF7_String(folder))) + "\\"); List<FolderMessageInfo> messagesInfo = FolderMessagesInfoManager.GetMessagesInfo(folderFullPath); Dictionary<int,int> flagsDB = FolderMessageFlagsManager.GetFlags(userID,folderFullPath); foreach(FolderMessageInfo messageInfo in messagesInfo){ IMAP_MessageFlags flags = IMAP_MessageFlags.Recent; if(flagsDB.ContainsKey(messageInfo.UID)){ flags = (IMAP_MessageFlags)flagsDB[messageInfo.UID]; } messages.Add( messageInfo.InternalDate.ToString("yyyyMMddHHmmss") + "_" + messageInfo.UID.ToString("D10"), messageInfo.UID, messageInfo.InternalDate.ToLocalTime(), messageInfo.Size, flags ); } //--------------------------------------------------------------------------------------------------// }
private void GetUserFolderMessagesInfo(string argsText) { try{ string[] args = TextUtils.SplitQuotedString(argsText,' ',true); if(args.Length != 3){ this.Socket.WriteLine("-ERR Invalid arguments. Syntax: GetUserFolderMessagesInfo <virtualServerID> \"<user>\" \"<folder>\""); return; } foreach(VirtualServer virtualServer in m_pServer.MailServer.VirtualServers){ if(virtualServer.ID.ToLower() == args[0].ToLower()){ // TODO: handle no existent user // TODO: handle no existent folder DataSet ds = new DataSet(); ds.Tables.Add("MessagesInfo"); ds.Tables["MessagesInfo"].Columns.Add("ID"); ds.Tables["MessagesInfo"].Columns.Add("UID"); // REMOVE ME: Now needed for delete message. ds.Tables["MessagesInfo"].Columns.Add("Size",typeof(long)); ds.Tables["MessagesInfo"].Columns.Add("Flags",typeof(long)); ds.Tables["MessagesInfo"].Columns.Add("Envelope"); IMAP_MessageCollection messages = new IMAP_MessageCollection(); virtualServer.API.GetMessagesInfo("system",args[1],args[2],messages); foreach(IMAP_Message message in messages){ try{ DataRow dr = ds.Tables["MessagesInfo"].NewRow(); dr["ID"] = message.ID; dr["UID"] = message.UID; dr["Size"] = message.Size; dr["Flags"] = message.Flags; EmailMessageItems msgItems = new EmailMessageItems(message.ID,IMAP_MessageItems_enum.Envelope); virtualServer.API.GetMessageItems("system",args[1],args[2],msgItems); dr["Envelope"] = msgItems.Envelope; ds.Tables["MessagesInfo"].Rows.Add(dr); } catch{ } } // Compress data byte[] dsZipped = CompressDataSet(ds); this.Socket.WriteLine("+OK " + dsZipped.Length); this.Socket.Write(dsZipped); return; } } this.Socket.WriteLine("-ERR Specified virtual server with ID '" + args[0] + "' doesn't exist !"); } catch(Exception x){ this.Socket.WriteLine("-ERR " + x.Message); } }
private void GetUserFolderInfo(string argsText) { /* GetUserFolderInfo <virtualServerID> "<folderOwnerUser>" "<folder>" Responses: +OK "<creationDate>" <numberOfMessages> <sizeUsed> -ERR <errorText> */ try{ string[] args = TextUtils.SplitQuotedString(argsText,' '); if(args.Length != 3){ this.Socket.WriteLine("-ERR Invalid arguments. Syntax: GetUserFolderInfo <virtualServerID> \"<folderOwnerUser>\" \"<folder>\""); return; } foreach(VirtualServer virtualServer in m_pServer.MailServer.VirtualServers){ if(virtualServer.ID.ToLower() == args[0].ToLower()){ // TODO: handle no existent user IMAP_MessageCollection messages = new IMAP_MessageCollection(); virtualServer.API.GetMessagesInfo( "system", TextUtils.UnQuoteString(args[1]), TextUtils.UnQuoteString(args[2]), messages ); // Calculate size used long sizeUsed = 0; foreach(IMAP_Message message in messages){ sizeUsed += message.Size; } DateTime creationTime = virtualServer.API.FolderCreationTime(TextUtils.UnQuoteString(args[1]),TextUtils.UnQuoteString(args[2])); this.Socket.WriteLine("+OK \"" + creationTime.ToString("yyyyMMdd HH:mm:ss") + "\" " + messages.Count + " " + sizeUsed + ""); return; } } this.Socket.WriteLine("-ERR Specified virtual server with ID '" + args[0] + "' doesn't exist !"); } catch(Exception x){ this.Socket.WriteLine("-ERR " + x.Message); } }
private void pop3_Server_GetMessgesList(object sender,LumiSoft.Net.POP3.Server.GetMessagesInfo_EventArgs e) { try{ string userName = e.UserName; IMAP_MessageCollection messages = new IMAP_MessageCollection(); m_pApi.GetMessagesInfo(userName,userName,"Inbox",messages); for(int i=0;i<messages.Count;i++){ IMAP_Message msg = messages[i]; e.Messages.Add(msg.ID,msg.UID.ToString(),msg.Size); } } catch(Exception x){ Error.DumpError(this.Name,x,new System.Diagnostics.StackTrace()); } }