// GET /captcha/new func GetCaptcha(ctx *macaron.Context, cpt *captcha.Captcha, cache cache.Cache) { // only allow 10 times request in one second cip := ctx.RemoteAddr() times, _ := cache.Get(cip).(int) if times > 10 { ctx.Status(http.StatusForbidden) return } cache.Put(cip, times+1, 1) // create the captcha v, err := cpt.CreateCaptcha() if err != nil { panic(fmt.Errorf("fail to create captcha: %v", err)) } rsp := &rest.CaptchaRsp{ cpt.FieldIdName, v, fmt.Sprintf("%s%s%s.png", cpt.SubURL, cpt.URLPrefix, v), } ctx.JSON(http.StatusOK, rsp) }
// POST /api/user/login func LoginUser(ctx *macaron.Context, as rest.AuthService, cpt *captcha.Captcha) { var ulr rest.UserLoginReq ok := getBody(ctx, &ulr) if !ok { return } if !cpt.Verify(ulr.CaptchaId, ulr.CaptchaValue) { ctx.JSON(http.StatusBadRequest, rest.INVALID_CAPTCHA) return } // check user whether existed u := &models.User{} if err := u.Find(ulr.Email, ulr.Username, ulr.Mobile); err != nil { ctx.JSON(http.StatusNotFound, rest.INVALID_USER) return } // check user password if !tkits.CmpPasswd(ulr.Passwd, u.Salt, u.Password) { ctx.JSON(http.StatusNotFound, rest.INVALID_USER) return } // update ip, time and count for login cip := ctx.RemoteAddr() u.LastLoginTime = time.Now() u.LastLoginIp = cip u.LoginCount += 1 if _, err := u.Update("LastLoginTime", "LastLoginIp", "LoginCount"); err != nil { ctx.JSON(http.StatusInternalServerError, tkits.DB_ERROR) return } // generate a token if token, err := as.GenUserToken(cip, u.Id, 15, rest.TokenUser); err != nil { ctx.JSON(http.StatusInternalServerError, tkits.SYS_ERROR) return } else { rsp := &rest.UserLoginRsp{} rsp.Uid = u.Id rsp.Username = u.Username rsp.Token = token if ulr.CookieMaxAge == 0 { ulr.CookieMaxAge = 60 * 60 * 12 //half of one day } suid := fmt.Sprintf("%v", u.Id) ctx.SetCookie("token", token, ulr.CookieMaxAge) ctx.SetCookie("uid", suid, ulr.CookieMaxAge) ctx.JSON(http.StatusOK, rsp) } }
func NewCaptcha(cpt *captcha.Captcha) *CaptchaInfo { cptvalue, err := cpt.CreateCaptcha() if err != nil { return nil } return &CaptchaInfo{ CaptchaId: cptvalue, CaptchaUrl: fmt.Sprintf("%s%s%s.png", cpt.SubURL, cpt.URLPrefix, cptvalue), } }
//---------------------------------------------------------- // POST /api/account/signup/ func ApiUserSignup(f SignupForm, c *macaron.Context, cpt *captcha.Captcha, a token.TokenService, ss session.Store) { if !a.ValidToken(c.RemoteAddr(), f.CsrfToken) { c.JSON(200, comps.NewRestErrResp(-1, "非法的跨站请求")) return } if !cpt.VerifyReq(c.Req) { c.JSON(200, comps.NewRestResp(comps.NewCaptcha(cpt), -1, "请填写正确的验证码")) return } s := NewService() u, msg, ok := s.Signup(f, c.RemoteAddr()) if !ok { c.JSON(200, comps.NewRestResp(comps.NewCaptcha(cpt), -1, msg)) return } // 如果不需要email验证 if boot.SysSetting.Ra.RegisterValidType == models.RegValidNone || u.GroupId != models.GroupNotValidated || u.ValidEmail { SetSigninCookies(c, u, a, ss) c.JSON(200, comps.NewRestRedirectResp("/h/firstlogin")) return } ss.Set("validemail", u.Email) if !models.NewValidByEmail(models.NewTr(), u.Id, u.Email) { c.JSON(200, comps.NewRestErrResp(-1, "内部系统错误")) return } SetSigninCookies(c, u, a, ss) c.JSON(200, comps.NewRestRedirectResp("/a/validemail/")) return }
func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { ctx.Data["Title"] = ctx.Tr("sign_up") ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha if setting.Service.DisableRegistration { ctx.Error(403) return } if ctx.HasError() { ctx.HTML(200, SIGNUP) return } if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) { ctx.Data["Err_Captcha"] = true ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), SIGNUP, &form) return } if form.Password != form.Retype { ctx.Data["Err_Password"] = true ctx.RenderWithErr(ctx.Tr("form.password_not_match"), SIGNUP, &form) return } u := &models.User{ Name: form.UserName, Email: form.Email, Passwd: form.Password, IsActive: !setting.Service.RegisterEmailConfirm, } if err := models.CreateUser(u); err != nil { switch { case models.IsErrUserAlreadyExist(err): ctx.Data["Err_UserName"] = true ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SIGNUP, &form) case models.IsErrEmailAlreadyUsed(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SIGNUP, &form) case models.IsErrNameReserved(err): ctx.Data["Err_UserName"] = true ctx.RenderWithErr(ctx.Tr("user.form.name_reserved", err.(models.ErrNameReserved).Name), SIGNUP, &form) case models.IsErrNamePatternNotAllowed(err): ctx.Data["Err_UserName"] = true ctx.RenderWithErr(ctx.Tr("user.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), SIGNUP, &form) default: ctx.Handle(500, "CreateUser", err) } return } log.Trace("Account created: %s", u.Name) // Auto-set admin for the only user. if models.CountUsers() == 1 { u.IsAdmin = true u.IsActive = true if err := models.UpdateUser(u); err != nil { ctx.Handle(500, "UpdateUser", err) return } } // Send confirmation e-mail, no need for social account. if setting.Service.RegisterEmailConfirm && u.Id > 1 { mailer.SendActivateAccountMail(ctx.Context, u) ctx.Data["IsSendRegisterMail"] = true ctx.Data["Email"] = u.Email ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60 ctx.HTML(200, ACTIVATE) if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { log.Error(4, "Set cache(MailResendLimit) fail: %v", err) } return } ctx.Redirect(setting.AppSubUrl + "/user/login") }
// POST /api/user/signup func AddUser(ctx *macaron.Context, as rest.AuthService, cpt *captcha.Captcha) { var uar rest.UserAddReq ok := getBody(ctx, &uar) if !ok { return } log.Debugf("retrive CaptchaId = %s, CaptchaValue= %s", uar.CaptchaId, uar.CaptchaValue) if !cpt.Verify(uar.CaptchaId, uar.CaptchaValue) { ctx.JSON(http.StatusBadRequest, rest.INVALID_CAPTCHA) return } valid := validation.Validation{} valid.Email(uar.Email, "Email") valid.Match(uar.Username, rest.ValidPasswd, "Username").Message(rest.UsernamePrompt) valid.Match(uar.Passwd, rest.ValidPasswd, "Passwd").Message(rest.PasswdPrompt) if !validMember(ctx, &valid) { return } // check user whether existed u := &models.User{} if err := u.Find(uar.Email, uar.Username, ""); err != orm.ErrNoRows { ctx.JSON(http.StatusBadRequest, rest.INVALID_SIGNUP) return } // check reserve users if _, ok := rest.ReserveUsers[uar.Username]; ok { ctx.JSON(http.StatusBadRequest, rest.INVALID_SIGNUP) return } // generate password mask pwd, salt := tkits.GenPasswd(uar.Passwd, 8) u.Salt = salt u.Password = pwd u.Updated = time.Now() u.Username = uar.Username u.Email = uar.Email if id, err := u.Insert(); err != nil { ctx.JSON(http.StatusInternalServerError, tkits.DB_ERROR) return } else { u.Id = id } // generate a token if token, err := as.GenUserToken(ctx.RemoteAddr(), u.Id, 15, rest.TokenUser); err != nil { ctx.JSON(http.StatusInternalServerError, tkits.SYS_ERROR) return } else { rsp := &rest.UserAddRsp{u.Id, u.Username, token} // set some cookies if uar.CookieMaxAge == 0 { uar.CookieMaxAge = 60 * 60 * 12 //half of one day } suid := fmt.Sprintf("%v", u.Id) ctx.SetCookie("token", token, uar.CookieMaxAge) ctx.SetCookie("uid", suid, uar.CookieMaxAge) ctx.JSON(http.StatusOK, rsp) } }