Example #1
0
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)
}
Example #2
0
// 校验验证码
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("验证码错误"))
	}
}
Example #3
0
// 用户登录表单提交
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
		}
	}

}
Example #4
0
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>")
}
Example #5
0
// 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
}
Example #6
0
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 {
		}
	}
}
Example #7
0
/*
	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
}
Example #8
0
// 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)

}
Example #9
0
// 用户注册表单提交
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
}
Example #10
0
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")
	}
}
Example #11
0
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": "用户名或密码错误"}))
		}
	}
}
Example #12
0
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
	}
}
Example #13
0
// 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)
	}
}
Example #14
0
// 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
}
Example #15
0
// 用户注册
// 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":"注册成功"}`)
}
Example #16
0
// 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)
}
Example #17
0
//登陆
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)
	}
}
Example #18
0
func CheckCaptcha(r *http.Request) bool {
	return captcha.VerifyString(r.FormValue("captchaId"), r.FormValue("captchaSolution"))
}
Example #19
0
/* 注册 */
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()
}
Example #20
0
File: user.go Project: qmdx/GoCMS
//登陆
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)
	}
}
Example #21
0
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
}
Example #22
0
//登陆
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)
	}
}
Example #23
0
	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]
Example #24
0
// 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()})
}
Example #25
0
// 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()})
}
Example #26
0
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>&nbsp;&nbsp;<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)
}
Example #27
0
// 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)
}
Example #28
0
// 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}))
}
Example #29
0
File: account.go Project: nosqldb/G
// 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()})
}