func (a Auth) DoLogin(email, pwd, validationCode, captchaId string) revel.Result { log.Println("email:", email, "validationCode:", validationCode, "captchaId:", captchaId) ok := app.NewOk() ok.Ok = a.Validation.Required(captcha.VerifyString(captchaId, validationCode)).Ok if !ok.Ok { ok.Msg = "captcha" return a.RenderJson(ok) } ok.Ok = a.Validation.Required(email).Ok if !ok.Ok { ok.Msg = "email" return a.RenderJson(ok) } ok.Ok = a.Validation.Email(email).Ok if !ok.Ok { ok.Msg = "email" return a.RenderJson(ok) } if !a.checkAuth() { ok.Msg = "login" ok.Ok = false } else { ok.Next = app.NextJson{"href", "/index"} a.Session["user"] = email if email == "*****@*****.**" { ok.Msg = "admin" } } log.Println("set register session:", a.Session, "with resp:", ok) return a.RenderJson(ok) }
// 校验验证码 func (this *Captcha) Check(req *http.Request, res http.ResponseWriter) { req.ParseForm() if ok := captcha.VerifyString(req.Form.Get(conf.ConfInstance.CaptchaIdName), req.Form.Get(conf.ConfInstance.CaptchaName)); !ok { res.WriteHeader(400) res.Write([]byte("验证码错误")) } }
// 用户登录表单提交 func (this *UserController) LoginAction() { flash := beego.NewFlash() user := &models.User{} err := this.ParseForm(user) if err != nil { beego.Error("用户登录失败:" + err.Error()) flash.Error("用户登录失败!") flash.Store(&this.Controller) this.Redirect("/login", 302) //登录失败,重定向到登录页 return } user.Password = models.MD5(user.Password) //将密码以MD5加密存储 captchaCode := this.Input().Get("captcha") //判断验证码是否正确 if !captcha.VerifyString(this.GetSession("captchaStr").(string), captchaCode) { flash.Error("验证码不正确!") flash.Store(&this.Controller) this.DelSession("captchaStr") //从session中清空 this.Redirect("/login", 302) //验证码不正确,重定向到登录页 return } else { isAutoLogin := this.Input().Get("isAutoLogin") == "on" //是否自动登录 u := models.Login(user) //成功返回user,失败返回nil if u != nil { maxAge := 0 if isAutoLogin { maxAge = 72 * 24 * 60 } this.Ctx.SetCookie("username", user.Username, maxAge, "/") //设置cookie this.Ctx.SetCookie("password", user.Password, maxAge, "/") //设置cookie u.Lastlogin = time.Now().Local() //设置最后登录时间 u.Loginip = this.Ctx.Input.IP() //获取客户端IP if !models.UserModify(u) { //用户登录成功后更新最后登录时间 beego.Error("更新用户最后登录时间失败" + err.Error()) flash.Error("更新用户最后登录时间失败!") flash.Store(&this.Controller) } this.SetSession("user", u) //将用户信息存放到Session中 flash.Notice("用户" + u.Nickname + "登录成功!") flash.Store(&this.Controller) this.Redirect("/", 302) //登录成功 return } else { flash.Error("用户名或密码不正确!") flash.Store(&this.Controller) this.Redirect("/login", 302) //登录失败,重定向到登录页 return } } }
func processFormHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") if !captcha.VerifyString(r.FormValue("captchaId"), r.FormValue("captchaSolution")) { io.WriteString(w, "Wrong captcha solution! No robots allowed!\n") } else { io.WriteString(w, "Great job, human! You solved the captcha.\n") } io.WriteString(w, "<br><a href='/'>Try another one</a>") }
// return true if this session has solved the last captcha given provided solution, otherwise false func (cs *CaptchaServer) CheckSession(w http.ResponseWriter, r *http.Request, solution string) (bool, error) { s, err := cs.store.Get(r, cs.sessionName) if err == nil { id, ok := s.Values["captcha_id"] if ok { return captcha.VerifyString(id.(string), solution), nil } } return false, err }
func captchaServer(w http.ResponseWriter, req *http.Request) { if req.Method == "GET" { w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, "%s", captcha.New()) return } else if req.Method == "POST" { if captcha.VerifyString(req.FormValue("captchaId"), req.FormValue("captchaSolution")) { } else { } } }
/* Checks to make sure the user gave a valid CAPTCHA solution. (Note: if false is returned, this function takes care of serving a webpage to the user) Parameters: ctx: the context of the http request id: the id string for the captcha we are to check the solution against soln: the solution the user submitted to the CAPTCHA Returns: bool: true if the user entered a correct solution, false otherwise. string: A string containing the error text as to why the solution was not accepted, or nil error: Any error that was encountered */ func goodCaptchaSolution(ctx *web.Context, id, soln string) (bool, string, error) { //make sure we were given a non-empty ID if id == "" { return false, "INTERNAL ERROR", errors.New("Attempting to verify CAPTCHA with empty ID") } else if soln == "" { //Make sure they actually answered the CAPTCHA return false, "You must enter a solution to the CAPTCHA to generate a short link", nil } else if !captcha.VerifyString(ctx.Params["captcha_id"], soln) { //They didn't give a correct solution return false, "The solution to the CAPTCHA that you entered was incorrect", nil } //The user gave us a correct solution to the CAPTCHA return true, "", nil }
// IsCaptchaValid checks (when the app is not in the developing mode) if the // captcha is correct for a particular name func (Adapter *Adapter) IsCaptchaValid(page string) bool { value := strings.TrimSpace(Adapter.GetString(page + "-captcha-value")) id := strings.TrimSpace(Adapter.GetString(page + "-captcha-id")) if !Adapter.IsProductionMode() { return true } if !Adapter.IsCaptchaRequired(page) { return true } return captcha.VerifyString(id, value) }
// 用户注册表单提交 func (this *UserController) RegisterAction() { flash := beego.NewFlash() user := &models.User{} err := this.ParseForm(user) if err != nil { beego.Error("用户注册失败:" + err.Error()) flash.Error("注册用户失败!") flash.Store(&this.Controller) this.Redirect("/register", 302) //注册失败,重定向到注册页 return } user.Password = models.MD5(user.Password) //将密码以MD5加密存储 user.Registed = time.Now().Local() //用户注册时间 user.Lastlogin = time.Now().Local() //用户最后登录时间 user.Registeip = this.Ctx.Input.IP() //用户注册的ip captchaCode := this.Input().Get("captcha") //判断验证码是否正确 if !captcha.VerifyString(this.GetSession("captchaStr").(string), captchaCode) { flash.Error("验证码不正确!") flash.Store(&this.Controller) this.DelSession("captchaStr") //从session中清空 this.Redirect("/register", 302) //验证码不正确,重定向到登录页 return } else { if models.CheckUser(user.Username) { //判断该用户是否已经存在 flash.Error("该用户已存在!") flash.Store(&this.Controller) this.Redirect("/register", 302) //该用户已存在,重定向到注册页 return } else { err = models.RegisterUser(user) //用户注册 if err != nil { flash.Error("注册用户失败!") flash.Store(&this.Controller) this.Redirect("/register", 302) //验证码不正确,重定向到注册页 return } } } flash.Notice("注册成功!") flash.Store(&this.Controller) this.Redirect("/login", 302) //注册成功,重定向到登录页 return }
func verifyCaptcha(writer http.ResponseWriter, request *http.Request) { captchaId := request.URL.Query().Get("captchaId") verifyString := request.URL.Query().Get("verifyString") clientId := validationStore.Get(captchaId, true) result := captcha.VerifyString(captchaId, verifyString) if result { privateKey := userStore.Get(clientId, false) md5String := fmt.Sprintf("%x", md5.Sum([]byte(privateKey+captchaId))) validationStore.Set(md5String, clientId) io.WriteString(writer, md5String) } else { io.WriteString(writer, "fail") } }
func login(w http.ResponseWriter, r *http.Request, s sessions.Session, logger *log.Logger) { r.ParseForm() username := r.PostForm.Get("username") password := r.PostForm.Get("password") checkcode := r.PostForm.Get("checkcode") code := s.Get("checkcode") if !captcha.VerifyString(code.(string), checkcode) { w.Write(jsonResponse(map[string]interface{}{"status": false, "msg": "验证码错误"})) } else { user := &data.User{Logger: logger} if user.Check(username, password) { s.Set("useradmin", username) w.Write(jsonResponse(map[string]interface{}{"status": true, "msg": "success"})) } else { w.Write(jsonResponse(map[string]interface{}{"status": false, "msg": "用户名或密码错误"})) } } }
func (self *CaptchaContext) Challenge(w http.ResponseWriter, r *http.Request, edge string) *ProxyError { captchaId := r.PostFormValue("captchaId") solution := r.PostFormValue("captchaSolution") // Verify the input. if captcha.VerifyString(captchaId, solution) { token, err := self.GenerateToken() if err != nil { return &ProxyError{ Code: 500, Msg: "Unable to generate token value.", Err: err, } } // Strip the port off, since I cannot use them in the cookie. parts := strings.Split(edge, ":") http.SetCookie(w, &http.Cookie{ Name: HumanCookieName, Value: token, Expires: time.Now().Add(self.ValidDuration), Domain: "." + parts[0], Path: "/", }) http.Redirect(w, r, r.URL.Path, 302) return nil } // Deal with displaying the Captcha. if strings.HasPrefix(r.URL.Path, "/captcha/") { self.Generator.ServeHTTP(w, r) return nil } else { if err := captchaTemplate.Execute(w, &struct{ CaptchaId string }{captcha.New()}); err != nil { return &ProxyError{ Code: 500, Msg: "Unable to generate captcha page.", Err: err, } } return nil } }
// addComment responds to a POST request for adding a comment to a post // with an ident matching "postname". If such a post cannot be found, // a 404 page is shown. // Form data is trimmed and the CAPTCHA is verified before anything else. // Finally, we add the comment but make sure to wrap it in an addCommentLocker. // This makes it so only a single comment can be added at a time for one // particular entry. This allows us to rely on the existing cache to provide // a unique identifier as a comment file name. (i.e., an incrementing integer.) func addComment(w http.ResponseWriter, req *http.Request) { // render404(w, "add comment") // return vars := mux.Vars(req) post := forceValidPost(w, vars["postname"]) if post == nil { return } // Get the form values. author := strings.TrimSpace(req.FormValue("plato")) email := strings.TrimSpace(req.FormValue("email")) comment := strings.TrimSpace(req.FormValue("cauchy")) // First check the captcha before anything else. captchaId := req.FormValue("captchaid") userTest := req.FormValue("captcha") if !captcha.VerifyString(captchaId, userTest) { renderPost(w, post, "The CAPTCHA text you entered did not match the text in the "+ "image. Please try again.", author, email, comment) return } // We need to make sure only one comment per post can be added at a time. // Namely, we need unique sequential identifiers for each comment. post.addCommentLocker.Lock() defer post.addCommentLocker.Unlock() // Add the comment and refresh the comment store for this post. // 'addComment' makes sure the input is valid and reports an // error otherwise. err := post.addComment(author, email, comment) if err == nil { // success! post.loadComments() http.Redirect(w, req, "/"+post.Ident+"#comments", http.StatusFound) } else { // failure... :-( renderPost(w, post, err.Error(), author, email, comment) } }
// VerifyCAPTCHA accepts a *http.Request and verifies that the given // 'captcha' form is valid. This is a string of the form // "id:solution". It will return IncorrectCAPTCHAError if the solution // or ID is invalid. func VerifyCAPTCHA(req *http.Request) error { // Get the "captcha" form value. solution := req.FormValue("captcha") // Find the point to split the form value at. If it's not found in // the string, return the InvalidCAPTCHAFormat error. index := strings.Index(solution, ":") if index < 0 { return InvalidCAPTCHAFormat } // If that was successful, try to verify it. If it returns false, // the ID or solution was invalid. if !captcha.VerifyString(solution[:index], solution[index+1:]) { return IncorrectCAPTCHA } // If we get to this point, then it was successfully validated and // we can return nil. return nil }
// 用户注册 // uri: /account/register{json:(|.json)} func RegisterHandler(rw http.ResponseWriter, req *http.Request) { if _, ok := filter.CurrentUser(req); ok { util.Redirect(rw, req, "/") return } vars := mux.Vars(req) username := req.PostFormValue("username") // 请求注册页面 if username == "" || req.Method != "POST" || vars["json"] == "" { filter.SetData(req, map[string]interface{}{"captchaId": captcha.NewLen(4)}) req.Form.Set(filter.CONTENT_TPL_KEY, "/template/register.html") return } // 校验验证码 if !captcha.VerifyString(req.PostFormValue("captchaid"), req.PostFormValue("captchaSolution")) { fmt.Fprint(rw, `{"ok": 0, "error":"验证码错误"}`) return } // 入库 errMsg, err := service.CreateUser(req.PostForm) if err != nil { // bugfix:http://studygolang.com/topics/255 if errMsg == "" { errMsg = err.Error() } fmt.Fprint(rw, `{"ok": 0, "error":"`, errMsg, `"}`) return } // 注册成功,自动为其登录 setCookie(rw, req, req.PostFormValue("username")) // 发送欢迎邮件 go sendWelcomeMail([]string{req.PostFormValue("email")}) fmt.Fprint(rw, `{"ok": 1, "msg":"注册成功"}`) }
// verify a captcha func (cs *CaptchaServer) VerifyCaptcha(w http.ResponseWriter, r *http.Request) { dec := json.NewDecoder(r.Body) defer r.Body.Close() // request req := make(map[string]string) // response resp := make(map[string]interface{}) resp["solved"] = false // decode request err := dec.Decode(req) if err == nil { // decode okay id, ok := req["id"] if ok { // we have id solution, ok := req["solution"] if ok { // we have solution and id resp["solved"] = captcha.VerifyString(id, solution) } else { // we don't have solution err = errors.New("no captcha solution provided") } } else { // we don't have id err = errors.New("no captcha id provided") } } if err != nil { // error happened resp["error"] = err.Error() } // send reply w.Header().Set("Content-Type", "text/json; encoding=UTF-8") enc := json.NewEncoder(w) enc.Encode(resp) }
//登陆 func (c *User) Login(admin *models.Admin) revel.Result { if c.Request.Method == "GET" { title := "登陆--GoCMS管理系统" CaptchaId := captcha.NewLen(6) return c.Render(title, CaptchaId) } else { var username string = c.Params.Get("username") var password string = c.Params.Get("password") var captchaId string = c.Params.Get("captchaId") var verify string = c.Params.Get("verify") data := make(map[string]string) if LANG, ok := c.Session["Lang"]; ok { //设置语言 c.Request.Locale = LANG } else { //设置默认语言 c.Request.Locale = "zh" } if !captcha.VerifyString(captchaId, verify) { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("verification_code") return c.RenderJson(data) } if len(username) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_user_name") return c.RenderJson(data) } if len(password) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_password") return c.RenderJson(data) } if len(verify) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_verification_code") return c.RenderJson(data) } admin_info := admin.GetByName(username) if admin_info.Id <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("admin_username_error") } else if admin_info.Status == 0 && admin_info.Id != 1 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("admin_forbid_login") } else if admin_info.Role.Status == 0 && admin_info.Id != 1 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("admin_forbid_role_login") } else if username == admin_info.Username && utils.Md5(password) == admin_info.Password { /* * %% 印出百分比符号,不转换。 * %c 整数转成对应的 ASCII 字元。 * %d 整数转成十进位。 * %f 倍精确度数字转成浮点数。 * %o 整数转成八进位。 * %s 整数转成字符串。 * %x 整数转成小写十六进位。 * %X 整数转成大写十六进位 */ c.Session["UserID"] = fmt.Sprintf("%d", admin_info.Id) c.Session["Lang"] = admin_info.Lang c.Flash.Success(c.Message("login_success")) c.Flash.Out["url"] = "/" //更新登陆时间 if ip := c.Request.Header.Get("X-Forwarded-For"); ip != "" { ips := strings.Split(ip, ",") if len(ips) > 0 && ips[0] != "" { rip := strings.Split(ips[0], ":") admin.Lastloginip = rip[0] } } else { ip := strings.Split(c.Request.RemoteAddr, ":") if len(ip) > 0 { if ip[0] != "[" { admin.Lastloginip = ip[0] } } } admin.UpdateLoginTime(admin_info.Id) //****************************************** //管理员日志 logs := new(models.Logs) desc := "登陆用户名:" + admin_info.Username + "|^|登陆系统!|^|登陆ID:" + fmt.Sprintf("%d", admin_info.Id) logs.Save(admin_info, c.Controller, desc) //***************************************** data["status"] = "1" data["url"] = "/Message/" data["message"] = c.Message("login_success") } else { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_password_error") } return c.RenderJson(data) } }
func CheckCaptcha(r *http.Request) bool { return captcha.VerifyString(r.FormValue("captchaId"), r.FormValue("captchaSolution")) }
/* 注册 */ func (this *CheckController) Register() { ok, data := func() (bool, interface{}) { if len([]rune(this.GetString("email"))) > 100 { return false, "邮箱过长" } if strings.Contains(this.GetString("email"), "|") { return false, "邮箱不能含有“|”符号" } if len([]rune(this.GetString("nickname"))) < 3 || len([]rune(this.GetString("nickname"))) > 20 { return false, "昵称长度为3-20" } if strings.Contains(this.GetString("nickname"), "|") { return false, "昵称不能含有“|”符号" } if len([]rune(this.GetString("password"))) < 6 || len([]rune(this.GetString("password"))) > 30 { return false, "密码长度为6-30" } if strings.Contains(this.GetString("password"), "|") { return false, "密码不能含有“|”符号" } if this.GetSession("WOKUID") != nil { //已有session则退出 return false, "已登录" } //验证码校验 cap_id, cap_value := this.GetString("capid"), this.GetString("cap") if ok := captcha.VerifyString(cap_id, cap_value); !ok { return false, "验证码错误" } //数据赋值 user := &UserController{} user.member.Email = this.GetString("email") user.member.Nickname = this.GetString("nickname") user.member.Password = this.GetString("password") user.member.Type = 1 //普通会员 //检测邮箱是否已存在 if objectid := user.member.EmailExist(this.GetString("email")); objectid != "" { return false, "您的账号已存在,可以直接登录" } //检测昵称是否存在 if objectid := user.member.NicknameExist(this.GetString("nickname")); objectid != "" { return false, "昵称已被使用" } //生成参数 _, urlParams := user.member.CreateSign(time.Now().Unix()+3600, "createAccount", this.GetString("email")+"|"+this.GetString("nickname")+"|"+this.GetString("password")) //发送验证邮件 SendEmail([]string{user.member.Email}, user.member.Nickname+":您的我酷账号申请成功,请点击链接激活!"+time.Now().String(), ` 您好:`+user.member.Nickname+`<br><br> (请在一小时内完成)您需要点击以下链接来激活您的我酷账户:<br><br> http://`+beego.AppConfig.String("httpWebSite")+`/auth`+urlParams) return true, nil }() this.Data["json"] = map[string]interface{}{ "ok": ok, "data": data, } this.ServeJson() }
//登陆 func (c *User) Login(admin *models.Admin) revel.Result { if c.Request.Method == "GET" { title := "登陆--GoCMS管理系统" CaptchaId := captcha.NewLen(6) return c.Render(title, CaptchaId) } else { var username string = c.Params.Get("username") var password string = c.Params.Get("password") var captchaId string = c.Params.Get("captchaId") var verify string = c.Params.Get("verify") data := make(map[string]string) if !captcha.VerifyString(captchaId, verify) { data["status"] = "0" data["url"] = "/" data["message"] = "验证码错误!" return c.RenderJson(data) } if len(username) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = "请填写用户名!" return c.RenderJson(data) } if len(password) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = "请填写密码!" return c.RenderJson(data) } if len(verify) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = "请填写验证码!" return c.RenderJson(data) } admin_info := admin.GetByName(username) if admin_info.Id <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = "用户名错误!" } else if admin_info.Status == 0 && admin_info.Id != 1 { data["status"] = "0" data["url"] = "/" data["message"] = "此账号禁止登陆!" } else if admin_info.Role.Status == 0 && admin_info.Id != 1 { data["status"] = "0" data["url"] = "/" data["message"] = "所属角色禁止登陆!" } else if username == admin_info.Username && utils.Md5(password) == admin_info.Password { c.Session["UserID"] = fmt.Sprintf("%d", admin_info.Id) c.Flash.Success("登陆成功!欢迎您 " + admin_info.Realname) c.Flash.Out["url"] = "/" //更新登陆时间 admin.UpdateLoginTime(admin_info.Id) //****************************************** //管理员日志 logs := new(models.Logs) desc := "登陆用户名:" + admin_info.Username + "|^|登陆系统!|^|登陆ID:" + fmt.Sprintf("%d", admin_info.Id) logs.Save(admin_info, c.Controller, desc) //***************************************** data["status"] = "1" data["url"] = "/Message/" data["message"] = "登陆成功!" } else { data["status"] = "0" data["url"] = "/" data["message"] = "密码错误!" } return c.RenderJson(data) } }
func Register(w http.ResponseWriter, req *http.Request, ctx *models.Context) error { if ctx.User != nil { http.Redirect(w, req, reverse("logout"), http.StatusSeeOther) return nil } if req.FormValue("csrf_token") != ctx.Session.Values["csrf_token"] { return perform_status(w, req, http.StatusForbidden) } ctx.Data["title"] = "Register" r := (&models.UserForm).Load(req) ctx.Data["result"] = r if len(r.Errors) != 0 { return RegisterForm(w, req, ctx) } u := r.Value.(map[string]interface{}) password1 := u["password1"].(string) if len(password1) < 5 { r.Errors["password1"] = errors.New("Passwords too short (5 chars or more)") } password2 := u["password2"].(string) if password2 != password1 { r.Errors["password2"] = errors.New("Passwords do not match") } gender := u["gender"].(string) if gender != "m" && gender != "f" { r.Errors["gender"] = errors.New("Please select Male or Female") } now := time.Now() oldest := time.Date(now.Year()-120, 1, 1, 0, 0, 0, 0, time.UTC) bDate := u["birthdate"].(time.Time) if bDate.Before(oldest) || bDate.After(now) { r.Errors["birthdate"] = errors.New("Invalid birth date") } if len(r.Errors) != 0 { return RegisterForm(w, req, ctx) } if r.Err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem registering user:"******"captchaId"), req.FormValue("captchaSolution")) { ctx.Session.AddFlash(models.F(models.ERROR, trans("The control numbers do not match!", ctx))) return RegisterForm(w, req, ctx) } pass, err := models.EncryptPassword(u["password1"].(string)) if err != nil { return internal_error(w, req, err.Error()) // bcrypt errors on invalid costs } u["password"] = pass delete(u, "password1") delete(u, "password2") u["_id"] = bson.NewObjectId() u["avatar"] = gravatar.UrlSize(u["email"].(string), 80) if err := ctx.C("users").Insert(u); err != nil { ctx.Session.AddFlash(models.F(models.ERROR, trans("Problem registering user:"******"user"] = u["_id"] ctx.Session.AddFlash(models.F(models.SUCCESS, trans("Welcome to lov3ly.me!", ctx))) http.Redirect(w, req, reverse("index"), http.StatusSeeOther) return nil }
//登陆 func (c *User) Login(admin *models.Admin) revel.Result { if c.Request.Method == "GET" { title := "登陆--GoCMS管理系统" CaptchaId := captcha.NewLen(6) return c.Render(title, CaptchaId) } else { var username string = c.Params.Get("username") var password string = c.Params.Get("password") var captchaId string = c.Params.Get("captchaId") var verify string = c.Params.Get("verify") data := make(map[string]string) if LANG, ok := c.Session["Lang"]; ok { //设置语言 c.Request.Locale = LANG } else { //设置默认语言 c.Request.Locale = "zh" } if !captcha.VerifyString(captchaId, verify) { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("verification_code") return c.RenderJson(data) } if len(username) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_user_name") return c.RenderJson(data) } if len(password) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_password") return c.RenderJson(data) } if len(verify) <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_verification_code") return c.RenderJson(data) } admin_info := admin.GetByName(username) if admin_info.Id <= 0 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("admin_username_error") } else if admin_info.Status == 0 && admin_info.Id != 1 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("admin_forbid_login") } else if admin_info.Role.Status == 0 && admin_info.Id != 1 { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("admin_forbid_role_login") } else if username == admin_info.Username && utils.Md5(password) == admin_info.Password { c.Session["UserID"] = fmt.Sprintf("%d", admin_info.Id) c.Session["Lang"] = admin_info.Lang c.Flash.Success(c.Message("login_success")) c.Flash.Out["url"] = "/" //更新登陆时间 admin.UpdateLoginTime(admin_info.Id) //****************************************** //管理员日志 logs := new(models.Logs) desc := "登陆用户名:" + admin_info.Username + "|^|登陆系统!|^|登陆ID:" + fmt.Sprintf("%d", admin_info.Id) logs.Save(admin_info, c.Controller, desc) //***************************************** data["status"] = "1" data["url"] = "/Message/" data["message"] = c.Message("login_success") } else { data["status"] = "0" data["url"] = "/" data["message"] = c.Message("login_password_error") } return c.RenderJson(data) } }
userkey := strings.TrimLeft(r.URL.Path, "/") userkey = strings.TrimRight(userkey, "/send") // Check URL Key if *debug { log.Printf("\nComparing... \n\t" + userkey + "\n\t" + c.URLKey) } if userkey != c.URLKey { log.Println("Key Mismatch. ", r.UserAgent(), r.RemoteAddr, r.RequestURI+"\n") return false } return true } // verifyCaptcha is a variable func for testing var verifyCaptcha = func(r *http.Request) bool { if !captcha.VerifyString(r.FormValue("captchaId"), r.FormValue("captchaSolution")) { log.Printf("User Error: CAPTCHA %s at %s", r.UserAgent(), r.RemoteAddr) log.Println(r.FormValue("captchaId")) log.Println(r.FormValue("captchaSolution")) return false } return true } func newfortune() string { if len(fortunes) == 0 { return "" } n := rand.Intn(len(fortunes)) log.Println("Fortune #", n) return fortunes[n]
// URL: /signin // 处理用户登录,如果登录成功,设置Cookie func signinHandler(handler *Handler) { // 如果已经登录了,跳转到首页 _, has := currentUser(handler) if has { handler.Redirect("/") } next := handler.Request.FormValue("next") form := wtforms.NewForm( wtforms.NewHiddenField("next", next), wtforms.NewTextField("username", "用户名", "", &wtforms.Required{}), wtforms.NewPasswordField("password", "密码", &wtforms.Required{}), wtforms.NewTextField("captcha", "验证码", "", wtforms.Required{}), wtforms.NewHiddenField("captchaId", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { // 检查验证码 if !captcha.VerifyString(form.Value("captchaId"), form.Value("captcha")) { form.AddError("captcha", "验证码错误") form.SetValue("captcha", "") handler.renderTemplate("account/signin.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } c := handler.DB.C(USERS) user := User{} err := c.Find(bson.M{"username": form.Value("username")}).One(&user) if err != nil { form.AddError("username", "该用户不存在") form.SetValue("captcha", "") handler.renderTemplate("account/signin.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } if !user.IsActive { form.AddError("username", "邮箱没有经过验证,如果没有收到邮件,请联系管理员") form.SetValue("captcha", "") handler.renderTemplate("account/signin.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } if user.Password != encryptPassword(form.Value("password"), user.Salt) { form.AddError("password", "密码和用户名不匹配") form.SetValue("captcha", "") handler.renderTemplate("account/signin.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } session, _ := store.Get(handler.Request, "user") session.Values["username"] = user.Username session.Save(handler.Request, handler.ResponseWriter) if form.Value("next") == "" { http.Redirect(handler.ResponseWriter, handler.Request, "/", http.StatusFound) } else { http.Redirect(handler.ResponseWriter, handler.Request, next, http.StatusFound) } return } } form.SetValue("captcha", "") handler.renderTemplate("account/signin.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) }
// URL: /signup // 处理用户注册,要求输入用户名,密码和邮箱 func signupHandler(handler *Handler) { // 如果已经登录了,跳转到首页 _, has := currentUser(handler) if has { handler.Redirect("/") } var username string var email string session, _ := store.Get(handler.Request, "user") if handler.Request.Method == "GET" { //如果是从新建关联过来的就自动填充字段 if session.Values[GITHUB_PROVIDER] == GITHUB_COM { username = session.Values[GITHUB_ID].(string) email = session.Values[GITHUB_EMAIL].(string) } } form := wtforms.NewForm( wtforms.NewTextField("username", "用户名", username, wtforms.Required{}, wtforms.Regexp{Expr: `^[a-zA-Z0-9_]{3,16}$`, Message: "请使用a-z, A-Z, 0-9以及下划线, 长度3-16之间"}), wtforms.NewPasswordField("password", "密码", wtforms.Required{}), wtforms.NewTextField("email", "电子邮件", email, wtforms.Required{}, wtforms.Email{}), wtforms.NewTextField("captcha", "验证码", "", wtforms.Required{}), wtforms.NewHiddenField("captchaId", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { // 检查验证码 if !captcha.VerifyString(form.Value("captchaId"), form.Value("captcha")) { form.AddError("captcha", "验证码错误") fmt.Println("captcha") form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } c := handler.DB.C(USERS) result := User{} // 检查用户名 err := c.Find(bson.M{"username": form.Value("username")}).One(&result) if err == nil { form.AddError("username", "该用户名已经被注册") form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } // 检查邮箱 err = c.Find(bson.M{"email": form.Value("email")}).One(&result) if err == nil { form.AddError("email", "电子邮件地址已经被注册") form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } c2 := handler.DB.C(STATUS) var status Status c2.Find(nil).One(&status) id := bson.NewObjectId() username := form.Value("username") validateCode := strings.Replace(uuid.NewUUID().String(), "-", "", -1) salt := strings.Replace(uuid.NewUUID().String(), "-", "", -1) index := status.UserIndex + 1 u := &User{ Id_: id, Username: username, Password: encryptPassword(form.Value("password"), salt), Avatar: "", // defaultAvatars[rand.Intn(len(defaultAvatars))], Salt: salt, Email: form.Value("email"), ValidateCode: validateCode, IsActive: true, JoinedAt: time.Now(), Index: index, } if session.Values[GITHUB_PROVIDER] == GITHUB_COM { u.GetGithubValues(session) defer deleteGithubValues(session) } err = c.Insert(u) if err != nil { logger.Println(err) return } c2.Update(nil, bson.M{"$inc": bson.M{"userindex": 1, "usercount": 1}}) // 重新生成users.json字符串 generateUsersJson(handler.DB) // 发送邮件 /* subject := "欢迎加入Golang 中国" message2 := `欢迎加入Golang 中国。请访问下面地址激活你的帐户。 <a href="%s/activate/%s">%s/activate/%s</a> 如果你没有注册,请忽略这封邮件。 ©2012 Golang 中国` message2 = fmt.Sprintf(message2, config["host"], validateCode, config["host"], validateCode) sendMail(subject, message2, []string{form.Value("email")}) message(w, r, "注册成功", "请查看你的邮箱进行验证,如果收件箱没有,请查看垃圾邮件,如果还没有,请给[email protected]发邮件,告知你的用户名。", "success") */ // 注册成功后设成登录状态 session, _ := store.Get(handler.Request, "user") session.Values["username"] = username session.Save(handler.Request, handler.ResponseWriter) // 跳到修改用户信息页面 http.Redirect(handler.ResponseWriter, handler.Request, "/profile", http.StatusFound) return } } form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) }
func (self AccountController) Register(ctx echo.Context) error { if _, ok := ctx.Get("user").(*model.Me); ok { return ctx.Redirect(http.StatusSeeOther, "/") } registerTpl := "register.html" username := ctx.FormValue("username") // 请求注册页面 if username == "" || ctx.Request().Method() != "POST" { return render(ctx, registerTpl, map[string]interface{}{"captchaId": captcha.NewLen(4)}) } data := map[string]interface{}{ "username": username, "email": ctx.FormValue("email"), "captchaId": captcha.NewLen(4), } // 校验验证码 if !captcha.VerifyString(ctx.FormValue("captchaid"), ctx.FormValue("captchaSolution")) { data["error"] = "验证码错误" return render(ctx, registerTpl, data) } if ctx.FormValue("passwd") != ctx.FormValue("pass2") { data["error"] = "两次密码不一致" return render(ctx, registerTpl, data) } fields := []string{"username", "email", "passwd"} form := url.Values{} for _, field := range fields { form.Set(field, ctx.FormValue(field)) } // 入库 errMsg, err := logic.DefaultUser.CreateUser(ctx, form) if err != nil { // bugfix:http://studygolang.com/topics/255 if errMsg == "" { errMsg = err.Error() } data["error"] = errMsg return render(ctx, registerTpl, data) } email := ctx.FormValue("email") uuid := self.genUUID(email) var emailUrl string if strings.HasSuffix(email, "@gmail.com") { emailUrl = "http://mail.google.com" } else { pos := strings.LastIndex(email, "@") emailUrl = "http://mail." + email[pos+1:] } data = map[string]interface{}{ "success": template.HTML(` <div style="padding:30px 30px 50px 30px;"> <div style="color:#339502;font-size:22px;line-height: 2.5;">恭喜您注册成功!</div> 我们已经发送一封邮件到 ` + email + `,请您根据提示信息完成邮箱验证.<br><br> <a href="` + emailUrl + `" target="_blank"><button type="button" class="btn btn-success">立即验证</button></a> <button type="button" class="btn btn-link" data-uuid="` + uuid + `" id="resend_email">未收到?再发一次</button> </div>`), } // 需要检验邮箱的正确性 go logic.DefaultEmail.SendActivateMail(email, uuid) return render(ctx, registerTpl, data) }
// handle new post via http request for a board func (self *httpFrontend) handle_postform(wr http.ResponseWriter, r *http.Request, board string) { // the post we will turn into an nntp article var pr postRequest // do we send json reply? sendJson := r.URL.Query().Get("t") == "json" if sendJson { wr.Header().Add("Content-Type", "text/json; encoding=UTF-8") } // close request body when done defer r.Body.Close() mp_reader, err := r.MultipartReader() if err != nil { wr.WriteHeader(500) if sendJson { json.NewEncoder(wr).Encode(map[string]interface{}{"error": err.Error()}) } else { io.WriteString(wr, err.Error()) } return } pr.Group = board // encrypt IP Addresses // when a post is recv'd from a frontend, the remote address is given its own symetric key that the local srnd uses to encrypt the address with, for privacy // when a mod event is fired, it includes the encrypted IP address and the symetric key that frontend used to encrypt it, thus allowing others to determine the IP address // each stnf will optionally comply with the mod event, banning the address from being able to post from that frontend // this will be done eventually but for now that requires too much infrastrucutre, let's go with regular IP Addresses for now. // get the "real" ip address from the request pr.IpAddress, _, err = net.SplitHostPort(r.RemoteAddr) // TODO: have in config upstream proxy ip and check for that if strings.HasPrefix(pr.IpAddress, "127.") { // if it's loopback check headers for reverse proxy headers // TODO: make sure this isn't a tor user being sneaky pr.IpAddress = getRealIP(r.Header.Get("X-Real-IP")) if pr.IpAddress == "" { // try X-Forwarded-For if X-Real-IP not set ip := r.Header.Get("X-Forwarded-For") parts := strings.Split(ip, ",") ip = parts[0] pr.IpAddress = getRealIP(ip) } } pr.Destination = r.Header.Get("X-I2P-DestHash") pr.Frontend = self.name var captcha_retry bool var captcha_solution, captcha_id string var url string url = fmt.Sprintf("%s-0.html", board) var part_buff bytes.Buffer for { part, err := mp_reader.NextPart() if err == nil { defer part.Close() // get the name of the part partname := part.FormName() // read part for attachment if strings.HasPrefix(partname, "attachment_") && self.attachments { if len(pr.Attachments) < self.attachmentLimit { // TODO: we could just write to disk the attachment so we're not filling ram up with crap att := readAttachmentFromMimePartAndStore(part, nil) if att != nil { log.Println("attaching file...") pr.Attachments = append(pr.Attachments, postAttachment{ Filedata: att.Filedata(), Filename: att.Filename(), Filetype: att.Mime(), }) } } continue } io.Copy(&part_buff, part) // check for values we want if partname == "subject" { pr.Subject = part_buff.String() } else if partname == "name" { pr.Name = part_buff.String() } else if partname == "message" { pr.Message = part_buff.String() } else if partname == "reference" { pr.Reference = part_buff.String() if len(pr.Reference) == 0 { url = fmt.Sprintf("%s-0.html", board) } else { url = fmt.Sprintf("thread-%s.html", HashMessageID(pr.Reference)) } } else if partname == "captcha_id" { captcha_id = part_buff.String() } else if partname == "captcha" { captcha_solution = part_buff.String() } else if partname == "dubs" { pr.Dubs = part_buff.String() == "on" } // we done // reset buffer for reading parts part_buff.Reset() // close our part part.Close() } else { if err != io.EOF { errmsg := fmt.Sprintf("httpfrontend post handler error reading multipart: %s", err) log.Println(errmsg) wr.WriteHeader(500) if sendJson { json.NewEncoder(wr).Encode(map[string]interface{}{"error": errmsg}) } else { io.WriteString(wr, errmsg) } return } break } } if len(captcha_id) == 0 { s, _ := self.store.Get(r, self.name) cid, ok := s.Values["captcha_id"] if ok { captcha_id = cid.(string) } s.Values["captcha_id"] = "" s.Save(r, wr) } if !captcha.VerifyString(captcha_id, captcha_solution) { // captcha is not valid captcha_retry = true } // make error template param resp_map := make(map[string]interface{}) resp_map["prefix"] = self.prefix // set redirect url if len(url) > 0 { // if we explicitly know the url use that resp_map["redirect_url"] = self.prefix + url } else { // if our referer is saying we are from /new/ page use that // otherwise use prefix if strings.HasSuffix(r.Referer(), self.prefix+"new/") { resp_map["redirect_url"] = self.prefix + "new/" } else { resp_map["redirect_url"] = self.prefix } } if captcha_retry { if sendJson { json.NewEncoder(wr).Encode(map[string]interface{}{"error": "bad captcha"}) } else { // retry the post with a new captcha resp_map = make(map[string]interface{}) resp_map["prefix"] = self.prefix resp_map["redirect_url"] = self.prefix + url resp_map["reason"] = "captcha incorrect" io.WriteString(wr, template.renderTemplate("post_fail.mustache", resp_map)) } return } b := func() { if sendJson { wr.WriteHeader(200) json.NewEncoder(wr).Encode(map[string]interface{}{"error": "banned"}) } else { wr.WriteHeader(403) io.WriteString(wr, "banned") } } e := func(err error) { log.Println("frontend error:", err) wr.WriteHeader(200) if sendJson { json.NewEncoder(wr).Encode(map[string]interface{}{"error": err.Error()}) } else { resp_map["reason"] = err.Error() resp_map["prefix"] = self.prefix resp_map["redirect_url"] = self.prefix + url io.WriteString(wr, template.renderTemplate("post_fail.mustache", resp_map)) } } s := func(nntp NNTPMessage) { // send success reply wr.WriteHeader(200) // determine the root post so we can redirect to the thread for it msg_id := nntp.Headers().Get("References", nntp.MessageID()) // render response as success url := fmt.Sprintf("%sthread-%s.html", self.prefix, HashMessageID(msg_id)) if sendJson { json.NewEncoder(wr).Encode(map[string]interface{}{"message_id": nntp.MessageID(), "url": url, "error": nil}) } else { io.WriteString(wr, template.renderTemplate("post_success.mustache", map[string]interface{}{"prefix": self.prefix, "message_id": nntp.MessageID(), "redirect_url": url})) } } self.handle_postRequest(&pr, b, e, s, false) }
// handle new post via http request for a board func (self httpFrontend) handle_postform(wr http.ResponseWriter, r *http.Request, board string) { // always lower case newsgroups board = strings.ToLower(board) // post fail message post_fail := "" // post message msg := "" // the nntp message var nntp nntpArticle nntp.headers = make(ArticleHeaders) // tripcode private key var tripcode_privkey []byte // encrypt IP Addresses // when a post is recv'd from a frontend, the remote address is given its own symetric key that the local srnd uses to encrypt the address with, for privacy // when a mod event is fired, it includes the encrypted IP address and the symetric key that frontend used to encrypt it, thus allowing others to determine the IP address // each stnf will optinally comply with the mod event, banning the address from being able to post from that frontend // this will be done eventually but for now that requires too much infrastrucutre, let's go with regular IP Addresses for now. // get the "real" ip address from the request address, _, err := net.SplitHostPort(r.RemoteAddr) // TODO: have in config upstream proxy ip and check for that if strings.HasPrefix(address, "127.") { // if it's loopback check headers for reverse proxy headers // TODO: make sure this isn't a tor user being sneaky address = getRealIP(r.Header.Get("X-Real-IP")) } // check for banned if len(address) > 0 { banned, err := self.daemon.database.CheckIPBanned(address) if err == nil { if banned { wr.WriteHeader(403) // TODO: ban messages io.WriteString(wr, "nigguh u banned.") return } } else { wr.WriteHeader(500) io.WriteString(wr, "error checking for ban: ") io.WriteString(wr, err.Error()) return } } if len(address) == 0 { address = "Tor" } if !strings.HasPrefix(address, "127.") { // set the ip address of the poster to be put into article headers // if we cannot determine it, i.e. we are on Tor/i2p, this value is not set if address == "Tor" { nntp.headers.Set("X-Tor-Poster", "1") } else { address, err = self.daemon.database.GetEncAddress(address) nntp.headers.Set("X-Encrypted-IP", address) // TODO: add x-tor-poster header for tor exits } } // if we don't have an address for the poster try checking for i2p httpd headers address = r.Header.Get("X-I2P-DestHash") // TODO: make sure this isn't a Tor user being sneaky if len(address) > 0 { nntp.headers.Set("X-I2P-DestHash", address) } // set newsgroup nntp.headers.Set("Newsgroups", board) // redirect url url := "" // mime part handler var part_buff bytes.Buffer mp_reader, err := r.MultipartReader() if err != nil { errmsg := fmt.Sprintf("httpfrontend post handler parse multipart POST failed: %s", err) log.Println(errmsg) wr.WriteHeader(500) io.WriteString(wr, errmsg) return } var subject, name string for { part, err := mp_reader.NextPart() if err == nil { // get the name of the part partname := part.FormName() // read part for attachment if partname == "attachment" && self.attachments { log.Println("attaching file...") att := readAttachmentFromMimePart(part) nntp = nntp.Attach(att).(nntpArticle) continue } io.Copy(&part_buff, part) // check for values we want if partname == "subject" { subject = part_buff.String() } else if partname == "name" { name = part_buff.String() } else if partname == "message" { msg = part_buff.String() } else if partname == "reference" { ref := part_buff.String() if len(ref) == 0 { url = fmt.Sprintf("%s.html", board) } else if ValidMessageID(ref) { if self.daemon.database.HasArticleLocal(ref) { nntp.headers.Set("References", ref) url = fmt.Sprintf("thread-%s.html", ShortHashMessageID(ref)) } else { // no such article url = fmt.Sprintf("%s.html", board) post_fail += "we don't have " post_fail += ref post_fail += "locally, can't reply. " } } else { post_fail += "invalid reference: " post_fail += ref post_fail += ", not posting. " } } else if partname == "captcha" { captcha_solution := part_buff.String() s, err := self.store.Get(r, self.name) captcha_id, ok := s.Values["captcha_id"] if err == nil && ok { if captcha.VerifyString(captcha_id.(string), captcha_solution) { // captcha is valid } else { // captcha is not valid post_fail += "failed captcha. " } } else { // captcha has no cookies post_fail += "enable cookies. " } } // we done // reset buffer for reading parts part_buff.Reset() // close our part part.Close() } else { if err != io.EOF { errmsg := fmt.Sprintf("httpfrontend post handler error reading multipart: %s", err) log.Println(errmsg) wr.WriteHeader(500) io.WriteString(wr, errmsg) return } break } } // make error template param resp_map := make(map[string]string) resp_map["prefix"] = self.prefix // set redirect url if len(url) > 0 { // if we explicitly know the url use that resp_map["redirect_url"] = self.prefix + url } else { // if our referer is saying we are from /new/ page use that // otherwise use prefix if strings.HasSuffix(r.Referer(), self.prefix+"new/") { resp_map["redirect_url"] = self.prefix + "new/" } else { resp_map["redirect_url"] = self.prefix } } if len(nntp.attachments) == 0 && len(msg) == 0 { post_fail += "no message. " } if len(post_fail) > 0 { wr.WriteHeader(200) resp_map["reason"] = post_fail io.WriteString(wr, template.renderTemplate("post_fail.mustache", resp_map)) return } // set subject if len(subject) == 0 { subject = "None" } nntp.headers.Set("Subject", subject) if isSage(subject) { nntp.headers.Set("X-Sage", "1") } // set name if len(name) == 0 { name = "Anonymous" } else { idx := strings.Index(name, "#") // tripcode if idx >= 0 { tripcode_privkey = parseTripcodeSecret(name[idx+1:]) name = strings.Trim(name[:idx], "\t ") if name == "" { name = "Anonymous" } } } nntp.headers.Set("From", nntpSanitize(fmt.Sprintf("%s <anon@%s>", name, self.name))) nntp.headers.Set("Message-ID", genMessageID(self.name)) // set message nntp.message = createPlaintextAttachment(msg) // set date nntp.headers.Set("Date", timeNowStr()) // append path from frontend nntp.AppendPath(self.name) // send message off to daemon log.Printf("uploaded %d attachments", len(nntp.Attachments())) nntp.Pack() // sign if needed if len(tripcode_privkey) == nacl.CryptoSignSeedLen() { nntp, err = signArticle(nntp, tripcode_privkey) if err != nil { // wtf? error!? log.Println("error signing", err) wr.WriteHeader(500) io.WriteString(wr, err.Error()) return } } // XXX: write it temp instead // self.postchan <- nntp f := self.daemon.store.CreateTempFile(nntp.MessageID()) if f != nil { nntp.WriteTo(f, "\n") f.Close() } self.daemon.infeed_load <- nntp.MessageID() // send success reply wr.WriteHeader(200) // determine the root post so we can redirect to the thread for it msg_id := nntp.headers.Get("References", nntp.MessageID()) // render response as success url = fmt.Sprintf("%sthread-%s.html", self.prefix, ShortHashMessageID(msg_id)) io.WriteString(wr, template.renderTemplate("post_success.mustache", map[string]string{"prefix": self.prefix, "message_id": nntp.MessageID(), "redirect_url": url})) }
// URL: /signup // 处理用户注册,要求输入用户名,密码和邮箱 func signupHandler(handler *Handler) { // 如果已经登录了,跳转到首页 _, has := currentUser(handler) if has { handler.Redirect("/") } var username string var email string session, _ := store.Get(handler.Request, "user") if handler.Request.Method == "GET" { //如果是从新建关联过来的就自动填充字段 if session.Values[GITHUB_PROVIDER] == GITHUB_COM { username = session.Values[GITHUB_ID].(string) email = session.Values[GITHUB_EMAIL].(string) } } form := wtforms.NewForm( wtforms.NewTextField("username", "用户名", username, wtforms.Required{}, wtforms.Regexp{Expr: `^[a-zA-Z0-9_]{3,16}$`, Message: "请使用a-z, A-Z, 0-9以及下划线, 长度3-16之间"}), wtforms.NewPasswordField("password", "密码", wtforms.Required{}), wtforms.NewTextField("email", "电子邮件", email, wtforms.Required{}, wtforms.Email{}), wtforms.NewTextField("captcha", "验证码", "", wtforms.Required{}), wtforms.NewHiddenField("captchaId", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { // 检查验证码 if !captcha.VerifyString(form.Value("captchaId"), form.Value("captcha")) { form.AddError("captcha", "验证码错误") fmt.Println("captcha") form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } c := handler.DB.C(USERS) result := User{} // 检查用户名 err := c.Find(bson.M{"username": form.Value("username")}).One(&result) if err == nil { form.AddError("username", "该用户名已经被注册") form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } // 检查邮箱 err = c.Find(bson.M{"email": form.Value("email")}).One(&result) if err == nil { form.AddError("email", "电子邮件地址已经被注册") form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } c2 := handler.DB.C(STATUS) var status Status c2.Find(nil).One(&status) id := bson.NewObjectId() username := form.Value("username") validateCode := strings.Replace(uuid.NewUUID().String(), "-", "", -1) index := status.UserIndex + 1 u := &User{ Id_: id, Username: username, Password: GenPwd(form.Value("password")), Avatar: "", // defaultAvatars[rand.Intn(len(defaultAvatars))], Email: form.Value("email"), ValidateCode: validateCode, IsActive: true, JoinedAt: time.Now(), Index: index, } if session.Values[GITHUB_PROVIDER] == GITHUB_COM { u.GetGithubValues(session) defer deleteGithubValues(session) } err = c.Insert(u) if err != nil { logger.Println(err) return } c2.Update(nil, bson.M{"$inc": bson.M{"userindex": 1, "usercount": 1}}) // 重新生成users.json字符串 generateUsersJson(handler.DB) // 注册成功后设成登录状态 session, _ := store.Get(handler.Request, "user") session.Values["username"] = username session.Save(handler.Request, handler.ResponseWriter) // 跳到修改用户信息页面 handler.redirect("/setting/edit_info", http.StatusFound) return } } form.SetValue("captcha", "") handler.renderTemplate("account/signup.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) }