// TODO return more detailed error number // NOTE: this will do a fully update, so the user must be read from DB, and then update its field func UpdateUser(user *User) int { o := orm.NewOrm() err := o.Begin() if err != nil { beego.Warning("UpdateUser fail: ", err) return utils.ERROR_CODE_SYSTEM_ERROR } var errNum int for i := 0; i < DB_UNIQUE_CONFLICT_TRY; i++ { user.UpdateAt = utils.GetTimeMillis() errNum = updateUserInternal(&o, user) if errNum == 0 { break } time.Sleep(1 * time.Millisecond) } if errNum > 0 { o.Rollback() return errNum } else { err = o.Commit() if err != nil { beego.Warning("UpdateUser fail: commit fail ", err) o.Rollback() return utils.ERROR_CODE_SYSTEM_ERROR } } return 0 }
func VerifyUserByPhone(phone *string, secret string) (*User, int) { utils.AssertNotEmptyString(phone) o := orm.NewOrm() user := User{Phone: phone} err := o.Read(&user, "Phone") if err != nil { return nil, utils.ERROR_CODE_USERS_USER_NOT_EXISTS } if utils.Secret2Password("phone:"+*phone, secret) != user.Password { return nil, utils.ERROR_CODE_TOKENS_PASSWORD_MISMATCH } for i := 0; i < DB_UNIQUE_CONFLICT_TRY; i++ { user.Token = utils.GenToken() user.UpdateAt = utils.GetTimeMillis() _, err = o.Update(&user) if err == nil { return &user, 0 } time.Sleep(1 * time.Millisecond) } beego.Warning("VerifyUser, update token fail: ", err) return nil, utils.ERROR_CODE_SYSTEM_ERROR }
func TestMysqlLikeSearch(t *testing.T) { initORM() o := orm.NewOrm() user1 := models.User{Uid: utils.GenUid(), Token: utils.GenToken(), CreateAt: utils.GetTimeMillis(), Nickname: "张三李四", UpdateAt: utils.GetTimeMillis() + 5} _, err := o.Insert(&user1) assert.Nil(t, err) user2 := models.User{Uid: utils.GenUid(), Token: utils.GenToken(), CreateAt: utils.GetTimeMillis() + 10, Nickname: "张李三四", UpdateAt: utils.GetTimeMillis() + 15} _, err = o.Insert(&user2) assert.Nil(t, err) var users *[]models.User users = new([]models.User) num, err := o.QueryTable(new(models.User)).Filter("Nickname__contains", "张三").All(users) assert.Nil(t, err) assert.Equal(t, int64(1), num) assertUserEquals(t, &user1, &((*users)[0])) deleteUser(t, user1.Id) deleteUser(t, user2.Id) }
func TestCreateUserByPhone(t *testing.T) { initORM() phone := "18801234567" secret := "8428d916f8cca9ba5971bf58b34d38da20bc3dff" password := "******" // insert one user, err := models.CreateUserByPhone(&phone, secret) assert.NotNil(t, user) assert.Zero(t, err) assert.Empty(t, user.Nickname) assert.True(t, user.Uid >= utils.USER_MIN_UID) assert.Equal(t, password, user.Password) assert.True(t, len(user.Token) == 40) assert.True(t, utils.AreStringEquals(user.Phone, &phone)) now := utils.GetTimeMillis() assert.True(t, now-1000 < user.CreateAt) assert.True(t, user.CreateAt < now+1000) // get it by phone getByPhone, err := models.GetUserByUid(user.Uid) assert.Zero(t, err) assertUserEquals(t, user, getByPhone) // get it by uid getByUid, err := models.GetUserByUid(user.Uid) assert.Zero(t, err) assertUserEquals(t, user, getByUid) // get it by token getByToken, err := models.GetUserByToken(user.Token) assert.Zero(t, err) assertUserEquals(t, user, getByToken) // clean up deleteUser(t, user.Id) // no such user after delete user, err = models.GetUserByUid(user.Uid) assert.Nil(t, user) assert.Equal(t, utils.ERROR_CODE_USERS_USER_NOT_EXISTS, err) }
func CreateUserByPhone(phone *string, secret string) (*User, int) { utils.AssertNotEmptyString(phone) o := orm.NewOrm() password := utils.Secret2Password("phone:"+*phone, secret) user := User{Phone: phone, Password: password} var err error for i := 0; i < DB_UNIQUE_CONFLICT_TRY; i++ { user.Uid = utils.GenUid() user.Token = utils.GenToken() now := utils.GetTimeMillis() user.CreateAt = now user.UpdateAt = now _, err = o.Insert(&user) if err == nil { return &user, 0 } time.Sleep(1 * time.Millisecond) } beego.Warning("CreateUser fail: ", err) return nil, utils.ERROR_CODE_SYSTEM_ERROR }
// callee's duty to commit & rollback func createOrUpdateUserInternal(o *orm.Ormer, user *User, authUser *utils.AuthUserInfo, logTag string, platform int) (*User, int) { if user != nil { if utils.IsLegalRestrictedStringWithLength(authUser.Nickname, utils.USER_NICKNAME_MEX_LEN) { user.Nickname = authUser.Nickname } user.Avatar = authUser.Avatar user.Gender = authUser.Gender switch platform { case utils.SNS_PLATFORM_WEIXIN: user.WeiXinNickName = authUser.Nickname case utils.SNS_PLATFORM_WEIBO: user.WeiBoNickName = authUser.Nickname case utils.SNS_PLATFORM_QQ: user.QQNickName = authUser.Nickname } var err int for i := 0; i < DB_UNIQUE_CONFLICT_TRY; i++ { user.Token = utils.GenToken() user.UpdateAt = utils.GetTimeMillis() err = updateUserInternal(o, user) if err == 0 { return user, 0 } time.Sleep(1 * time.Millisecond) } beego.Warning(logTag, err) return nil, utils.ERROR_CODE_SYSTEM_ERROR } user = &User{Gender: authUser.Gender, Avatar: authUser.Avatar} if utils.IsLegalRestrictedStringWithLength(authUser.Nickname, utils.USER_NICKNAME_MEX_LEN) { user.Nickname = authUser.Nickname } switch platform { case utils.SNS_PLATFORM_WEIXIN: user.WeiXin = &authUser.Openid user.WeiXinNickName = authUser.Nickname case utils.SNS_PLATFORM_WEIBO: user.WeiBo = &authUser.Openid user.WeiBoNickName = authUser.Nickname case utils.SNS_PLATFORM_QQ: user.QQ = &authUser.Openid user.QQNickName = authUser.Nickname } var err error for i := 0; i < DB_UNIQUE_CONFLICT_TRY; i++ { user.Uid = utils.GenUid() user.Token = utils.GenToken() now := utils.GetTimeMillis() user.CreateAt = now user.UpdateAt = now _, err = (*o).Insert(user) if err == nil { return user, 0 } time.Sleep(1 * time.Millisecond) } beego.Warning(logTag, err) return nil, utils.ERROR_CODE_SYSTEM_ERROR }