/// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner POP3 client message.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(POP3_ClientMessage owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner      = owner;
                m_pPop3Client = owner.m_Pop3Client;

                SetState(AsyncOP_State.Active);

                try{
                    /* RFC 1939 5. DELE
                         Arguments:
                             a message-number (required) which may NOT refer to a
                             message marked as deleted

                         Restrictions:
                             may only be given in the TRANSACTION state

                         Discussion:
                             The POP3 server marks the message as deleted.  Any future
                             reference to the message-number associated with the message
                             in a POP3 command generates an error.  The POP3 server does
                             not actually delete the message until the POP3 session
                             enters the UPDATE state.

                         Possible Responses:
                             +OK message deleted
                             -ERR no such message

                         Examples:
                             C: DELE 1
                             S: +OK message 1 deleted
                                ...
                             C: DELE 2
                             S: -ERR message 2 already deleted
                    */

                    byte[] buffer = Encoding.UTF8.GetBytes("DELE " + owner.SequenceNumber.ToString() + "\r\n");

                    // Log
                    m_pPop3Client.LogAddWrite(buffer.Length,"DELE " + owner.SequenceNumber.ToString());

                    // Start command sending.
                    m_pPop3Client.TcpStream.BeginWrite(buffer,0,buffer.Length,this.DeleCommandSendingCompleted,null);
                }
                catch(Exception x){
                    m_pException = x;
                    m_pPop3Client.LogAddException("Exception: " + x.Message,x);
                    SetState(AsyncOP_State.Completed);
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }
Exemple #2
0
        private bool DecodeMessageAttachment(POP3_ClientMessage message)
        {
            bool _IsValid = false;
            var ro = new ReceiverObject();
            //获取这封邮件的内容
            byte[] bytes = message.MessageToByte();
            //解析从Pop3服务器发送过来的邮件附件
            Mime m = Mime.Parse(bytes);

            //二个月前的不接收了
            if (m.MainEntity.Date < DateTime.Now.AddDays(-60))
            {
                return false;
            }
            //遍历所有附件
            foreach (MimeEntity me in m.Attachments)
            {
                //附件有效
                if (!IsValidAttachment(me.ContentType_Name))
                {
                    continue;
                }
                //解压邮件
                object obj = DeSerialObj(me.Data);
                if (obj != null)
                {
                    ro.Objects.Add(obj);
                    _IsValid = true;
                }
            }
            if (_IsValid)
            {
                _ReceiverObjects.Add(ro);
                ro.Message = message;
            }
            return _IsValid;
        }
        private bool ProcessNewComment(List<string> recipients, POP3_ClientMessage message, Mail_Message mailHeader, MailboxReaderResult result)
        {
            string messageFrom = string.Empty;
            if (mailHeader.From.Count > 0)
            {
                messageFrom = string.Join("; ", mailHeader.From.ToList().Select(p => p.Address).ToArray()).Trim();
            }

            bool processed = false;

            foreach (var address in recipients)
            {
                Regex isReply = new Regex(@"(.*)(\+iid-)(\d+)@(.*)");
                Match commentMatch = isReply.Match(address);
                if (commentMatch.Success && commentMatch.Groups.Count >= 4)
                {
                    // we are in a reply and group 4 must contain the id of the original issue
                    int issueId;
                    if (int.TryParse(commentMatch.Groups[3].Value, out issueId))
                    {
                        var _currentIssue = IssueManager.GetById(issueId);

                        if (_currentIssue != null)
                        {
                            var project = ProjectManager.GetById(_currentIssue.ProjectId);

                            var mailbody = Mail_Message.ParseFromByte(message.MessageToByte());

                            bool isHtml;
                            List<MIME_Entity> attachments = null;
                            string content = GetMessageContent(mailbody, project, out isHtml, ref attachments);

                            IssueComment comment = new IssueComment
                            {
                                IssueId = issueId,
                                Comment = content,
                                DateCreated = mailHeader.Date
                            };

                            // try to find if the creator is valid user in the project, otherwise take
                            // the user defined in the mailbox config
                            var users = UserManager.GetUsersByProjectId(project.Id);
                            var emails = messageFrom.Split(';').Select(e => e.Trim().ToLower());
                            var user = users.Find(x => emails.Contains(x.Email.ToLower()));
                            if (user != null)
                            {
                                comment.CreatorUserName = user.UserName;
                            }
                            else
                            {
                                // user not found
                                continue;
                            }

                            var saved = IssueCommentManager.SaveOrUpdate(comment);
                            if (saved)
                            {
                                //add history record
                                var history = new IssueHistory
                                {
                                    IssueId = issueId,
                                    CreatedUserName = comment.CreatorUserName,
                                    DateChanged = comment.DateCreated,
                                    FieldChanged = ResourceStrings.GetGlobalResource(GlobalResources.SharedResources, "Comment", "Comment"),
                                    OldValue = string.Empty,
                                    NewValue = ResourceStrings.GetGlobalResource(GlobalResources.SharedResources, "Added", "Added"),
                                    TriggerLastUpdateChange = true
                                };
                                IssueHistoryManager.SaveOrUpdate(history);

                                var projectFolderPath = Path.Combine(Config.UploadsFolderPath, project.UploadPath);

                                // save attachments as new files
                                int attachmentsSavedCount = 1;
                                foreach (MIME_Entity mimeEntity in attachments)
                                {
                                    string fileName;
                                    var contentType = mimeEntity.ContentType.Type.ToLower();

                                    var attachment = new IssueAttachment
                                    {
                                        Id = 0,
                                        Description = "File attached by mailbox reader",
                                        DateCreated = DateTime.Now,
                                        ContentType = mimeEntity.ContentType.TypeWithSubtype,
                                        CreatorDisplayName = user.DisplayName,
                                        CreatorUserName = user.UserName,
                                        IssueId = issueId,
                                        ProjectFolderPath = projectFolderPath
                                    };
                                    attachment.Attachment = ((MIME_b_SinglepartBase)mimeEntity.Body).Data;

                                    if (contentType.Equals("attachment")) // this is an attached email
                                    {
                                        fileName = mimeEntity.ContentDisposition.Param_FileName;
                                    }
                                    else if (contentType.Equals("message")) // message has no filename so we create one
                                    {
                                        fileName = string.Format("Attached_Message_{0}.eml", attachmentsSavedCount);
                                    }
                                    else
                                    {
                                        fileName = string.IsNullOrWhiteSpace(mimeEntity.ContentType.Param_Name) ?
                                            string.Format("untitled.{0}", mimeEntity.ContentType.SubType) :
                                            mimeEntity.ContentType.Param_Name;
                                    }

                                    attachment.FileName = fileName;

                                    var saveFile = IsAllowedFileExtension(fileName);
                                    var fileSaved = false;

                                    // can we save the file?
                                    if (saveFile)
                                    {
                                        fileSaved = IssueAttachmentManager.SaveOrUpdate(attachment);

                                        if (fileSaved)
                                        {
                                            attachmentsSavedCount++;
                                        }
                                        else
                                        {
                                            LogWarning("MailboxReader: Attachment could not be saved, please see previous logs");
                                        }
                                    }
                                }

                                processed = true;

                                // add the entry if the save did not throw any exceptions
                                result.MailboxEntries.Add(new MailboxEntry());
                            }
                        }
                    }
                }
            }
            return processed;
        }
        private bool ProcessNewIssue(List<string> recipients, POP3_ClientMessage message, Mail_Message mailHeader, IList<Project> projects, MailboxReaderResult result)
        {
            var messageFrom = string.Empty;
            if (mailHeader.From.Count > 0)
            {
                messageFrom = string.Join("; ", mailHeader.From.ToList().Select(p => p.Address).ToArray()).Trim();
            }

            bool processed = false;

            // loop through the mailboxes
            foreach (var address in recipients)
            {
                var pmbox = ProjectMailboxManager.GetByMailbox(address);

                // cannot find the mailbox skip the rest
                if (pmbox == null)
                {
                    LogWarning(string.Format("MailboxReader: could not find project mailbox: {0} skipping.", address));
                    continue;
                }

                var project = projects.FirstOrDefault(p => p.Id == pmbox.ProjectId);

                if (project == null)
                {
                    project = ProjectManager.GetById(pmbox.ProjectId);

                    // project is disabled skip
                    if (project.Disabled)
                    {
                        LogWarning(string.Format("MailboxReader: Project {0} - {1} is flagged as disabled skipping.", project.Id, project.Code));
                        continue;
                    }

                    projects.Add(project);
                }

                var entry = new MailboxEntry
                {
                    Title = mailHeader.Subject.Trim(),
                    From = messageFrom,
                    ProjectMailbox = pmbox,
                    Date = mailHeader.Date,
                    Project = project,
                    Content = "Email Body could not be parsed."
                };

                var mailbody = Mail_Message.ParseFromByte(message.MessageToByte());

                bool isHtml;
                List<MIME_Entity> attachments = null;
                string content = GetMessageContent(mailbody, project, out isHtml, ref attachments);

                entry.Content = content;
                entry.IsHtml = isHtml;
                foreach (var attachment in attachments)
                {
                    entry.MailAttachments.Add(attachment);
                }

                //save this message
                Issue issue = SaveMailboxEntry(entry);

                //send notifications for the new issue
                SendNotifications(issue);

                // add the entry if the save did not throw any exceptions
                result.MailboxEntries.Add(entry);

                processed = true;
            }

            return processed;
        }
Exemple #5
0
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if(m_State == AsyncOP_State.Disposed){
                    return;
                }
                SetState(AsyncOP_State.Disposed);
                
                m_pException  = null;
                m_pOwner      = null;
                m_pPop3Client = null;
                m_pStream     = null;

                this.CompletedAsync = null;
            }
Exemple #6
0
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner POP3 client message.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(POP3_ClientMessage owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner      = owner;
                m_pPop3Client = owner.m_Pop3Client;

                SetState(AsyncOP_State.Active);

                try{
                    /* RFC 1939 5. RETR
                         Arguments:
                             a message-number (required) which may NOT refer to a
                             message marked as deleted

                         Restrictions:
                             may only be given in the TRANSACTION state

                         Discussion:
                             If the POP3 server issues a positive response, then the
                             response given is multi-line.  After the initial +OK, the
                             POP3 server sends the message corresponding to the given
                             message-number, being careful to byte-stuff the termination
                             character (as with all multi-line responses).

                         Possible Responses:
                             +OK message follows
                             -ERR no such message

                         Examples:
                             C: RETR 1
                             S: +OK 120 octets
                             S: <the POP3 server sends the entire message here>
                             S: .
			        */

                    byte[] buffer = Encoding.UTF8.GetBytes("RETR " + owner.SequenceNumber.ToString() + "\r\n");

                    // Log
                    m_pPop3Client.LogAddWrite(buffer.Length,"RETR " + owner.SequenceNumber.ToString());

                    // Start command sending.
                    m_pPop3Client.TcpStream.BeginWrite(buffer,0,buffer.Length,this.RetrCommandSendingCompleted,null);
                }
                catch(Exception x){
                    m_pException = x;
                    m_pPop3Client.LogAddException("Exception: " + x.Message,x);
                    SetState(AsyncOP_State.Completed);
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }
Exemple #7
0
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner POP3 client message.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(POP3_ClientMessage owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner      = owner;
                m_pPop3Client = owner.m_Pop3Client;

                SetState(AsyncOP_State.Active);

                try{
                    /* RFC 1939 7. TOP
                         Arguments:
                             a message-number (required) which may NOT refer to to a
                             message marked as deleted, and a non-negative number
                             of lines (required)

                         Restrictions:
                             may only be given in the TRANSACTION state

                         Discussion:
                             If the POP3 server issues a positive response, then the
                             response given is multi-line.  After the initial +OK, the
                             POP3 server sends the headers of the message, the blank
                             line separating the headers from the body, and then the
                             number of lines of the indicated message's body, being
                             careful to byte-stuff the termination character (as with
                             all multi-line responses).

                             Note that if the number of lines requested by the POP3
                             client is greater than than the number of lines in the
                             body, then the POP3 server sends the entire message.

                         Possible Responses:
                             +OK top of message follows
                             -ERR no such message

                         Examples:
                             C: TOP 1 10
                             S: +OK
                             S: <the POP3 server sends the headers of the
                                message, a blank line, and the first 10 lines
                                of the body of the message>
                             S: .
                                ...
                             C: TOP 100 3
                             S: -ERR no such message
			        */

                    byte[] buffer = Encoding.UTF8.GetBytes("TOP " + owner.SequenceNumber.ToString()+ " " + m_LineCount.ToString() + "\r\n");

                    // Log
                    m_pPop3Client.LogAddWrite(buffer.Length,"TOP " + owner.SequenceNumber.ToString()+ " " + m_LineCount.ToString());

                    // Start command sending.
                    m_pPop3Client.TcpStream.BeginWrite(buffer,0,buffer.Length,this.TopCommandSendingCompleted,null);
                }
                catch(Exception x){
                    m_pException = x;
                    m_pPop3Client.LogAddException("Exception: " + x.Message,x);
                    SetState(AsyncOP_State.Completed);
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }