2014-03-19 15:21:23 +04:00
// Copyright 2014 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 mailer
import (
2014-03-19 18:46:48 +04:00
"encoding/hex"
2014-03-26 05:37:18 +04:00
"errors"
2014-03-19 18:46:48 +04:00
"fmt"
2014-05-05 12:27:28 +04:00
"path"
2014-03-19 18:46:48 +04:00
2014-03-19 15:21:23 +04:00
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
2014-03-19 18:46:48 +04:00
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
2014-05-26 04:11:25 +04:00
"github.com/gogits/gogs/modules/setting"
2014-03-19 15:21:23 +04:00
)
2014-06-22 21:14:03 +04:00
const (
AUTH_ACTIVE base . TplName = "mail/auth/active"
AUTH_REGISTER_SUCCESS base . TplName = "mail/auth/register_success"
AUTH_RESET_PASSWORD base . TplName = "mail/auth/reset_passwd"
NOTIFY_COLLABORATOR base . TplName = "mail/notify/collaborator"
NOTIFY_MENTION base . TplName = "mail/notify/mention"
)
2014-03-19 16:27:27 +04:00
// Create New mail message use MailFrom and MailUser
2014-03-26 05:37:18 +04:00
func NewMailMessageFrom ( To [ ] string , from , subject , body string ) Message {
msg := NewHtmlMessage ( To , from , subject , body )
2014-05-26 04:11:25 +04:00
msg . User = setting . MailService . User
2014-03-19 16:27:27 +04:00
return msg
}
2014-03-26 05:37:18 +04:00
// Create New mail message use MailFrom and MailUser
func NewMailMessage ( To [ ] string , subject , body string ) Message {
2014-06-03 20:51:53 +04:00
return NewMailMessageFrom ( To , setting . MailService . From , subject , body )
2014-03-26 05:37:18 +04:00
}
2014-06-06 06:07:35 +04:00
func GetMailTmplData ( u * models . User ) map [ interface { } ] interface { } {
2014-03-19 15:21:23 +04:00
data := make ( map [ interface { } ] interface { } , 10 )
2014-05-26 04:11:25 +04:00
data [ "AppName" ] = setting . AppName
data [ "AppVer" ] = setting . AppVer
data [ "AppUrl" ] = setting . AppUrl
data [ "AppLogo" ] = setting . AppLogo
data [ "ActiveCodeLives" ] = setting . Service . ActiveCodeLives / 60
data [ "ResetPwdCodeLives" ] = setting . Service . ResetPwdCodeLives / 60
2014-06-06 06:07:35 +04:00
if u != nil {
data [ "User" ] = u
2014-03-19 15:21:23 +04:00
}
return data
}
2014-03-19 18:46:48 +04:00
// create a time limit code for user active
2014-06-06 06:07:35 +04:00
func CreateUserActiveCode ( u * models . User , startInf interface { } ) string {
2014-05-26 04:11:25 +04:00
minutes := setting . Service . ActiveCodeLives
2014-06-06 06:07:35 +04:00
data := base . ToStr ( u . Id ) + u . Email + u . LowerName + u . Passwd + u . Rands
2014-03-19 20:50:44 +04:00
code := base . CreateTimeLimitCode ( data , minutes , startInf )
2014-03-19 18:46:48 +04:00
// add tail hex username
2014-06-06 06:07:35 +04:00
code += hex . EncodeToString ( [ ] byte ( u . LowerName ) )
2014-03-19 18:46:48 +04:00
return code
}
// Send user register mail with active code
2014-06-06 06:07:35 +04:00
func SendRegisterMail ( r * middleware . Render , u * models . User ) {
code := CreateUserActiveCode ( u , nil )
2014-03-19 18:46:48 +04:00
subject := "Register success, Welcome"
2014-06-06 06:07:35 +04:00
data := GetMailTmplData ( u )
2014-03-19 18:46:48 +04:00
data [ "Code" ] = code
2014-06-22 21:14:03 +04:00
body , err := r . HTMLString ( string ( AUTH_REGISTER_SUCCESS ) , data )
2014-03-19 18:46:48 +04:00
if err != nil {
log . Error ( "mail.SendRegisterMail(fail to render): %v" , err )
return
}
2014-06-06 06:07:35 +04:00
msg := NewMailMessage ( [ ] string { u . Email } , subject , body )
msg . Info = fmt . Sprintf ( "UID: %d, send register mail" , u . Id )
2014-03-19 18:46:48 +04:00
2014-03-20 05:05:48 +04:00
SendAsync ( & msg )
2014-03-19 18:46:48 +04:00
}
// Send email verify active email.
2014-06-06 06:07:35 +04:00
func SendActiveMail ( r * middleware . Render , u * models . User ) {
code := CreateUserActiveCode ( u , nil )
2014-03-19 18:46:48 +04:00
2014-03-19 20:50:44 +04:00
subject := "Verify your e-mail address"
2014-03-19 18:46:48 +04:00
2014-06-06 06:07:35 +04:00
data := GetMailTmplData ( u )
2014-03-19 18:46:48 +04:00
data [ "Code" ] = code
2014-06-22 21:14:03 +04:00
body , err := r . HTMLString ( string ( AUTH_ACTIVE ) , data )
2014-03-19 18:46:48 +04:00
if err != nil {
log . Error ( "mail.SendActiveMail(fail to render): %v" , err )
return
}
2014-06-06 06:07:35 +04:00
msg := NewMailMessage ( [ ] string { u . Email } , subject , body )
msg . Info = fmt . Sprintf ( "UID: %d, send active mail" , u . Id )
2014-04-05 20:32:34 +04:00
SendAsync ( & msg )
}
// Send reset password email.
2014-06-06 06:07:35 +04:00
func SendResetPasswdMail ( r * middleware . Render , u * models . User ) {
code := CreateUserActiveCode ( u , nil )
2014-04-05 20:32:34 +04:00
subject := "Reset your password"
2014-06-06 06:07:35 +04:00
data := GetMailTmplData ( u )
2014-04-05 20:32:34 +04:00
data [ "Code" ] = code
2014-06-22 21:14:03 +04:00
body , err := r . HTMLString ( string ( AUTH_RESET_PASSWORD ) , data )
2014-04-05 20:32:34 +04:00
if err != nil {
log . Error ( "mail.SendResetPasswdMail(fail to render): %v" , err )
return
}
2014-06-06 06:07:35 +04:00
msg := NewMailMessage ( [ ] string { u . Email } , subject , body )
msg . Info = fmt . Sprintf ( "UID: %d, send reset password email" , u . Id )
2014-03-19 18:46:48 +04:00
2014-03-20 05:05:48 +04:00
SendAsync ( & msg )
2014-03-19 18:46:48 +04:00
}
2014-03-26 05:37:18 +04:00
2014-04-07 20:56:40 +04:00
// SendIssueNotifyMail sends mail notification of all watchers of repository.
2014-06-06 06:07:35 +04:00
func SendIssueNotifyMail ( u , owner * models . User , repo * models . Repository , issue * models . Issue ) ( [ ] string , error ) {
2014-05-08 00:51:14 +04:00
ws , err := models . GetWatchers ( repo . Id )
2014-03-26 05:37:18 +04:00
if err != nil {
2014-05-08 00:51:14 +04:00
return nil , errors . New ( "mail.NotifyWatchers(GetWatchers): " + err . Error ( ) )
2014-03-26 05:37:18 +04:00
}
2014-05-08 00:51:14 +04:00
tos := make ( [ ] string , 0 , len ( ws ) )
for i := range ws {
2014-05-08 01:23:02 +04:00
uid := ws [ i ] . UserId
2014-06-06 06:07:35 +04:00
if u . Id == uid {
2014-03-26 05:37:18 +04:00
continue
}
u , err := models . GetUserById ( uid )
if err != nil {
2014-05-08 00:51:14 +04:00
return nil , errors . New ( "mail.NotifyWatchers(GetUserById): " + err . Error ( ) )
2014-03-26 05:37:18 +04:00
}
tos = append ( tos , u . Email )
}
if len ( tos ) == 0 {
2014-04-07 20:56:40 +04:00
return tos , nil
2014-03-26 05:37:18 +04:00
}
2014-05-05 12:27:28 +04:00
subject := fmt . Sprintf ( "[%s] %s(#%d)" , repo . Name , issue . Name , issue . Index )
2014-04-02 18:38:30 +04:00
content := fmt . Sprintf ( "%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>." ,
2014-04-07 20:56:40 +04:00
base . RenderSpecialLink ( [ ] byte ( issue . Content ) , owner . Name + "/" + repo . Name ) ,
2014-05-26 04:11:25 +04:00
setting . AppUrl , owner . Name , repo . Name , issue . Index )
2014-06-06 06:07:35 +04:00
msg := NewMailMessageFrom ( tos , u . Email , subject , content )
2014-04-07 20:56:40 +04:00
msg . Info = fmt . Sprintf ( "Subject: %s, send issue notify emails" , subject )
SendAsync ( & msg )
return tos , nil
}
// SendIssueMentionMail sends mail notification for who are mentioned in issue.
2014-06-06 06:07:35 +04:00
func SendIssueMentionMail ( r * middleware . Render , u , owner * models . User ,
2014-05-05 12:27:28 +04:00
repo * models . Repository , issue * models . Issue , tos [ ] string ) error {
2014-04-07 20:56:40 +04:00
if len ( tos ) == 0 {
return nil
}
2014-05-05 12:27:28 +04:00
subject := fmt . Sprintf ( "[%s] %s(#%d)" , repo . Name , issue . Name , issue . Index )
data := GetMailTmplData ( nil )
data [ "IssueLink" ] = fmt . Sprintf ( "%s/%s/issues/%d" , owner . Name , repo . Name , issue . Index )
data [ "Subject" ] = subject
2014-06-22 21:14:03 +04:00
body , err := r . HTMLString ( string ( NOTIFY_MENTION ) , data )
2014-05-05 12:27:28 +04:00
if err != nil {
return fmt . Errorf ( "mail.SendIssueMentionMail(fail to render): %v" , err )
}
2014-06-06 06:07:35 +04:00
msg := NewMailMessageFrom ( tos , u . Email , subject , body )
2014-04-07 20:56:40 +04:00
msg . Info = fmt . Sprintf ( "Subject: %s, send issue mention emails" , subject )
2014-03-26 05:37:18 +04:00
SendAsync ( & msg )
return nil
}
2014-05-05 12:27:28 +04:00
// SendCollaboratorMail sends mail notification to new collaborator.
2014-06-06 06:07:35 +04:00
func SendCollaboratorMail ( r * middleware . Render , u , owner * models . User ,
2014-05-05 12:27:28 +04:00
repo * models . Repository ) error {
subject := fmt . Sprintf ( "%s added you to %s" , owner . Name , repo . Name )
data := GetMailTmplData ( nil )
data [ "RepoLink" ] = path . Join ( owner . Name , repo . Name )
data [ "Subject" ] = subject
2014-06-22 21:14:03 +04:00
body , err := r . HTMLString ( string ( NOTIFY_COLLABORATOR ) , data )
2014-05-05 12:27:28 +04:00
if err != nil {
return fmt . Errorf ( "mail.SendCollaboratorMail(fail to render): %v" , err )
}
2014-06-06 06:07:35 +04:00
msg := NewMailMessage ( [ ] string { u . Email } , subject , body )
msg . Info = fmt . Sprintf ( "UID: %d, send register mail" , u . Id )
2014-05-05 12:27:28 +04:00
SendAsync ( & msg )
return nil
}