aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/auth/mail.go11
-rw-r--r--modules/base/conf.go4
-rw-r--r--modules/base/tool.go55
-rw-r--r--modules/mailer/mail.go7
-rw-r--r--modules/mailer/mailer.go112
5 files changed, 180 insertions, 9 deletions
diff --git a/modules/auth/mail.go b/modules/auth/mail.go
index 6f6bf20a..cdfcce4f 100644
--- a/modules/auth/mail.go
+++ b/modules/auth/mail.go
@@ -16,7 +16,7 @@ import (
// create a time limit code for user active
func CreateUserActiveCode(user *models.User, startInf interface{}) string {
hours := base.Service.ActiveCodeLives / 60
- data := fmt.Sprintf("%d", user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
+ data := base.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
code := base.CreateTimeLimitCode(data, hours, startInf)
// add tail hex username
@@ -32,11 +32,10 @@ func SendRegisterMail(user *models.User) {
data := mailer.GetMailTmplData(user)
data["Code"] = code
body := base.RenderTemplate("mail/auth/register_success.html", data)
- _, _, _ = code, subject, body
- // msg := mailer.NewMailMessage([]string{user.Email}, subject, body)
- // msg.Info = fmt.Sprintf("UID: %d, send register mail", user.Id)
+ msg := mailer.NewMailMessage([]string{user.Email}, subject, body)
+ msg.Info = fmt.Sprintf("UID: %d, send register mail", user.Id)
- // // async send mail
- // mailer.SendAsync(msg)
+ // async send mail
+ mailer.SendAsync(msg)
}
diff --git a/modules/base/conf.go b/modules/base/conf.go
index ee5638ed..24ee1d7f 100644
--- a/modules/base/conf.go
+++ b/modules/base/conf.go
@@ -37,7 +37,7 @@ var (
)
var Service struct {
- RegisterEmailConfitm bool
+ RegisterEmailConfirm bool
ActiveCodeLives int
ResetPwdCodeLives int
}
@@ -138,7 +138,7 @@ func newRegisterService() {
log.Warn("Register Service: Mail Service is not enabled")
return
}
- Service.RegisterEmailConfitm = true
+ Service.RegisterEmailConfirm = true
log.Info("Register Service Enabled")
}
diff --git a/modules/base/tool.go b/modules/base/tool.go
index 2a989b37..fc3b4c45 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -13,6 +13,7 @@ import (
"encoding/json"
"fmt"
"math"
+ "strconv"
"strings"
"time"
)
@@ -59,13 +60,14 @@ func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string
// create sha1 encode string
sh := sha1.New()
- sh.Write([]byte(data + SecretKey + startStr + endStr + fmt.Sprintf("%d", minutes)))
+ sh.Write([]byte(data + SecretKey + startStr + endStr + ToStr(minutes)))
encoded := hex.EncodeToString(sh.Sum(nil))
code := fmt.Sprintf("%s%06d%s", startStr, minutes, encoded)
return code
}
+// TODO:
func RenderTemplate(TplNames string, Data map[interface{}]interface{}) string {
// if beego.RunMode == "dev" {
// beego.BuildTemplate(beego.ViewsPath)
@@ -300,6 +302,57 @@ func DateFormat(t time.Time, format string) string {
return t.Format(format)
}
+type argInt []int
+
+func (a argInt) Get(i int, args ...int) (r int) {
+ if i >= 0 && i < len(a) {
+ r = a[i]
+ }
+ if len(args) > 0 {
+ r = args[0]
+ }
+ return
+}
+
+// convert any type to string
+func ToStr(value interface{}, args ...int) (s string) {
+ switch v := value.(type) {
+ case bool:
+ s = strconv.FormatBool(v)
+ case float32:
+ s = strconv.FormatFloat(float64(v), 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 32))
+ case float64:
+ s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64))
+ case int:
+ s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
+ case int8:
+ s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
+ case int16:
+ s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
+ case int32:
+ s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
+ case int64:
+ s = strconv.FormatInt(v, argInt(args).Get(0, 10))
+ case uint:
+ s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
+ case uint8:
+ s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
+ case uint16:
+ s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
+ case uint32:
+ s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
+ case uint64:
+ s = strconv.FormatUint(v, argInt(args).Get(0, 10))
+ case string:
+ s = v
+ case []byte:
+ s = string(v)
+ default:
+ s = fmt.Sprintf("%v", v)
+ }
+ return s
+}
+
type Actioner interface {
GetOpType() int
GetActUserName() string
diff --git a/modules/mailer/mail.go b/modules/mailer/mail.go
index fe74af9e..cc4fd6d0 100644
--- a/modules/mailer/mail.go
+++ b/modules/mailer/mail.go
@@ -9,6 +9,13 @@ import (
"github.com/gogits/gogs/modules/base"
)
+// Create New mail message use MailFrom and MailUser
+func NewMailMessage(To []string, subject, body string) Message {
+ msg := NewHtmlMessage(To, base.MailService.User, subject, body)
+ msg.User = base.MailService.User
+ return msg
+}
+
func GetMailTmplData(user *models.User) map[interface{}]interface{} {
data := make(map[interface{}]interface{}, 10)
data["AppName"] = base.AppName
diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go
new file mode 100644
index 00000000..cc76acb2
--- /dev/null
+++ b/modules/mailer/mailer.go
@@ -0,0 +1,112 @@
+// 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 (
+ "fmt"
+ "net/smtp"
+ "strings"
+
+ "github.com/gogits/gogs/modules/base"
+ "github.com/gogits/gogs/modules/log"
+)
+
+type Message struct {
+ To []string
+ From string
+ Subject string
+ Body string
+ User string
+ Type string
+ Massive bool
+ Info string
+}
+
+// create mail content
+func (m Message) Content() string {
+ // set mail type
+ contentType := "text/plain; charset=UTF-8"
+ if m.Type == "html" {
+ contentType = "text/html; charset=UTF-8"
+ }
+
+ // create mail content
+ content := "From: " + m.User + "<" + m.From +
+ ">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
+ return content
+}
+
+// Direct Send mail message
+func Send(msg Message) (int, error) {
+ log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
+ host := strings.Split(base.MailService.Host, ":")
+
+ // get message body
+ content := msg.Content()
+
+ auth := smtp.PlainAuth("", base.MailService.User, base.MailService.Passwd, host[0])
+
+ if len(msg.To) == 0 {
+ return 0, fmt.Errorf("empty receive emails")
+ }
+
+ if len(msg.Body) == 0 {
+ return 0, fmt.Errorf("empty email body")
+ }
+
+ if msg.Massive {
+ // send mail to multiple emails one by one
+ num := 0
+ for _, to := range msg.To {
+ body := []byte("To: " + to + "\r\n" + content)
+ err := smtp.SendMail(base.MailService.Host, auth, msg.From, []string{to}, body)
+ if err != nil {
+ return num, err
+ }
+ num++
+ }
+ return num, nil
+ } else {
+ body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
+
+ // send to multiple emails in one message
+ err := smtp.SendMail(base.MailService.Host, auth, msg.From, msg.To, body)
+ if err != nil {
+ return 0, err
+ } else {
+ return 1, nil
+ }
+ }
+}
+
+// Async Send mail message
+func SendAsync(msg Message) {
+ // TODO may be need pools limit concurrent nums
+ go func() {
+ num, err := Send(msg)
+ tos := strings.Join(msg.To, "; ")
+ info := ""
+ if err != nil {
+ if len(msg.Info) > 0 {
+ info = ", info: " + msg.Info
+ }
+ // log failed
+ log.Error(fmt.Sprintf("Async sent email %d succeed, not send emails: %s%s err: %s", num, tos, info, err))
+ return
+ }
+ log.Trace(fmt.Sprintf("Async sent email %d succeed, sent emails: %s%s", num, tos, info))
+ }()
+}
+
+// Create html mail message
+func NewHtmlMessage(To []string, From, Subject, Body string) Message {
+ return Message{
+ To: To,
+ From: From,
+ Subject: Subject,
+ Body: Body,
+ Type: "html",
+ }
+}