github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/routers/ForgotHandler.go (about)

     1  package routers
     2  
     3  import (
     4  	"encoding/base64"
     5  	"fmt"
     6  	"github.com/insionng/makross"
     7  	
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  	"github.com/insionng/yougam/helper"
    12  	simplejson "github.com/insionng/yougam/libraries/bitly/go-simplejson"
    13  	"github.com/insionng/yougam/models"
    14  )
    15  
    16  func GetForgotHandler(self *makross.Context) error {
    17  	
    18  
    19  	self.Set("catpage", "ForgotHandler")
    20  	tplname := "forgot"
    21  
    22  	var keyin string
    23  	if keyin = self.Param("key").String(); len(keyin) <= 0 {
    24  		keyin = self.FormValue("key")
    25  	}
    26  
    27  	userkey := helper.MD5to16(self.RealIP())
    28  
    29  	switch {
    30  	case ((len(keyin) > 0) && (len(userkey) > 0)):
    31  		{
    32  
    33  			keybyte, e := base64.URLEncoding.DecodeString(keyin)
    34  			if e != nil {
    35  				self.Flash.Error("抱歉,取回密码认证链接非法!")
    36  				goto render
    37  			}
    38  			keyin = string(keybyte)
    39  			if s, err := helper.Aes128COMDecrypt(keyin, helper.AesConstKey); err != nil {
    40  
    41  				self.Flash.Error("抱歉,取回密码认证链接不合法!!")
    42  				goto render
    43  
    44  			} else {
    45  				if s == "" {
    46  					self.Flash.Error("抱歉,取回密码认证失败!")
    47  					goto render
    48  				}
    49  				if sjson, err := simplejson.NewJson([]byte(s)); err != nil {
    50  
    51  					self.Flash.Error("抱歉,取回密码认证失败!!")
    52  					goto render
    53  				} else {
    54  
    55  					data := sjson.Get("data").MustMap()
    56  					if data == nil {
    57  						self.Flash.Error("抱歉,取回密码认证失败!!!")
    58  
    59  						goto render
    60  					}
    61  
    62  					var key, email, randkey, timekey string
    63  					if data["key"] != nil {
    64  						key = data["key"].(string)
    65  					}
    66  					if data["email"] != nil {
    67  						email = data["email"].(string)
    68  					}
    69  					if data["randkey"] != nil {
    70  						randkey = data["randkey"].(string)
    71  					}
    72  					if data["timekey"] != nil {
    73  						timekey = data["timekey"].(string)
    74  					}
    75  
    76  					timekeyInt64, _ := strconv.ParseInt(timekey, 10, 0)
    77  					key2 := helper.SHA1(randkey + userkey + email + helper.AesConstKey + timekey)
    78  					if now := time.Now().Unix(); timekeyInt64 < now { //超时
    79  
    80  						self.Flash.Error("抱歉,该认证链接已经超时失效!")
    81  						goto render
    82  					}
    83  					if key == key2 {
    84  
    85  						tplname = "password"
    86  						self.Set("fmail", email)
    87  
    88  						if usr, e := models.GetUserByEmail(email); usr != nil && e == nil {
    89  							tplname = "password"
    90  							self.Flash.Success("恭喜,该次链接校验成功,请设置密码!")
    91  							goto render
    92  						} else {
    93  
    94  							self.Flash.Error("抱歉,该Email并没有用作注册账号!")
    95  							goto render
    96  						}
    97  					} else {
    98  
    99  						self.Flash.Error("抱歉,该认证链接验证失败!")
   100  						goto render
   101  					}
   102  
   103  				}
   104  			}
   105  		}
   106  	default:
   107  		{
   108  			tplname = "forgot"
   109  			goto render
   110  		}
   111  	}
   112  render:
   113  	return self.Render(tplname)
   114  }
   115  
   116  func PostForgotHandler(self *makross.Context) error {
   117  	
   118  
   119  	self.Set("catpage", "ForgotHandler")
   120  	tplname := "forgot"
   121  	var keyin string
   122  	if keyin = self.Param("key").String(); len(keyin) <= 0 {
   123  		keyin = self.FormValue("key")
   124  	}
   125  
   126  	userkey := helper.MD5to16(self.RealIP())
   127  
   128  	switch {
   129  	case ((len(keyin) > 0) && (len(userkey) > 0)): //进入重置密码分支
   130  		{
   131  
   132  			keybyte, e := base64.URLEncoding.DecodeString(keyin)
   133  			if e != nil {
   134  				self.Flash.Error("抱歉,取回密码认证链接非法!")
   135  				goto render
   136  			}
   137  			keyin = string(keybyte)
   138  			if s, err := helper.Aes128COMDecrypt(keyin, helper.AesConstKey); err != nil {
   139  
   140  				self.Flash.Error("抱歉,取回密码认证链接不合法!!")
   141  				goto render
   142  
   143  			} else {
   144  				if len(s) == 0 {
   145  					self.Flash.Error("抱歉,取回密码认证失败!")
   146  					goto render
   147  				}
   148  				if sjson, err := simplejson.NewJson([]byte(s)); err != nil {
   149  
   150  					self.Flash.Error("抱歉,取回密码认证失败!!")
   151  					goto render
   152  				} else {
   153  
   154  					data := sjson.Get("data").MustMap()
   155  					if data == nil {
   156  						self.Flash.Error("抱歉,取回密码认证失败!!!")
   157  						goto render
   158  					}
   159  
   160  					var key, email, randkey, timekey string
   161  					if data["key"] != nil {
   162  						key = data["key"].(string)
   163  					}
   164  					if data["email"] != nil {
   165  						email = data["email"].(string)
   166  					}
   167  					if data["randkey"] != nil {
   168  						randkey = data["randkey"].(string)
   169  					}
   170  					if data["timekey"] != nil {
   171  						timekey = data["timekey"].(string)
   172  					}
   173  
   174  					timekeyInt64, _ := strconv.ParseInt(timekey, 10, 0)
   175  					key2 := helper.SHA1(randkey + userkey + email + helper.AesConstKey + timekey)
   176  					if now := time.Now().Unix(); timekeyInt64 < now { //超时
   177  						self.Flash.Error("抱歉,该认证链接已经超时失效!")
   178  						goto render
   179  					}
   180  					if key == key2 {
   181  
   182  						tplname = "password"
   183  						self.Set("fmail", email)
   184  
   185  						if usr, e := models.GetUserByEmail(email); usr != nil && e == nil {
   186  							tplname = "password"
   187  							password := self.FormValue("password")
   188  							repassword := self.FormValue("repassword")
   189  							if len(password) == 0 {
   190  								self.Flash.Error("密码不能设置为空!")
   191  								goto render
   192  							}
   193  
   194  							if password == repassword {
   195  								usr.Password = helper.EncryptHash(password, nil)
   196  
   197  								if rows, e := models.PutUser(usr.Id, usr); rows <= 0 || e != nil {
   198  
   199  									self.Flash.Error("抱歉,服务器写入数据发送错误,请你稍后重新尝试.")
   200  									goto render
   201  								} else {
   202  
   203  									self.Flash.Success("恭喜,你已经成功设置新密码!")
   204  									goto render
   205  								}
   206  							} else {
   207  								self.Flash.Error("抱歉,新设置密码与确认密码不一致,请你修改后重新尝试.")
   208  								goto render
   209  							}
   210  						} else {
   211  
   212  							self.Flash.Error("抱歉,该Email并没有用作注册账号!")
   213  							goto render
   214  						}
   215  					} else {
   216  
   217  						self.Flash.Error("抱歉,该认证链接验证失败!")
   218  						goto render
   219  					}
   220  
   221  				}
   222  			}
   223  		}
   224  	default: //发送认证链接邮件分支
   225  		{
   226  			var email string
   227  			if email = strings.TrimSpace(self.Param("email").String()); len(email) <= 0 {
   228  				email = strings.TrimSpace(self.FormValue("email"))
   229  			}
   230  
   231  			if len(email) <= 0 {
   232  				self.Flash.Error("抱歉,提交的邮件地址不能为空!")
   233  				goto render
   234  			}
   235  
   236  			randkey := helper.GUID32BIT()
   237  			d, _ := time.ParseDuration("1h") //设为1小时后失效
   238  			timekey := strconv.FormatInt(time.Now().Add(d).UnixNano(), 10)
   239  			key := helper.SHA1(randkey + userkey + email + helper.AesConstKey + timekey)
   240  
   241  			m := map[string]string{}
   242  			m["key"] = key
   243  			m["email"] = email
   244  			m["randkey"] = randkey //string
   245  			m["timekey"] = timekey //string
   246  
   247  			crypted, _ := helper.SetJsonCOMEncrypt(1, "", m)
   248  			b64key := base64.URLEncoding.EncodeToString([]byte(crypted))
   249  
   250  			if helper.CheckEmail(email) {
   251  
   252  				if usr, e := models.GetUserByEmail(email); usr != nil && e == nil {
   253  
   254  					url := fmt.Sprintf("http://%s/forgot/?key=%s", helper.Domain, b64key)
   255  					body := "<html><body><div>"
   256  					body = body + "<p>亲爱的 <strong>" + usr.Username + "</strong> ,您好:</p>"
   257  					body = body + `<p style="padding-left:2em;">您申请了重置` + helper.SiteName + `登录密码,请点击以下链接设置新密码.</p>`
   258  					body = body + `<p><a href="` + url + `" target="_blank">` + url + `</a></p>`
   259  					body = body + "<p>(如果无法点击该URL链接地址,请将它复制并粘帖到浏览器的地址输入框访问即可.)</p>"
   260  					body = body + "<p>注意:请您在收到邮件后点击此链接以完成重置,否则该链接将会在1小时后失效.</p>"
   261  					body = body + "<p>我们将一如既往竭诚为您服务!</p>"
   262  					body = body + `<p style="border-bottom:dotted 1px gray;height:1px;"></p>`
   263  					body = body + "<p>" + helper.MailAdline + "</p>"
   264  					body = body + "</div></body></html>"
   265  
   266  					subject := "【" + helper.SiteName + "】找回密码"
   267  
   268  					//发送邮件
   269  					if err := helper.SendEmail(email, subject, body, "html"); err != nil {
   270  						self.Flash.Error("抱歉," + helper.SiteName + "发送重置邮件失败,请你稍后重新尝试.")
   271  						goto render
   272  					} else {
   273  						self.Flash.Success("恭喜," + helper.SiteName + "已经发送重置邮件到你的注册邮箱,请你注意查收.")
   274  						goto render
   275  					}
   276  
   277  				} else {
   278  					self.Flash.Error("抱歉,该Email并没有用作注册账号!")
   279  					return self.Redirect("/forgot/")
   280  				}
   281  			} else {
   282  				self.Flash.Error("抱歉,你提交的邮件地址不合法!")
   283  				goto render
   284  			}
   285  		}
   286  	}
   287  render:
   288  	return self.Render(tplname)
   289  }