예제 #1
0
        /// <summary>
        /// Gets the name of the tab.
        /// </summary>
        /// <param name="tabName"></param>
        /// <param name="tabValue"></param>
        /// <returns></returns>
        private string GetTabName(string tabName, string tabValue)
        {
            switch (tabValue.ToLower())
            {
            case "tabcomments":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : IssueCommentManager.GetByIssueId(IssueId).Count));

            case "tabhistory":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : IssueHistoryManager.GetByIssueId(IssueId).Count));

            case "tabattachments":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : IssueAttachmentManager.GetByIssueId(IssueId).Count));

            case "tabnotifications":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : IssueNotificationManager.GetByIssueId(IssueId).Count));

            case "tabrelatedissues":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : RelatedIssueManager.GetRelatedIssues(IssueId).Count));

            case "tabparentissues":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : RelatedIssueManager.GetParentIssues(IssueId).Count));

            case "tabsubissues":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : RelatedIssueManager.GetChildIssues(IssueId).Count));

            case "tabrevisions":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : IssueRevisionManager.GetByIssueId(IssueId).Count));

            case "tabtimetracking":
                return(string.Format("{0} ({1})", tabName, IssueId == 0 ? 0 : IssueWorkReportManager.GetByIssueId(IssueId).Count));

            default:
                return(tabName);
            }
        }
예제 #2
0
        /// <summary>
        /// Handles the ItemDataBound event of the IssuesCommentListRepeater control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.RepeaterItemEventArgs"/> instance containing the event data.</param>
        protected void IssuesCommentListRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
            {
                return;
            }

            var lblcomm = ((Label)e.Item.FindControl("lblComment"));
            var ic      = (IssueComment)e.Item.DataItem;

            // Prevent XSS
            lblcomm.Text = Server.HtmlEncode(IssueCommentManager.GetShortTextComment(ic.Comment));
        }
예제 #3
0
        /// <summary>
        /// Gets the name of the tab.
        /// </summary>
        /// <param name="tabName"></param>
        /// <param name="tabValue"></param>
        /// <returns></returns>
        private string GetTabName(string tabName, string tabValue)
        {
            int cnt;

            switch (tabValue.ToLower())
            {
            case "tabcomments":
                cnt = IssueId == 0 ? 0 : IssueCommentManager.GetByIssueId(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "bold"));

            case "tabhistory":
                cnt = IssueId == 0 ? 0 : IssueHistoryManager.GetByIssueId(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "normal"));

            case "tabattachments":
                cnt = IssueId == 0 ? 0 : IssueAttachmentManager.GetByIssueId(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "bold"));

            case "tabnotifications":
                cnt = IssueId == 0 ? 0 : IssueNotificationManager.GetByIssueId(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "normal"));

            case "tabrelatedissues":
                cnt = IssueId == 0 ? 0 : RelatedIssueManager.GetRelatedIssues(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "bold"));

            case "tabparentissues":
                cnt = IssueId == 0 ? 0 : RelatedIssueManager.GetParentIssues(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "bold"));

            case "tabsubissues":
                cnt = IssueId == 0 ? 0 : RelatedIssueManager.GetChildIssues(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "bold"));

            case "tabrevisions":
                cnt = IssueId == 0 ? 0 : IssueRevisionManager.GetByIssueId(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "normal"));

            case "tabtimetracking":
                cnt = IssueId == 0 ? 0 : IssueWorkReportManager.GetByIssueId(IssueId).Count;
                return(string.Format("<span class='{2}'>{0} ({1})</span>", tabName, cnt, cnt == 0 ? "normal" : "normal"));

            default:
                return(tabName);
            }
        }
예제 #4
0
        /// <summary>
        /// Binds the comments.
        /// </summary>
        private void BindComments()
        {
            IList comments = IssueCommentManager.GetByIssueId(IssueId);

            if (comments.Count == 0)
            {
                lblComments.Text    = GetLocalResourceObject("NoComments").ToString();
                lblComments.Visible = true;
                rptComments.Visible = false;
            }
            else
            {
                _issueOwnerUserId   = IssueManager.GetById(IssueId).OwnerUserId;
                lblComments.Visible = false;

                rptComments.DataSource = comments;
                rptComments.DataBind();
                rptComments.Visible = true;
            }
        }
예제 #5
0
        /// <summary>
        /// Handles the Click event of the cmdAddComment control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void CmdAddCommentClick(object sender, EventArgs e)
        {
            if (CommentHtmlEditor.Text.Trim().Length == 0)
            {
                return;
            }

            var comment = new IssueComment
            {
                IssueId         = IssueId,
                Comment         = CommentHtmlEditor.Text.Trim(),
                CreatorUserName = Security.GetUserName(),
                DateCreated     = DateTime.Now
            };

            var result = IssueCommentManager.SaveOrUpdate(comment);

            if (result)
            {
                //add history record
                var history = new IssueHistory
                {
                    IssueId                 = IssueId,
                    CreatedUserName         = Security.GetUserName(),
                    DateChanged             = DateTime.Now,
                    FieldChanged            = ResourceStrings.GetGlobalResource(GlobalResources.SharedResources, "Comment", "Comment"),
                    OldValue                = string.Empty,
                    NewValue                = ResourceStrings.GetGlobalResource(GlobalResources.SharedResources, "Added", "Added"),
                    TriggerLastUpdateChange = true
                };

                IssueHistoryManager.SaveOrUpdate(history);
            }

            CommentHtmlEditor.Text = String.Empty;
            BindComments();
        }
예제 #6
0
        /// <summary>
        /// Performs the issue search and populates mainIssues and mainComment.
        /// </summary>
        /// <param name="searchProjects">A List of projects to search through.</param>
        private void PerformIssueSearch(IEnumerable <Project> searchProjects)
        {
            var foundComments = new List <IssueComment>();
            var issueComments = new List <IssueComment>();

            // Our search strings on normal and "like" comparators
            // Note: these are deliberately not trimmed!
            // to the users, "test" might be different from "test "
            var strSearch     = txtSearch.Text;
            var strLike       = "%" + strSearch + "%";
            var strHtmlSearch = Server.HtmlEncode(strSearch);
            var strHtmlLike   = "%" + strHtmlSearch + "%";

            // if the two strings are equal srchHtmlcode is false
            // If they are not equal, then I need to search for the HTML encoded
            // variants later on.
            var srchHtmlcode = strHtmlSearch != strSearch;

            var srchComments = chkComments.Checked;

            // Sort the projects using LINQ
            foreach (var p in searchProjects)
            {
                // now search each project with wildcard parameters
                // (except for the search string)

                // ---------------------------------------------------------------
                // Normal Search
                //
                // Searches Description, Issue Title using a LIKE query
                // If you are searching username it adds the LastUpdateUsername,
                // AssignedUsername, CreatorUserName, OwnerUserName to the list.
                //
                // ---------------------------------------------------------------

                var queryClauses = new List <QueryClause>();

                // filter out disabled issues
                queryClauses.Add(new QueryClause("AND", "iv.[Disabled]", "=", "0", SqlDbType.Int));

                // if the user wants to exclude closed issues then filter the closed flag otherwise don't bother
                if (chkExcludeClosedIssues.Checked)
                {
                    queryClauses.Add(new QueryClause("AND", "iv.[IsClosed]", "=", "0", SqlDbType.Int));
                }

                queryClauses.Add(new QueryClause("AND (", "1", "=", "2", SqlDbType.NVarChar));
                queryClauses.Add(new QueryClause("OR", "iv.[IssueId]", "LIKE", strLike, SqlDbType.NVarChar));

                if (chkSearchTitle.Checked || chkSearchDesc.Checked)
                {
                    if (chkSearchTitle.Checked)
                    {
                        queryClauses.Add(new QueryClause("OR", "iv.[IssueTitle]", "LIKE", strLike, SqlDbType.NVarChar));
                        if (srchHtmlcode)
                        {
                            queryClauses.Add(new QueryClause("OR", "iv.[IssueTitle]", "LIKE", strHtmlLike, SqlDbType.NVarChar));
                        }
                    }

                    if (chkSearchDesc.Checked)
                    {
                        queryClauses.Add(new QueryClause("OR", "iv.[IssueDescription]", "LIKE", strLike, SqlDbType.NVarChar));
                        if (srchHtmlcode)
                        {
                            queryClauses.Add(new QueryClause("OR", "iv.[IssueDescription]", "LIKE", strHtmlLike, SqlDbType.NVarChar));
                        }
                    }
                }

                queryClauses.Add(new QueryClause(")", "", "", "", SqlDbType.NVarChar));

                // Use the new Generic way to search with those QueryClauses
                var issues = IssueManager.PerformQuery(queryClauses, null, p.Id);

                queryClauses.Clear();

                _mainIssues.AddRange(issues);

                // ---------------------------------------------------------------
                // Search Comments
                //
                // ---------------------------------------------------------------

                if (!srchComments)
                {
                    continue;
                }

                issues.Clear();
                issueComments.Clear();
                foundComments.Clear();

                queryClauses.Add(new QueryClause("AND", "iv.[Disabled]", "=", "0", SqlDbType.Int));

                // if the user wants to exclude closed issues then filter the closed flag otherwise don't bother
                // stuff the criteria into the first spot because we have an open nested criteria going on
                if (chkExcludeClosedIssues.Checked)
                {
                    queryClauses.Insert(0, new QueryClause("AND", "iv.[IsClosed]", "=", "0", SqlDbType.Int));
                }

                // Get ALL issues
                issues = IssueManager.PerformQuery(queryClauses, null, p.Id);

                // to the private check on all issues
                issues = IssueManager.StripPrivateIssuesForRequestor(issues, Security.GetUserName()).ToList();

                foreach (var iss in issues)
                {
                    // New Way
                    // Using the Generic Interface
                    var qryComment = new List <QueryClause>
                    {
                        new QueryClause("AND (", "Comment", "LIKE", strLike, SqlDbType.NVarChar)
                    };
                    if (srchHtmlcode)
                    {
                        qryComment.Add(new QueryClause("OR", "Comment", "LIKE", strHtmlLike, SqlDbType.NVarChar));
                    }

                    // close parenthesis
                    qryComment.Add(new QueryClause(")", "", "", "", SqlDbType.NVarChar));

                    issueComments = IssueCommentManager.PerformQuery(iss.Id, qryComment);

                    // Did we find anything?
                    if (issueComments.Count <= 0)
                    {
                        continue;
                    }

                    _mainComments.AddRange(issueComments);
                    _mainIssues.Add(iss);
                    // make sure we record the parent issue of the comment(s)
                }
            }

            // ---------------------------------------------------------------
            // Clean up duplicates and sort
            //
            // mainIssues and mainComments
            // Sorry for the horrible variable names
            //
            // ---------------------------------------------------------------


            var tmpIss = (from iss1 in _mainIssues
                          orderby iss1.ProjectId, iss1.Id descending
                          select iss1).Distinct(new DistinctIssueComparer());


            var tmpIssues1 = new List <Issue>();

            tmpIssues1.AddRange(tmpIss);
            _mainIssues.Clear();
            _mainIssues.AddRange(tmpIssues1);

            // to the private check on all issues
            _mainIssues = IssueManager.StripPrivateIssuesForRequestor(_mainIssues, Security.GetUserName()).ToList();

            // mainIssues list should be pure now
            var tmpComm = (from comm in _mainComments
                           orderby comm.IssueId, comm.Id
                           select comm)
                          .Distinct();

            var tmpComm1 = new List <IssueComment>();

            tmpComm1.AddRange(tmpComm);
            _mainComments.Clear();
            _mainComments.AddRange(tmpComm1);
        }
예제 #7
0
        /// <summary>
        /// Handles the ItemCommand event of the rptComments control.
        /// </summary>
        /// <param name="source">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.RepeaterCommandEventArgs"/> instance containing the event data.</param>
        protected void RptCommentsItemCommand(object source, RepeaterCommandEventArgs e)
        {
            var pnlEditComment = e.Item.FindControl("pnlEditComment") as Panel;
            var pnlComment     = e.Item.FindControl("pnlComment") as Panel;

            if (pnlEditComment == null)
            {
                return;
            }
            if (pnlComment == null)
            {
                return;
            }

            BugNET.UserControls.HtmlEditor editor;
            HiddenField  commentNumber;
            IssueComment comment;

            switch (e.CommandName)
            {
            case "Save":
                editor = pnlEditComment.FindControl("EditCommentHtmlEditor") as BugNET.UserControls.HtmlEditor;
                if (editor != null)
                {
                    if (editor.Text.Trim().Length == 0)
                    {
                        return;
                    }

                    commentNumber = (HiddenField)pnlEditComment.FindControl("commentNumber");
                    var commentId = Convert.ToInt32(commentNumber.Value);

                    comment         = IssueCommentManager.GetById(Convert.ToInt32(commentId));
                    comment.Comment = editor.Text.Trim();
                    IssueCommentManager.SaveOrUpdate(comment);

                    editor.Text         = String.Empty;
                    commentNumber.Value = String.Empty;
                }

                pnlEditComment.Visible = false;
                pnlComment.Visible     = true;
                pnlAddComment.Visible  = true;

                BindComments();
                break;

            case "Cancel":
                pnlEditComment.Visible = false;
                pnlComment.Visible     = true;
                pnlAddComment.Visible  = true;
                BindComments();
                break;

            case "Delete":
                IssueCommentManager.Delete(Convert.ToInt32(e.CommandArgument));
                BindComments();
                break;

            case "Edit":
                comment = IssueCommentManager.GetById(Convert.ToInt32(e.CommandArgument));

                // Show the edit comment panel for the comment
                pnlAddComment.Visible  = false;
                pnlEditComment.Visible = true;
                pnlComment.Visible     = false;

                // Insert the existing comment text in the edit control.
                editor = pnlEditComment.FindControl("EditCommentHtmlEditor") as BugNET.UserControls.HtmlEditor;
                if (editor != null)
                {
                    editor.Text = comment.Comment;
                }

                // Save the comment ID for further editting.
                commentNumber = (HiddenField)e.Item.FindControl("commentNumber");
                if (commentNumber != null)
                {
                    commentNumber.Value = (string)e.CommandArgument;
                }
                break;
            }
        }
예제 #8
0
        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);
        }