Skip to content
Permalink
Browse files

10-Email-Support add reset_password_request page

  • Loading branch information...
bonfy committed Oct 11, 2018
1 parent f741e78 commit 3e6471f01981dc176ee588579aa02aae4b6ad683
@@ -9,4 +9,5 @@ mail:
smtp-port: 587
user: user
password: pwd

server:
url: http://127.0.0.1:8888
@@ -43,3 +43,9 @@ func GetSMTPConfig() (server string, port int, user, pwd string) {
pwd = viper.GetString("mail.password")
return
}

// GetServerURL func
func GetServerURL() (url string) {
url = viper.GetString("server.url")
return
}
@@ -1,7 +1,9 @@
package controller

import (
"bytes"
"fmt"
"html/template"
"log"
"net/http"

@@ -21,6 +23,7 @@ func (h home) registerRoutes() {
r.HandleFunc("/unfollow/{username}", middleAuth(unFollowHandler))
r.HandleFunc("/profile_edit", middleAuth(profileEditHandler))
r.HandleFunc("/explore", middleAuth(exploreHandler))
r.HandleFunc("/reset_password_request", resetPasswordRequestHandler)
r.HandleFunc("/", middleAuth(indexHandler))

http.Handle("/", r)
@@ -193,3 +196,40 @@ func exploreHandler(w http.ResponseWriter, r *http.Request) {
v := vop.GetVM(username, page, pageLimit)
templates[tpName].Execute(w, &v)
}

func resetPasswordRequestHandler(w http.ResponseWriter, r *http.Request) {
tpName := "reset_password_request.html"
vop := vm.ResetPasswordRequestViewModelOp{}
v := vop.GetVM()

if r.Method == http.MethodGet {
templates[tpName].Execute(w, &v)
}
if r.Method == http.MethodPost {
r.ParseForm()
email := r.Form.Get("email")

errs := checkResetPasswordRequest(email)
v.AddError(errs...)

if len(v.Errs) > 0 {
templates[tpName].Execute(w, &v)

} else {
log.Println("Send mail to", email)
vopEmail := vm.EmailViewModelOp{}
vEmail := vopEmail.GetVM(email)
var contentByte bytes.Buffer
tpl, _ := template.ParseFiles("templates/email.html")

if err := tpl.Execute(&contentByte, &vEmail); err != nil {
log.Println("Get Parse Template:", err)
w.Write([]byte("Error send email"))
return
}
content := contentByte.String()
go sendEmail(email, "Reset Password", content)
http.Redirect(w, r, "/login", http.StatusSeeOther)
}
}
}
@@ -135,12 +135,26 @@ func checkUserPassword(username, password string) string {
}

func checkUserExist(username string) string {
if !vm.CheckUserExist(username) {
if vm.CheckUserExist(username) {
return fmt.Sprintf("Username already exist, please choose another username")
}
return ""
}

func checkEmailExistRegister(email string) string {
if vm.CheckUserExist(email) {
return fmt.Sprintf("Email has registered by others, please choosse another email.")
}
return ""
}

func checkEmailExist(email string) string {
if !vm.CheckEmailExist(email) {
return fmt.Sprintf("Email does not register yet.Please Check email.")
}
return ""
}

// checkLogin()
func checkLogin(username, password string) []string {
var errs []string
@@ -171,12 +185,37 @@ func checkRegister(username, email, pwd1, pwd2 string) []string {
if errCheck := checkEmail(email); len(errCheck) > 0 {
errs = append(errs, errCheck)
}
if errCheck := checkEmailExistRegister(email); len(errCheck) > 0 {
errs = append(errs, errCheck)
}
if errCheck := checkUserExist(username); len(errCheck) > 0 {
errs = append(errs, errCheck)
}
return errs
}

func checkResetPasswordRequest(email string) []string {
var errs []string
if errCheck := checkEmail(email); len(errCheck) > 0 {
errs = append(errs, errCheck)
}
if errCheck := checkEmailExist(email); len(errCheck) > 0 {
errs = append(errs, errCheck)
}
return errs
}

func checkResetPassword(pwd1, pwd2 string) []string {
var errs []string
if pwd1 != pwd2 {
errs = append(errs, "2 password does not match")
}
if errCheck := checkPassword(pwd1); len(errCheck) > 0 {
errs = append(errs, errCheck)
}
return errs
}

// addUser()
func addUser(username, password, email string) error {
return vm.AddUser(username, password, email)
@@ -4,6 +4,8 @@ import (
"fmt"
"log"
"time"

jwt "github.com/dgrijalva/jwt-go"
)

// User struct
@@ -127,6 +129,34 @@ func (u *User) CreatePost(body string) error {
return db.Create(&post).Error
}

// GenerateToken func
func (u *User) GenerateToken() (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": u.Username,
"exp": time.Now().Add(time.Hour * 2).Unix(), // 可以添加过期时间
})
return token.SignedString([]byte("secret"))
}

// CheckToken func
func CheckToken(tokenString string) (string, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}

// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return []byte("secret"), nil
})

if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims["username"].(string), nil
} else {
return "", err
}
}

// GetUserByUsername func
func GetUserByUsername(username string) (*User, error) {
var user User
@@ -136,6 +166,15 @@ func GetUserByUsername(username string) (*User, error) {
return &user, nil
}

// GetUserByEmail func
func GetUserByEmail(email string) (*User, error) {
var user User
if err := db.Where("email=?", email).Find(&user).Error; err != nil {
return nil, err
}
return &user, nil
}

// AddUser func
func AddUser(username, password, email string) error {
user := User{Username: username, Email: email}
@@ -167,3 +206,9 @@ func UpdateAboutMe(username, text string) error {
contents := map[string]interface{}{"about_me": text}
return UpdateUserByUsername(username, contents)
}

// UpdatePassword func
func UpdatePassword(username, password string) error {
contents := map[string]interface{}{"password_hash": Md5(password)}
return UpdateUserByUsername(username, contents)
}
@@ -7,6 +7,7 @@ <h1>Login</h1>
</form>

<p>New User? <a href="/register">Click to Register!</a></p>
<p>Forget Password? <a href="/reset_password_request">Click to Reset Password!</a></p>

{{if .Errs}}
<ul>
@@ -0,0 +1,15 @@
{{define "content"}}
<h1>Input your email address:</h1>
<form action="/reset_password_request" method="post" name="reset_password_request">
<p><input type="text" class="form-control" name="email" value="" placeholder="Email"></p>
<p><input type="submit" class="btn btn-outline-primary" name="submit" value="Submit" ></p>
</form>

{{if .Errs}}
<ul>
{{range .Errs}}
<li>{{.}}</li>
{{end}}
</ul>
{{end}}
{{end}}
@@ -0,0 +1,13 @@
<p>Dear {{.Username}},</p>
<p>
To reset your password
<a href="{{.Server}}/reset_password/{{.Token}}">
click here
</a>
</p>
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
<p>{{.Server}}/reset_password/{{.Token}}</p>
<p>If you have not requested a password reset simply ignore this message.</p>
<p>This Email will expire in 2 hours.</p>
<p>Sincerely,</p>
<p>BONFY</p>
@@ -0,0 +1,26 @@
package vm

import (
"github.com/bonfy/go-mega-code/config"
"github.com/bonfy/go-mega-code/model"
)

// EmailViewModel struct
type EmailViewModel struct {
Username string
Token string
Server string
}

// EmailViewModelOp struct
type EmailViewModelOp struct{}

// GetVM func
func (EmailViewModelOp) GetVM(email string) EmailViewModel {
v := EmailViewModel{}
u, _ := model.GetUserByEmail(email)
v.Username = u.Username
v.Token, _ = u.GenerateToken()
v.Server = config.GetServerURL()
return v
}
@@ -26,9 +26,9 @@ func CheckUserExist(username string) bool {
_, err := model.GetUserByUsername(username)
if err != nil {
log.Println("Can not find username: ", username)
return true
return false
}
return false
return true
}

// AddUser func
@@ -0,0 +1,32 @@
package vm

import (
"log"

"github.com/bonfy/go-mega-code/model"
)

// ResetPasswordRequestViewModel struct
type ResetPasswordRequestViewModel struct {
LoginViewModel
}

// ResetPasswordRequestViewModelOp struct
type ResetPasswordRequestViewModelOp struct{}

// GetVM func
func (ResetPasswordRequestViewModelOp) GetVM() ResetPasswordRequestViewModel {
v := ResetPasswordRequestViewModel{}
v.SetTitle("Forget Password")
return v
}

// CheckEmailExist func
func CheckEmailExist(email string) bool {
_, err := model.GetUserByEmail(email)
if err != nil {
log.Println("Can not find email:", email)
return false
}
return true
}

0 comments on commit 3e6471f

Please sign in to comment.
You can’t perform that action at this time.