2016-07-15 19:36:39 +03:00
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"fmt"
"html/template"
"path"
"gopkg.in/gomail.v2"
"gopkg.in/macaron.v1"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/mailer"
"code.gitea.io/gitea/modules/markdown"
"code.gitea.io/gitea/modules/setting"
2016-07-15 19:36:39 +03:00
)
const (
2016-11-25 11:11:12 +03:00
mailAuthActivate base . TplName = "auth/activate"
mailAuthActivateEmail base . TplName = "auth/activate_email"
mailAuthResetPassword base . TplName = "auth/reset_passwd"
mailAuthRegisterNotify base . TplName = "auth/register_notify"
2016-07-15 19:36:39 +03:00
2016-11-25 11:11:12 +03:00
mailIssueComment base . TplName = "issue/comment"
mailIssueMention base . TplName = "issue/mention"
2016-07-15 19:36:39 +03:00
2016-11-25 11:11:12 +03:00
mailNotifyCollaborator base . TplName = "notify/collaborator"
2016-07-15 19:36:39 +03:00
)
2016-11-25 11:11:12 +03:00
type mailRenderInterface interface {
2016-07-15 19:36:39 +03:00
HTMLString ( string , interface { } , ... macaron . HTMLOptions ) ( string , error )
}
2016-11-25 11:11:12 +03:00
var mailRender mailRenderInterface
2016-07-15 19:36:39 +03:00
2016-11-25 11:11:12 +03:00
// InitMailRender initializes the macaron mail renderer
2016-07-15 19:36:39 +03:00
func InitMailRender ( dir , appendDir string , funcMap [ ] template . FuncMap ) {
opt := & macaron . RenderOptions {
Directory : dir ,
AppendDirectories : [ ] string { appendDir } ,
Funcs : funcMap ,
Extensions : [ ] string { ".tmpl" , ".html" } ,
}
ts := macaron . NewTemplateSet ( )
ts . Set ( macaron . DEFAULT_TPL_SET_NAME , opt )
mailRender = & macaron . TplRender {
TemplateSet : ts ,
Opt : opt ,
}
}
2016-11-25 11:11:12 +03:00
// SendTestMail sends a test mail
2016-07-15 19:36:39 +03:00
func SendTestMail ( email string ) error {
return gomail . Send ( & mailer . Sender { } , mailer . NewMessage ( [ ] string { email } , "Gogs Test Email!" , "Gogs Test Email!" ) . Message )
}
2016-11-25 11:11:12 +03:00
// SendUserMail sends a mail to the user
2016-07-15 19:36:39 +03:00
func SendUserMail ( c * macaron . Context , u * User , tpl base . TplName , code , subject , info string ) {
data := map [ string ] interface { } {
"Username" : u . DisplayName ( ) ,
"ActiveCodeLives" : setting . Service . ActiveCodeLives / 60 ,
"ResetPwdCodeLives" : setting . Service . ResetPwdCodeLives / 60 ,
"Code" : code ,
}
body , err := mailRender . HTMLString ( string ( tpl ) , data )
if err != nil {
log . Error ( 3 , "HTMLString: %v" , err )
return
}
msg := mailer . NewMessage ( [ ] string { u . Email } , subject , body )
2016-07-23 20:08:22 +03:00
msg . Info = fmt . Sprintf ( "UID: %d, %s" , u . ID , info )
2016-07-15 19:36:39 +03:00
mailer . SendAsync ( msg )
}
2016-11-25 11:11:12 +03:00
// SendActivateAccountMail sends an activation mail to the user
2016-07-15 19:36:39 +03:00
func SendActivateAccountMail ( c * macaron . Context , u * User ) {
2016-11-25 11:11:12 +03:00
SendUserMail ( c , u , mailAuthActivate , u . GenerateActivateCode ( ) , c . Tr ( "mail.activate_account" ) , "activate account" )
2016-07-15 19:36:39 +03:00
}
2016-11-25 11:11:12 +03:00
// SendResetPasswordMail sends a password reset mail to the user
2016-07-15 19:36:39 +03:00
func SendResetPasswordMail ( c * macaron . Context , u * User ) {
2016-11-25 11:11:12 +03:00
SendUserMail ( c , u , mailAuthResetPassword , u . GenerateActivateCode ( ) , c . Tr ( "mail.reset_password" ) , "reset password" )
2016-07-15 19:36:39 +03:00
}
2016-11-25 11:11:12 +03:00
// SendActivateEmailMail sends confirmation email.
2016-07-15 19:36:39 +03:00
func SendActivateEmailMail ( c * macaron . Context , u * User , email * EmailAddress ) {
data := map [ string ] interface { } {
"Username" : u . DisplayName ( ) ,
"ActiveCodeLives" : setting . Service . ActiveCodeLives / 60 ,
"Code" : u . GenerateEmailActivateCode ( email . Email ) ,
"Email" : email . Email ,
}
2016-11-25 11:11:12 +03:00
body , err := mailRender . HTMLString ( string ( mailAuthActivateEmail ) , data )
2016-07-15 19:36:39 +03:00
if err != nil {
log . Error ( 3 , "HTMLString: %v" , err )
return
}
msg := mailer . NewMessage ( [ ] string { email . Email } , c . Tr ( "mail.activate_email" ) , body )
2016-07-23 20:08:22 +03:00
msg . Info = fmt . Sprintf ( "UID: %d, activate email" , u . ID )
2016-07-15 19:36:39 +03:00
mailer . SendAsync ( msg )
}
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
func SendRegisterNotifyMail ( c * macaron . Context , u * User ) {
data := map [ string ] interface { } {
"Username" : u . DisplayName ( ) ,
}
2016-11-25 11:11:12 +03:00
body , err := mailRender . HTMLString ( string ( mailAuthRegisterNotify ) , data )
2016-07-15 19:36:39 +03:00
if err != nil {
log . Error ( 3 , "HTMLString: %v" , err )
return
}
msg := mailer . NewMessage ( [ ] string { u . Email } , c . Tr ( "mail.register_notify" ) , body )
2016-07-23 20:08:22 +03:00
msg . Info = fmt . Sprintf ( "UID: %d, registration notify" , u . ID )
2016-07-15 19:36:39 +03:00
mailer . SendAsync ( msg )
}
// SendCollaboratorMail sends mail notification to new collaborator.
func SendCollaboratorMail ( u , doer * User , repo * Repository ) {
repoName := path . Join ( repo . Owner . Name , repo . Name )
subject := fmt . Sprintf ( "%s added you to %s" , doer . DisplayName ( ) , repoName )
data := map [ string ] interface { } {
"Subject" : subject ,
"RepoName" : repoName ,
2016-08-16 20:19:09 +03:00
"Link" : repo . HTMLURL ( ) ,
2016-07-15 19:36:39 +03:00
}
2016-11-25 11:11:12 +03:00
body , err := mailRender . HTMLString ( string ( mailNotifyCollaborator ) , data )
2016-07-15 19:36:39 +03:00
if err != nil {
log . Error ( 3 , "HTMLString: %v" , err )
return
}
msg := mailer . NewMessage ( [ ] string { u . Email } , subject , body )
2016-07-23 20:08:22 +03:00
msg . Info = fmt . Sprintf ( "UID: %d, add collaborator" , u . ID )
2016-07-15 19:36:39 +03:00
mailer . SendAsync ( msg )
}
func composeTplData ( subject , body , link string ) map [ string ] interface { } {
data := make ( map [ string ] interface { } , 10 )
data [ "Subject" ] = subject
data [ "Body" ] = body
data [ "Link" ] = link
return data
}
func composeIssueMessage ( issue * Issue , doer * User , tplName base . TplName , tos [ ] string , info string ) * mailer . Message {
2016-11-25 11:11:12 +03:00
subject := issue . mailSubject ( )
2016-08-16 20:19:09 +03:00
body := string ( markdown . RenderSpecialLink ( [ ] byte ( issue . Content ) , issue . Repo . HTMLURL ( ) , issue . Repo . ComposeMetas ( ) ) )
data := composeTplData ( subject , body , issue . HTMLURL ( ) )
2016-07-15 19:36:39 +03:00
data [ "Doer" ] = doer
content , err := mailRender . HTMLString ( string ( tplName ) , data )
if err != nil {
log . Error ( 3 , "HTMLString (%s): %v" , tplName , err )
}
2016-09-07 12:19:44 +03:00
msg := mailer . NewMessageFrom ( tos , fmt . Sprintf ( ` "%s" <%s> ` , doer . DisplayName ( ) , setting . MailService . FromEmail ) , subject , content )
2016-07-15 19:36:39 +03:00
msg . Info = fmt . Sprintf ( "Subject: %s, %s" , subject , info )
return msg
}
// SendIssueCommentMail composes and sends issue comment emails to target receivers.
func SendIssueCommentMail ( issue * Issue , doer * User , tos [ ] string ) {
if len ( tos ) == 0 {
return
}
2016-11-25 11:11:12 +03:00
mailer . SendAsync ( composeIssueMessage ( issue , doer , mailIssueComment , tos , "issue comment" ) )
2016-07-15 19:36:39 +03:00
}
// SendIssueMentionMail composes and sends issue mention emails to target receivers.
func SendIssueMentionMail ( issue * Issue , doer * User , tos [ ] string ) {
if len ( tos ) == 0 {
return
}
2016-11-25 11:11:12 +03:00
mailer . SendAsync ( composeIssueMessage ( issue , doer , mailIssueMention , tos , "issue mention" ) )
2016-07-15 19:36:39 +03:00
}