예제 #1
0
파일: auth.go 프로젝트: henyouqian/grid
func authNewApp(w http.ResponseWriter, r *http.Request) {
	lwutil.CheckMathod(r, "POST")

	session, err := findSession(w, r, nil)
	lwutil.CheckError(err, "err_auth")
	checkAdmin(session)

	// input
	var input struct {
		Name string
	}
	err = lwutil.DecodeRequestBody(r, &input)
	lwutil.CheckError(err, "err_decode_body")

	if input.Name == "" {
		lwutil.SendError("err_input", "input.Name empty")
	}

	// db
	stmt, err := authDB.Prepare("INSERT INTO apps (name, secret) VALUES (?, ?)")
	lwutil.CheckError(err, "")

	secret := lwutil.GenUUID()
	_, err = stmt.Exec(input.Name, secret)
	lwutil.CheckError(err, "err_name_exists")

	// reply
	reply := struct {
		Name   string
		Secret string
	}{input.Name, secret}
	lwutil.WriteResponse(w, reply)
}
예제 #2
0
파일: auth.go 프로젝트: henyouqian/grid
func newSession(w http.ResponseWriter, userid uint64, username string, appid uint32, rc redis.Conn) (usertoken string, err error) {
	if rc == nil {
		rc = redisPool.Get()
		defer rc.Close()
	}
	usertoken = ""
	usertokenRaw, err := rc.Do("get", fmt.Sprintf("usertokens/%d+%d", userid, appid))
	lwutil.CheckError(err, "")
	if usertokenRaw != nil {
		if usertoken, err := redis.String(usertokenRaw, err); err != nil {
			return usertoken, lwutil.NewErr(err)
		}
		rc.Do("del", fmt.Sprintf("sessions/%s", usertoken))
	}

	usertoken = lwutil.GenUUID()

	session := Session{userid, username, time.Now(), appid}
	jsonSession, err := json.Marshal(session)
	if err != nil {
		return usertoken, lwutil.NewErr(err)
	}

	rc.Send("setex", fmt.Sprintf("sessions/%s", usertoken), sessionLifeSecond, jsonSession)
	rc.Send("setex", fmt.Sprintf("usertokens/%d+%d", userid, appid), sessionLifeSecond, usertoken)
	rc.Flush()
	for i := 0; i < 2; i++ {
		if _, err = rc.Receive(); err != nil {
			return usertoken, lwutil.NewErr(err)
		}
	}

	// cookie
	http.SetCookie(w, &http.Cookie{Name: "usertoken", Value: usertoken, MaxAge: sessionLifeSecond, Path: "/"})

	return usertoken, err
}
예제 #3
0
파일: match.go 프로젝트: henyouqian/matches
func startMatch(w http.ResponseWriter, r *http.Request) {
	lwutil.CheckMathod(r, "POST")

	rc := redisPool.Get()
	defer rc.Close()

	session, err := findSession(w, r, rc)
	lwutil.CheckError(err, "err_auth")

	appid := session.Appid
	if appid == 0 {
		lwutil.SendError("err_auth", "Please login with app secret")
	}

	//input
	var in struct {
		MatchId uint32
	}
	err = lwutil.DecodeRequestBody(r, &in)
	lwutil.CheckError(err, "err_decode_body")

	//get match info
	key := fmt.Sprintf("%d+%d", appid, in.MatchId)
	matchJson, err := redis.Bytes(rc.Do("hget", "matches", key))
	lwutil.CheckError(err, "err_not_found")

	var match Match
	err = json.Unmarshal(matchJson, &match)
	lwutil.CheckError(err, "")

	//check time
	now := time.Now().Unix()
	if now < match.Begin || now >= match.End-MATCH_TRY_DURATION_SEC {
		lwutil.SendError("err_time", "now < match.Begin || now >= match.End-MATCH_TRY_DURATION_SEC")
	}

	//incr and check try number
	tryNumKey := makeTryNumKey(in.MatchId)
	tryNum, err := redis.Int(rc.Do("hget", tryNumKey, session.Userid))
	if err != nil && err != redis.ErrNil {
		lwutil.CheckError(err, "")
	}
	if uint32(tryNum) >= match.TryMax {
		lwutil.SendError("err_no_try", "no try left")
	}
	_, err = rc.Do("hincrby", tryNumKey, session.Userid, 1)
	lwutil.CheckError(err, "")
	tryNum++

	//new try secret
	trySecret := lwutil.GenUUID()
	_, err = rc.Do("setex", fmt.Sprintf("trySecrets/%s", trySecret), MATCH_TRY_DURATION_SEC, in.MatchId)
	lwutil.CheckError(err, "")

	//out
	out := struct {
		Secret string
		TryNum uint32
	}{trySecret, uint32(tryNum)}
	lwutil.WriteResponse(w, out)
}