diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index bfca858..061a747 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -164,7 +164,8 @@ post("/admin/system/sendmail", sendMailForm)(adminOnly { form => try { new Mailer(form.smtp).send(form.testAddress, - "Test message from GitBucket", "This is a test message from GitBucket.") + "Test message from GitBucket", "This is a test message from GitBucket.", + context.loginAccount.get) "Test mail has been sent to: " + form.testAddress diff --git a/src/main/scala/gitbucket/core/service/HandleCommentService.scala b/src/main/scala/gitbucket/core/service/HandleCommentService.scala index 22cfc88..cc5e219 100644 --- a/src/main/scala/gitbucket/core/service/HandleCommentService.scala +++ b/src/main/scala/gitbucket/core/service/HandleCommentService.scala @@ -17,76 +17,77 @@ */ def handleComment(issue: Issue, content: Option[String], repository: RepositoryService.RepositoryInfo, actionOpt: Option[String]) (implicit context: Context, s: Session) = { + context.loginAccount.flatMap { loginAccount => + defining(repository.owner, repository.name){ case (owner, name) => + val userName = loginAccount.userName - defining(repository.owner, repository.name){ case (owner, name) => - val userName = context.loginAccount.get.userName - - val (action, recordActivity) = actionOpt - .collect { - case "close" if(!issue.closed) => true -> - (Some("close") -> Some(if(issue.isPullRequest) recordClosePullRequestActivity _ else recordCloseIssueActivity _)) - case "reopen" if(issue.closed) => false -> - (Some("reopen") -> Some(recordReopenIssueActivity _)) - } - .map { case (closed, t) => - updateClosed(owner, name, issue.issueId, closed) - t - } - .getOrElse(None -> None) - - val commentId = (content, action) match { - case (None, None) => None - case (None, Some(action)) => Some(createComment(owner, name, userName, issue.issueId, action.capitalize, action)) - case (Some(content), _) => Some(createComment(owner, name, userName, issue.issueId, content, action.map(_+ "_comment").getOrElse("comment"))) - } - - // record comment activity if comment is entered - content foreach { - (if(issue.isPullRequest) recordCommentPullRequestActivity _ else recordCommentIssueActivity _) - (owner, name, userName, issue.issueId, _) - } - recordActivity foreach ( _ (owner, name, userName, issue.issueId, issue.title) ) - - // extract references and create refer comment - content.map { content => - createReferComment(owner, name, issue, content, context.loginAccount.get) - } - - // call web hooks - action match { - case None => commentId.map { commentIdSome => callIssueCommentWebHook(repository, issue, commentIdSome, context.loginAccount.get) } - case Some(act) => { - val webHookAction = act match { - case "open" => "opened" - case "reopen" => "reopened" - case "close" => "closed" - case _ => act + val (action, recordActivity) = actionOpt + .collect { + case "close" if(!issue.closed) => true -> + (Some("close") -> Some(if(issue.isPullRequest) recordClosePullRequestActivity _ else recordCloseIssueActivity _)) + case "reopen" if(issue.closed) => false -> + (Some("reopen") -> Some(recordReopenIssueActivity _)) } - if (issue.isPullRequest) { - callPullRequestWebHook(webHookAction, repository, issue.issueId, context.baseUrl, context.loginAccount.get) - } else { - callIssuesWebHook(webHookAction, repository, issue, context.baseUrl, context.loginAccount.get) + .map { case (closed, t) => + updateClosed(owner, name, issue.issueId, closed) + t } - } - } + .getOrElse(None -> None) - // notifications - Notifier() match { - case f => - content foreach { - f.toNotify(repository, issue, _){ - Notifier.msgComment(s"${context.baseUrl}/${owner}/${name}/${ - if(issue.isPullRequest) "pull" else "issues"}/${issue.issueId}#comment-${commentId.get}") + val commentId = (content, action) match { + case (None, None) => None + case (None, Some(action)) => Some(createComment(owner, name, userName, issue.issueId, action.capitalize, action)) + case (Some(content), _) => Some(createComment(owner, name, userName, issue.issueId, content, action.map(_+ "_comment").getOrElse("comment"))) + } + + // record comment activity if comment is entered + content foreach { + (if(issue.isPullRequest) recordCommentPullRequestActivity _ else recordCommentIssueActivity _) + (owner, name, userName, issue.issueId, _) + } + recordActivity foreach ( _ (owner, name, userName, issue.issueId, issue.title) ) + + // extract references and create refer comment + content.map { content => + createReferComment(owner, name, issue, content, loginAccount) + } + + // call web hooks + action match { + case None => commentId.map { commentIdSome => callIssueCommentWebHook(repository, issue, commentIdSome, loginAccount) } + case Some(act) => { + val webHookAction = act match { + case "open" => "opened" + case "reopen" => "reopened" + case "close" => "closed" + case _ => act + } + if (issue.isPullRequest) { + callPullRequestWebHook(webHookAction, repository, issue.issueId, context.baseUrl, loginAccount) + } else { + callIssuesWebHook(webHookAction, repository, issue, context.baseUrl, loginAccount) } } - action foreach { - f.toNotify(repository, issue, _){ - Notifier.msgStatus(s"${context.baseUrl}/${owner}/${name}/issues/${issue.issueId}") - } - } - } + } - commentId.map( issue -> _ ) + // notifications + Notifier() match { + case f => + content foreach { + f.toNotify(repository, issue, _){ + Notifier.msgComment(s"${context.baseUrl}/${owner}/${name}/${ + if(issue.isPullRequest) "pull" else "issues"}/${issue.issueId}#comment-${commentId.get}") + } + } + action foreach { + f.toNotify(repository, issue, _){ + Notifier.msgStatus(s"${context.baseUrl}/${owner}/${name}/issues/${issue.issueId}") + } + } + } + + commentId.map( issue -> _ ) + } } } diff --git a/src/main/scala/gitbucket/core/util/Notifier.scala b/src/main/scala/gitbucket/core/util/Notifier.scala index 438a4e1..000a5c5 100644 --- a/src/main/scala/gitbucket/core/util/Notifier.scala +++ b/src/main/scala/gitbucket/core/util/Notifier.scala @@ -1,7 +1,7 @@ package gitbucket.core.util -import gitbucket.core.model.{Session, Issue} -import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, SystemSettingsService} +import gitbucket.core.model.{Account, Issue, Session} +import gitbucket.core.service.{AccountService, IssuesService, RepositoryService, SystemSettingsService} import gitbucket.core.servlet.Database import gitbucket.core.view.Markdown @@ -9,16 +9,16 @@ import ExecutionContext.Implicits.global import org.apache.commons.mail.{DefaultAuthenticator, HtmlEmail} import org.slf4j.LoggerFactory - import gitbucket.core.controller.Context import SystemSettingsService.Smtp import ControlUtil.defining trait Notifier extends RepositoryService with AccountService with IssuesService { + def toNotify(r: RepositoryService.RepositoryInfo, issue: Issue, content: String) (msg: String => String)(implicit context: Context): Unit - protected def recipients(issue: Issue)(notify: String => Unit)(implicit session: Session, context: Context) = + protected def recipients(issue: Issue, loginAccount: Account)(notify: String => Unit)(implicit session: Session) = ( // individual repository's owner issue.userName :: @@ -31,9 +31,13 @@ getComments(issue.userName, issue.repositoryName, issue.issueId).map(_.commentedUserName) ) .distinct - .withFilter ( _ != context.loginAccount.get.userName ) // the operation in person is excluded - .foreach ( getAccountByUserName(_) filterNot (_.isGroupAccount) filterNot (LDAPUtil.isDummyMailAddress(_)) foreach (x => notify(x.mailAddress)) ) - + .withFilter ( _ != loginAccount.userName ) // the operation in person is excluded + .foreach ( + getAccountByUserName(_) + .filterNot (_.isGroupAccount) + .filterNot (LDAPUtil.isDummyMailAddress(_)) + .foreach (x => notify(x.mailAddress)) + ) } object Notifier { @@ -70,37 +74,38 @@ private val logger = LoggerFactory.getLogger(classOf[Mailer]) def toNotify(r: RepositoryService.RepositoryInfo, issue: Issue, content: String) - (msg: String => String)(implicit context: Context) = { - val database = Database() + (msg: String => String)(implicit context: Context): Unit = { + context.loginAccount.foreach { loginAccount => + val database = Database() - val f = Future { - database withSession { implicit session => - defining( - s"[${r.name}] ${issue.title} (#${issue.issueId})" -> - msg(Markdown.toHtml( - markdown = content, - repository = r, - enableWikiLink = false, - enableRefsLink = true, - enableAnchor = false, - enableLineBreaks = false - ))) { case (subject, msg) => - recipients(issue) { to => - send(to, subject, msg) - } + val f = Future { + database withSession { implicit session => + defining( + s"[${r.name}] ${issue.title} (#${issue.issueId})" -> + msg(Markdown.toHtml( + markdown = content, + repository = r, + enableWikiLink = false, + enableRefsLink = true, + enableAnchor = false, + enableLineBreaks = false + )) + ) { case (subject, msg) => + recipients(issue, loginAccount) { to => send(to, subject, msg, loginAccount) } + } } + "Notifications Successful." } - "Notifications Successful." - } - f onSuccess { - case s => logger.debug(s) - } - f onFailure { - case t => logger.error("Notifications Failed.", t) + f onSuccess { + case s => logger.debug(s) + } + f onFailure { + case t => logger.error("Notifications Failed.", t) + } } } - def send(to: String, subject: String, msg: String)(implicit context: Context): Unit = { + def send(to: String, subject: String, msg: String, loginAccount: Account): Unit = { val email = new HtmlEmail email.setHostName(smtp.host) email.setSmtpPort(smtp.port.get) @@ -114,8 +119,8 @@ } } smtp.fromAddress - .map (_ -> smtp.fromName.getOrElse(context.loginAccount.get.userName)) - .orElse (Some("notifications@gitbucket.com" -> context.loginAccount.get.userName)) + .map (_ -> smtp.fromName.getOrElse(loginAccount.userName)) + .orElse (Some("notifications@gitbucket.com" -> loginAccount.userName)) .foreach { case (address, name) => email.setFrom(address, name) }