]> source.dussan.org Git - gitea.git/commitdiff
Working on register mail confirmation
authorUnknown <joe2010xtmf@163.com>
Wed, 19 Mar 2014 11:21:23 +0000 (07:21 -0400)
committerUnknown <joe2010xtmf@163.com>
Wed, 19 Mar 2014 11:21:23 +0000 (07:21 -0400)
conf/app.ini
models/user.go
modules/auth/mail.go [new file with mode: 0644]
modules/base/conf.go
modules/base/tool.go
modules/mailer/mail.go [new file with mode: 0644]
modules/middleware/logger.go
routers/user/user.go

index debfcf93bd1fe26379550c79081561b8971d32aa..82d78d2334f982e93859a18d3a16f6840828c1f6 100644 (file)
@@ -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
index 80af9bd4ba861bee15d6360607f791d81e4fad42..579f6a74861967de1c914eb7bb2e7e0af4216f7d 100644 (file)
@@ -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 (file)
index 0000000..6f6bf20
--- /dev/null
@@ -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)
+}
index 9f6de56b9da3b9a739ecc1e000b612af9b78d4d0..ee5638ed689c8df5cd9aee2f5a7fe547da9229ec 100644 (file)
@@ -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()
 }
index 046b2c5174efd25ab7b7993b49b7ab66aba40d1e..2a989b377d5349bfd87927ecb7ad05fd7bce8d10 100644 (file)
@@ -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 (file)
index 0000000..fe74af9
--- /dev/null
@@ -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
+}
index 9ae620ebad20ea3e7c7838cfd334d920f28687f6..dcf85246089f6799e6a303dc5644de0e300a33c9 100644 (file)
@@ -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)
index fc56997b581650c6d4a79833eb00fb0356f9c8e3..05aeac60ecfa5254afe231c4c0a9d9a9ed1386eb 100644 (file)
@@ -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 {