Пример #1
0
func (c *Controller) AvailableKeys() (string, error) {

	var email string
	if c.Community {
		// если это пул, то будет прислан email
		email = c.r.FormValue("email")
		if !utils.ValidateEmail(email) {
			return utils.JsonAnswer("Incorrect email", "error").String(), nil
		}
		// если мест в пуле нет, то просто запишем юзера в очередь
		pool_max_users, err := c.Single("SELECT pool_max_users FROM config").Int()
		if err != nil {
			return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
		}
		if len(c.CommunityUsers) >= pool_max_users {
			err = c.ExecSql("INSERT INTO pool_waiting_list ( email, time, user_id ) VALUES ( ?, ?, ? )", email, utils.Time(), 0)
			if err != nil {
				return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
			}
			return utils.JsonAnswer(c.Lang["pool_is_full"], "error").String(), nil
		}
	}

	availablekey := &availablekey.AvailablekeyStruct{}
	availablekey.DCDB = c.DCDB
	availablekey.Email = email
	userId, publicKey, err := availablekey.GetAvailableKey()
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}
	if userId > 0 {
		c.sess.Set("user_id", userId)
		c.sess.Set("public_key", publicKey)
		log.Debug("user_id: %d", userId)
		log.Debug("public_key: %s", publicKey)
		return utils.JsonAnswer("success", "success").String(), nil
	}
	return utils.JsonAnswer("no_available_keys", "error").String(), nil
}
Пример #2
0
func FirstChangePkey(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "FirstChangePkey"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if utils.Mobile() {
		d.sleepTime = 360
	} else {
		d.sleepTime = 60
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		community, err := d.GetCommunityUsers()
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		var uids []int64
		if len(community) > 0 {
			uids = community
		} else {
			myuid, err := d.GetMyUserId("")
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			uids = append(uids, myuid)
		}
		log.Debug("uids %v", uids)
		var status, myPrefix string
		for _, uid := range uids {
			if len(community) > 0 {
				myPrefix = utils.Int64ToStr(uid) + "_"
			}
			status, err = d.Single(`SELECT status FROM ` + myPrefix + `my_table`).String()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			log.Debug("status: %v / myPrefix: %v", status, myPrefix)
			if status == "waiting_accept_new_key" {

				// если ключ кто-то сменил
				userPublicKey, err := d.GetUserPublicKey(uid)
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				myUserPublicKey, err := d.GetMyPublicKey(myPrefix)
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				if !bytes.Equal(myUserPublicKey, []byte(userPublicKey)) {
					log.Debug("myUserPublicKey:%s != userPublicKey:%s", utils.BinToHex(myUserPublicKey), utils.BinToHex(userPublicKey))
					// удаляем старый ключ
					err = d.ExecSql(`DELETE FROM ` + myPrefix + `my_keys`)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					// и user_id
					q := `UPDATE ` + myPrefix + `my_table SET status="my_pending", user_id=0`
					if len(community) > 0 {
						q = `DELETE FROM ` + myPrefix + `my_table`
					}
					err = d.ExecSql(q)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					if len(community) > 0 {
						err = d.ExecSql(`DELETE FROM community WHERE user_id = ?`, uid)
						if err != nil {
							if d.dPrintSleep(err, d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
					}
					// и пробуем взять новый
					availablekey := &availablekey.AvailablekeyStruct{}
					availablekey.DCDB = d.DCDB
					userId, _, err := availablekey.GetAvailableKey()
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					if userId > 0 {
						if len(community) > 0 {
							err = d.ExecSql(`INSERT INTO community (user_id) VALUES (?)`, userId)
							if err != nil {
								if d.dPrintSleep(err, d.sleepTime) {
									break BEGIN
								}
								continue BEGIN
							}
						}
						// генерим и шлем новую тр-ию
						err = d.SendTxChangePkey(userId)
						if err != nil {
							if d.dPrintSleep(err, d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
					} else {
						// если userId == 0, значит ключей в паблике больше нет и юзеру придется искать ключ самому
						continue
					}
				}

				// проверим, не прошла ли тр-ия и не сменился ли уже ключ
				userPubKeyCount, err := d.Single(`SELECT count(*) FROM ` + myPrefix + `my_keys WHERE status='approved'`).Int64()
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				log.Debug("userPubKey: %v", userPubKeyCount)
				if userPubKeyCount > 1 {
					err = d.ExecSql(`UPDATE ` + myPrefix + `my_table SET status='user'`)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					// также, если это пул, то надо удалить приватный ключ из базы данных, т.к. взлом пула будет означать угон всех акков
					// хранение ключа на мобильном - безопасно, хранение ключа на ПК, пока Dcoin не стал популярен, тоже допустимо
					if len(community) > 0 {
						err = d.ExecSql(`DELETE private_key FROM ` + myPrefix + `my_keys`)
						if err != nil {
							if d.dPrintSleep(err, d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
					}

					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}

				lastTx, err := d.GetLastTx(uid, utils.TypesToIds([]string{"ChangePrimaryKey"}), 1, "2006-02-01 15:04:05")
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				log.Debug("lastTx: %v", lastTx)
				if len(lastTx) > 0 {
					if len(lastTx[0]["error"]) > 0 || utils.Time()-utils.StrToInt64(lastTx[0]["time_int"]) > 1800 {
						// генерим и шлем новую тр-ию
						err = d.SendTxChangePkey(uid)
						if err != nil {
							if d.dPrintSleep(err, d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
					}
				}
			}
		}

		if d.dSleep(d.sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}