Exemple #1
0
func unbindQQ(userId int64) (err error) {
	para := struct {
		UserId      int64    `sqlx:"user_id"`
		NotBindType BindType `sqlx:"not_bind_type"`
	}{
		UserId:      userId,
		NotBindType: BindTypeMask &^ BindTypeQQ,
	}

	tx, err := db.GetDB().Beginx()
	if err != nil {
		return
	}

	// user_qq 表删除一个 item
	stmt1, err := tx.Prepare("delete from user_qq where user_id=? and verified=1")
	if err != nil {
		tx.Rollback()
		return
	}
	rslt1, err := stmt1.Exec(para.UserId)
	if err != nil {
		tx.Rollback()
		return
	}
	rowsAffected1, err := rslt1.RowsAffected()
	if err != nil {
		tx.Rollback()
		return
	}

	// user 更新 item
	stmt2, err := tx.PrepareNamed("update user set bind_types = bind_types&:not_bind_type where id=:user_id and verified=1 and bind_types&:not_bind_type<>0")
	if err != nil {
		tx.Rollback()
		return
	}
	rslt2, err := stmt2.Exec(para)
	if err != nil {
		tx.Rollback()
		return
	}
	rowsAffected2, err := rslt2.RowsAffected()
	if err != nil {
		tx.Rollback()
		return
	}

	if rowsAffected1 != rowsAffected2 {
		err = fmt.Errorf("用户 %d 解绑QQ失败", para.UserId)
		tx.Rollback()
		return
	}

	err = tx.Commit()
	return
}
Exemple #2
0
func bindWeibo(userId int64, openid string) (err error) {
	para := struct {
		UserId   int64    `sqlx:"user_id"`
		OpenId   string   `sqlx:"openid"`
		BindType BindType `sqlx:"bind_type"`
	}{
		UserId:   userId,
		OpenId:   openid,
		BindType: BindTypeWeibo,
	}

	tx, err := db.GetDB().Beginx()
	if err != nil {
		return
	}

	// user_weibo 表增加一个 item
	stmt1, err := tx.Prepare("insert into user_weibo(user_id, openid, verified) values(?, ?, 1)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt1.Exec(para.UserId, para.OpenId); err != nil {
		tx.Rollback()
		return
	}

	// user 更新 item
	stmt2, err := tx.PrepareNamed("update user set bind_types = bind_types|:bind_type where id=:user_id and verified=1 and bind_types&:bind_type=0")
	if err != nil {
		tx.Rollback()
		return
	}
	rslt2, err := stmt2.Exec(para)
	if err != nil {
		tx.Rollback()
		return
	}
	rowsAffected2, err := rslt2.RowsAffected()
	if err != nil {
		tx.Rollback()
		return
	}
	if rowsAffected2 != 1 {
		err = fmt.Errorf("绑定微博 %s 到用户 %d 失败", para.OpenId, para.UserId)
		tx.Rollback()
		return
	}

	err = tx.Commit()
	return
}
Exemple #3
0
// 通过 邮箱 注册一个账户.
//  如果 nickname 为空, 则默认为 email
//  验证码注册时, password, salt 可以为 nil
//  如果 timestamp == 0 则默认使用当前时间
func AddByEmail(email, nickname string, password, salt []byte, timestamp int64) (userId int64, err error) {
	userId, err = userid.GetId()
	if err != nil {
		return
	}

	if nickname == "" {
		nickname = email
	}
	if password == nil {
		password = emptyByteSlice
	}
	if salt == nil {
		salt = emptyByteSlice
	}
	if timestamp == 0 {
		timestamp = time.Now().Unix()
	}

	para := struct {
		UserId      int64    `sqlx:"user_id"`
		BindType    BindType `sqlx:"bind_type"`
		Email       string   `sqlx:"email"`
		Nickname    string   `sqlx:"nickname"`
		Password    []byte   `sqlx:"password"`
		PasswordTag []byte   `sqlx:"password_tag"`
		Salt        []byte   `sqlx:"salt"`
		CreateTime  int64    `sqlx:"create_time"`
	}{
		UserId:      userId,
		BindType:    BindTypeEmail,
		Email:       email,
		Nickname:    nickname,
		Password:    password,
		PasswordTag: random.NewRandomEx(),
		Salt:        salt,
		CreateTime:  timestamp,
	}

	tx, err := db.GetDB().Beginx()
	if err != nil {
		return
	}

	// user_email 表增加一个 item
	stmt1, err := tx.Prepare("insert into user_email(user_id, email, verified) values(?, ?, 0)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt1.Exec(para.UserId, para.Email); err != nil {
		tx.Rollback()
		return
	}

	// user 表增加一个 item
	stmt2, err := tx.PrepareNamed("insert into user(id, nickname, bind_types, password, password_tag, salt, create_time, verified) values(:user_id, :nickname, :bind_type, :password, :password_tag, :salt, :create_time, 0)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt2.Exec(para); err != nil {
		tx.Rollback()
		return
	}

	err = tx.Commit()
	return
}
Exemple #4
0
func bindEmailUserTo(toUserId, userId int64) (err error) {
	if toUserId == userId {
		return errors.New("toUserId 不能等于 userId")
	}

	para := struct {
		ToUserId int64    `sqlx:"to_user_id"`
		UserId   int64    `sqlx:"user_id"`
		BindType BindType `sqlx:"bind_type"`
	}{
		ToUserId: toUserId,
		UserId:   userId,
		BindType: BindTypeEmail,
	}

	tx, err := db.GetDB().Beginx()
	if err != nil {
		return
	}

	// user 更新 ToUserId
	stmt1, err := tx.PrepareNamed("update user set bind_types = bind_types|:bind_type where id=:to_user_id and verified=1 and bind_types&:bind_type=0")
	if err != nil {
		tx.Rollback()
		return
	}
	rslt1, err := stmt1.Exec(para)
	if err != nil {
		tx.Rollback()
		return
	}
	rowsAffected1, err := rslt1.RowsAffected()
	if err != nil {
		tx.Rollback()
		return
	}

	// user 删除 UserId
	stmt2, err := tx.PrepareNamed("delete from user where id=:user_id and verified=0 and bind_types=:bind_type")
	if err != nil {
		tx.Rollback()
		return
	}
	rslt2, err := stmt2.Exec(para)
	if err != nil {
		tx.Rollback()
		return
	}
	rowsAffected2, err := rslt2.RowsAffected()
	if err != nil {
		tx.Rollback()
		return
	}

	// user_email 更新 item
	stmt3, err := tx.PrepareNamed("update user_email set user_id=:to_user_id, verified=1 where user_id=:user_id and verified=0")
	if err != nil {
		tx.Rollback()
		return
	}
	rslt3, err := stmt3.Exec(para)
	if err != nil {
		tx.Rollback()
		return
	}
	rowsAffected3, err := rslt3.RowsAffected()
	if err != nil {
		tx.Rollback()
		return
	}

	if rowsAffected1 != rowsAffected2 || rowsAffected1 != rowsAffected3 {
		err = fmt.Errorf("绑定用户 %d 到用户 %d 失败", para.UserId, para.ToUserId)
		tx.Rollback()
		return
	}

	err = tx.Commit()
	return
}
Exemple #5
0
// 通过 微信 注册一个账户.
//  如果 nickname 为空, 则默认为 openid
//  如果 timestamp == 0 则默认使用当前时间
func AddByWechat(openid, nickname string, timestamp int64) (userId int64, err error) {
	userId, err = userid.GetId()
	if err != nil {
		return
	}

	if nickname == "" {
		nickname = openid
	}
	if timestamp == 0 {
		timestamp = time.Now().Unix()
	}

	para := struct {
		UserId      int64    `sqlx:"user_id"`
		BindType    BindType `sqlx:"bind_type"`
		OpenId      string   `sqlx:"openid"`
		Nickname    string   `sqlx:"nickname"`
		Password    []byte   `sqlx:"password"`
		PasswordTag []byte   `sqlx:"password_tag"`
		Salt        []byte   `sqlx:"salt"`
		CreateTime  int64    `sqlx:"create_time"`
	}{
		UserId:      userId,
		BindType:    BindTypeWechat,
		OpenId:      openid,
		Nickname:    nickname,
		Password:    emptyByteSlice,
		PasswordTag: random.NewRandomEx(),
		Salt:        emptyByteSlice,
		CreateTime:  timestamp,
	}

	tx, err := db.GetDB().Beginx()
	if err != nil {
		return
	}

	// user_wechat 表增加一个 item
	stmt1, err := tx.Prepare("insert into user_wechat(user_id, openid, verified) values(?, ?, 0)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt1.Exec(para.UserId, para.OpenId); err != nil {
		tx.Rollback()
		return
	}

	// user 表增加一个 item
	stmt2, err := tx.PrepareNamed("insert into user(id, nickname, bind_types, password, password_tag, salt, create_time, verified) values(:user_id, :nickname, :bind_type, :password, :password_tag, :salt, :create_time, 0)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt2.Exec(para); err != nil {
		tx.Rollback()
		return
	}

	err = tx.Commit()
	return
}
Exemple #6
0
// 通过 微博 注册一个账户.
//  如果 nickname 为空, 则默认为 openid
//  如果 timestamp == 0 则默认使用当前时间
func AddByWeibo(openid, nickname string, timestamp int64) (user *User, err error) {
	userId, err := userid.GetId()
	if err != nil {
		return
	}

	if nickname == "" {
		nickname = openid
	}
	if timestamp == 0 {
		timestamp = time.Now().Unix()
	}

	para := struct {
		UserId      int64    `sqlx:"user_id"`
		BindType    BindType `sqlx:"bind_type"`
		OpenId      string   `sqlx:"openid"`
		Nickname    string   `sqlx:"nickname"`
		Password    []byte   `sqlx:"password"`
		PasswordTag string   `sqlx:"password_tag"`
		Salt        []byte   `sqlx:"salt"`
		CreateTime  int64    `sqlx:"create_time"`
		Verified    bool     `sqlx:"verified"`
	}{
		UserId:      userId,
		BindType:    BindTypeWeibo,
		OpenId:      openid,
		Nickname:    nickname,
		Password:    emptyByteSlice,
		PasswordTag: NewPasswordTag(),
		Salt:        emptyByteSlice,
		CreateTime:  timestamp,
		Verified:    defaultVerified,
	}

	tx, err := db.GetDB().Beginx()
	if err != nil {
		return
	}

	// user_weibo 表增加一个 item
	stmt1, err := tx.Prepare("insert into user_weibo(user_id, openid, verified) values(?, ?, ?)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt1.Exec(para.UserId, para.OpenId, para.Verified); err != nil {
		tx.Rollback()
		return
	}

	// user 表增加一个 item
	stmt2, err := tx.PrepareNamed("insert into user(id, nickname, bind_types, password, password_tag, salt, create_time, verified) values(:user_id, :nickname, :bind_type, :password, :password_tag, :salt, :create_time, :verified)")
	if err != nil {
		tx.Rollback()
		return
	}
	if _, err = stmt2.Exec(para); err != nil {
		tx.Rollback()
		return
	}

	if err = tx.Commit(); err != nil {
		return
	}

	user = &User{
		Id:          para.UserId,
		Nickname:    para.Nickname,
		BindTypes:   para.BindType,
		Password:    para.Password,
		PasswordTag: para.PasswordTag,
		Salt:        para.Salt,
		CreateTime:  para.CreateTime,
		Verified:    para.Verified,
	}
	return
}