aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUnknown <joe2010xtmf@163.com>2014-03-19 07:21:23 -0400
committerUnknown <joe2010xtmf@163.com>2014-03-19 07:21:23 -0400
commitfbbae2b721c04be740d67b9d227a7578030f93b9 (patch)
tree394b9bb1e2e3b36611d834027ecaf6ee34a8a41d
parent9a666f33773c5d8b66e9ab66598414f62bcfdc11 (diff)
Working on register mail confirmation
-rw-r--r--conf/app.ini12
-rw-r--r--models/user.go25
-rw-r--r--modules/auth/mail.go42
-rw-r--r--modules/base/conf.go29
-rw-r--r--modules/base/tool.go62
-rw-r--r--modules/mailer/mail.go24
-rw-r--r--modules/middleware/logger.go2
-rw-r--r--routers/user/user.go7
8 files changed, 189 insertions, 14 deletions
diff --git a/conf/app.ini b/conf/app.ini
index debfcf93..82d78d23 100644
--- a/conf/app.ini
+++ b/conf/app.ini
@@ -1,5 +1,6 @@
; App name that shows on every page title
APP_NAME = Gogs: Go Git Service
+APP_LOGO = img/favicon.png
; !!MUST CHANGE TO YOUR USER NAME!!
RUN_USER = lunny
; Either "dev", "prod" or "test", default is "dev"
@@ -11,7 +12,8 @@ LANG_IGNS = Google Go|C|Python|Ruby|C Sharp
LICENSES = Apache v2 License|GPL v2|MIT License|Affero GPL|BSD (3-Clause) License
[server]
-DOMAIN = gogits.org
+DOMAIN = localhost
+ROOT_URL = http://%(DOMAIN)s:%(HTTP_PORT)s/
HTTP_ADDR =
HTTP_PORT = 3000
@@ -27,7 +29,13 @@ SSL_MODE = disable
[security]
; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!!
-USER_PASSWD_SALT = !#@FDEWREWR&*(
+SECRET_KEY = !#@FDEWREWR&*(
+
+[service]
+ACTIVE_CODE_LIVE_MINUTES = 180
+RESET_PASSWD_CODE_LIVE_MINUTES = 180
+; User need to confirm e-mail for registration
+REGISTER_EMAIL_CONFIRM = true
[mailer]
ENABLED = false
diff --git a/models/user.go b/models/user.go
index 80af9bd4..579f6a74 100644
--- a/models/user.go
+++ b/models/user.go
@@ -19,14 +19,6 @@ import (
"github.com/gogits/gogs/modules/base"
)
-var (
- UserPasswdSalt string
-)
-
-func init() {
- UserPasswdSalt = base.Cfg.MustValue("security", "USER_PASSWD_SALT")
-}
-
// User types.
const (
UT_INDIVIDUAL = iota + 1
@@ -56,6 +48,9 @@ type User struct {
AvatarEmail string `xorm:"not null"`
Location string
Website string
+ IsActive bool
+ Rands string `xorm:"VARCHAR(10)"`
+ Expired time.Time
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
}
@@ -104,6 +99,11 @@ func (user *User) NewGitSig() *git.Signature {
}
}
+// return a user salt token
+func GetUserSalt() string {
+ return base.GetRandomString(10)
+}
+
// RegisterUser creates record of a new user.
func RegisterUser(user *User) (err error) {
isExist, err := IsUserExist(user.Name)
@@ -123,6 +123,8 @@ func RegisterUser(user *User) (err error) {
user.LowerName = strings.ToLower(user.Name)
user.Avatar = base.EncodeMd5(user.Email)
user.AvatarEmail = user.Email
+ user.Expired = time.Now().Add(3 * 24 * time.Hour)
+ user.Rands = GetUserSalt()
if err = user.EncodePasswd(); err != nil {
return err
} else if _, err = orm.Insert(user); err != nil {
@@ -134,6 +136,11 @@ func RegisterUser(user *User) (err error) {
}
return err
}
+
+ // Send confirmation e-mail.
+ if base.Service.RegisterEmailConfitm {
+
+ }
return nil
}
@@ -183,7 +190,7 @@ func DeleteUser(user *User) error {
// EncodePasswd encodes password to safe format.
func (user *User) EncodePasswd() error {
- newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(UserPasswdSalt), 16384, 8, 1, 64)
+ newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(base.SecretKey), 16384, 8, 1, 64)
user.Passwd = fmt.Sprintf("%x", newPasswd)
return err
}
diff --git a/modules/auth/mail.go b/modules/auth/mail.go
new file mode 100644
index 00000000..6f6bf20a
--- /dev/null
+++ b/modules/auth/mail.go
@@ -0,0 +1,42 @@
+// 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 auth
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/gogits/gogs/models"
+ "github.com/gogits/gogs/modules/base"
+ "github.com/gogits/gogs/modules/mailer"
+)
+
+// 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
+ code := base.CreateTimeLimitCode(data, hours, startInf)
+
+ // add tail hex username
+ code += hex.EncodeToString([]byte(user.LowerName))
+ return code
+}
+
+// Send user register mail with active code
+func SendRegisterMail(user *models.User) {
+ code := CreateUserActiveCode(user, nil)
+ subject := "Register success, Welcome"
+
+ 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)
+
+ // // async send mail
+ // mailer.SendAsync(msg)
+}
diff --git a/modules/base/conf.go b/modules/base/conf.go
index 9f6de56b..ee5638ed 100644
--- a/modules/base/conf.go
+++ b/modules/base/conf.go
@@ -28,11 +28,20 @@ type Mailer struct {
var (
AppVer string
AppName string
+ AppLogo string
+ AppUrl string
Domain string
+ SecretKey string
Cfg *goconfig.ConfigFile
MailService *Mailer
)
+var Service struct {
+ RegisterEmailConfitm bool
+ ActiveCodeLives int
+ ResetPwdCodeLives int
+}
+
func exeDir() (string, error) {
file, err := exec.LookPath(os.Args[0])
if err != nil {
@@ -54,6 +63,11 @@ var logLevels = map[string]string{
"Critical": "5",
}
+func newService() {
+ Service.ActiveCodeLives = Cfg.MustInt("service", "ACTIVE_CODE_LIVE_MINUTES", 180)
+ Service.ResetPwdCodeLives = Cfg.MustInt("service", "RESET_PASSWD_CODE_LIVE_MINUTES", 180)
+}
+
func newLogService() {
// Get and check log mode.
mode := Cfg.MustValue("log", "MODE", "console")
@@ -117,6 +131,17 @@ func newMailService() {
}
}
+func newRegisterService() {
+ if !Cfg.MustBool("service", "REGISTER_EMAIL_CONFIRM") {
+ return
+ } else if MailService == nil {
+ log.Warn("Register Service: Mail Service is not enabled")
+ return
+ }
+ Service.RegisterEmailConfitm = true
+ log.Info("Register Service Enabled")
+}
+
func init() {
var err error
workDir, err := exeDir()
@@ -143,9 +168,13 @@ func init() {
Cfg.BlockMode = false
AppName = Cfg.MustValue("", "APP_NAME", "Gogs: Go Git Service")
+ AppLogo = Cfg.MustValue("", "APP_LOGO", "img/favicon.png")
+ AppUrl = Cfg.MustValue("server", "ROOT_URL")
Domain = Cfg.MustValue("server", "DOMAIN")
+ SecretKey = Cfg.MustValue("security", "SECRET_KEY")
// Extensions.
newLogService()
newMailService()
+ newRegisterService()
}
diff --git a/modules/base/tool.go b/modules/base/tool.go
index 046b2c51..2a989b37 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -7,6 +7,8 @@ package base
import (
"bytes"
"crypto/md5"
+ "crypto/rand"
+ "crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
@@ -22,6 +24,66 @@ func EncodeMd5(str string) string {
return hex.EncodeToString(m.Sum(nil))
}
+// Random generate string
+func GetRandomString(n int) string {
+ const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ var bytes = make([]byte, n)
+ rand.Read(bytes)
+ for i, b := range bytes {
+ bytes[i] = alphanum[b%byte(len(alphanum))]
+ }
+ return string(bytes)
+}
+
+// create a time limit code
+// code format: 12 length date time string + 6 minutes string + 40 sha1 encoded string
+func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string {
+ format := "YmdHi"
+
+ var start, end time.Time
+ var startStr, endStr string
+
+ if startInf == nil {
+ // Use now time create code
+ start = time.Now()
+ startStr = DateFormat(start, format)
+ } else {
+ // use start string create code
+ startStr = startInf.(string)
+ start, _ = DateParse(startStr, format)
+ startStr = DateFormat(start, format)
+ }
+
+ end = start.Add(time.Minute * time.Duration(minutes))
+ endStr = DateFormat(end, format)
+
+ // create sha1 encode string
+ sh := sha1.New()
+ sh.Write([]byte(data + SecretKey + startStr + endStr + fmt.Sprintf("%d", minutes)))
+ encoded := hex.EncodeToString(sh.Sum(nil))
+
+ code := fmt.Sprintf("%s%06d%s", startStr, minutes, encoded)
+ return code
+}
+
+func RenderTemplate(TplNames string, Data map[interface{}]interface{}) string {
+ // if beego.RunMode == "dev" {
+ // beego.BuildTemplate(beego.ViewsPath)
+ // }
+
+ // ibytes := bytes.NewBufferString("")
+ // if _, ok := beego.BeeTemplates[TplNames]; !ok {
+ // panic("can't find templatefile in the path:" + TplNames)
+ // }
+ // err := beego.BeeTemplates[TplNames].ExecuteTemplate(ibytes, TplNames, Data)
+ // if err != nil {
+ // beego.Trace("template Execute err:", err)
+ // }
+ // icontent, _ := ioutil.ReadAll(ibytes)
+ // return string(icontent)
+ return "not implement yet"
+}
+
// AvatarLink returns avatar link by given e-mail.
func AvatarLink(email string) string {
return "http://1.gravatar.com/avatar/" + EncodeMd5(email)
diff --git a/modules/mailer/mail.go b/modules/mailer/mail.go
new file mode 100644
index 00000000..fe74af9e
--- /dev/null
+++ b/modules/mailer/mail.go
@@ -0,0 +1,24 @@
+// 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 (
+ "github.com/gogits/gogs/models"
+ "github.com/gogits/gogs/modules/base"
+)
+
+func GetMailTmplData(user *models.User) map[interface{}]interface{} {
+ data := make(map[interface{}]interface{}, 10)
+ data["AppName"] = base.AppName
+ data["AppVer"] = base.AppVer
+ data["AppUrl"] = base.AppUrl
+ data["AppLogo"] = base.AppLogo
+ data["ActiveCodeLives"] = base.Service.ActiveCodeLives
+ data["ResetPwdCodeLives"] = base.Service.ResetPwdCodeLives
+ if user != nil {
+ data["User"] = user
+ }
+ return data
+}
diff --git a/modules/middleware/logger.go b/modules/middleware/logger.go
index 9ae620eb..dcf85246 100644
--- a/modules/middleware/logger.go
+++ b/modules/middleware/logger.go
@@ -37,6 +37,8 @@ func Logger() martini.Handler {
content = fmt.Sprintf("\033[1;33m%s\033[0m", content)
case 404:
content = fmt.Sprintf("\033[1;31m%s\033[0m", content)
+ case 500:
+ content = fmt.Sprintf("\033[1;36m%s\033[0m", content)
}
}
log.Println(content)
diff --git a/routers/user/user.go b/routers/user/user.go
index fc56997b..05aeac60 100644
--- a/routers/user/user.go
+++ b/routers/user/user.go
@@ -131,9 +131,10 @@ func SignUp(ctx *middleware.Context, form auth.RegisterForm) {
}
u := &models.User{
- Name: form.UserName,
- Email: form.Email,
- Passwd: form.Password,
+ Name: form.UserName,
+ Email: form.Email,
+ Passwd: form.Password,
+ IsActive: !base.Service.RegisterEmailConfitm,
}
if err := models.RegisterUser(u); err != nil {