Commit 6d6d3723 authored by 贾浩@五瓣科技's avatar 贾浩@五瓣科技

update retry msg, initdata verify

parent df865d95
......@@ -35,6 +35,7 @@ type PGSQLConfig struct {
type TGTaskConfig struct {
URL string `toml:"url"`
BOTToken string `toml:"bot_token"`
}
type TwitterTaskConfig struct {
......
......@@ -160,7 +160,7 @@ func (d *Dao) GetTaskResult(tid int, userId string) (status string, err error) {
return temp.Status, err
}
func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (exist bool, err error) {
func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool, initStatus string) (exist bool, err error) {
// 使用行锁,防止并发
tx := d.db.Begin()
defer func() {
......@@ -179,7 +179,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
Id: util.GenFlakeID(),
TaskId: taskId,
UserId: userId,
Status: constant.TaskHistoryStatusPending,
Status: initStatus,
}).Error
if err != nil {
return false, err
......@@ -190,7 +190,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
return true, tx.Model(&dbModel.TaskHistory{}).
Where("task_id = ? and user_id = ?", taskId, userId).
Limit(1).
Updates(map[string]interface{}{"updated_at": time.Now(), "status": constant.TaskHistoryStatusPending}).Error
Updates(map[string]interface{}{"updated_at": time.Now(), "status": initStatus}).Error
}
return err == nil, err
......@@ -202,7 +202,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
Id: util.GenFlakeID(),
TaskId: taskId,
UserId: userId,
Status: constant.TaskHistoryStatusPending,
Status: initStatus,
}).Error
if err != nil {
return false, err
......@@ -213,7 +213,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
return true, tx.Model(&dbModel.TaskHistory{}).
Where("task_id = ? and user_id = ? and created_at >= ?", taskId, userId, time.Now().UTC().Truncate(24*time.Hour)).
Limit(1).
Updates(map[string]interface{}{"updated_at": time.Now(), "status": constant.TaskHistoryStatusPending}).
Updates(map[string]interface{}{"updated_at": time.Now(), "status": initStatus}).
Error
}
return err == nil, err
......
......@@ -4,8 +4,10 @@ import (
"strconv"
"taskcenter/constant"
apiModel "taskcenter/model/api"
"taskcenter/util"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
func createTask(c *gin.Context) {
......@@ -82,6 +84,10 @@ func checkTask(c *gin.Context) {
return
}
if status == constant.TaskHistoryStatusRetry {
c.JSON(200, withSuccess(gin.H{"status": status, "msg": "The task is not completed, please try again."}))
}
c.JSON(200, withSuccess(gin.H{"status": status}))
}
......@@ -91,6 +97,7 @@ func submitTask(c *gin.Context) {
taskId, _ := strconv.Atoi(_taskId)
// userId := c.Query("userId")
userId := c.GetString("userId")
initData := c.Query("initData")
if taskId == 0 || userId == "" {
c.JSON(200, withError(constant.InvalidParam))
......@@ -124,11 +131,51 @@ func submitTask(c *gin.Context) {
return
}
_, err = srv.SubmitTask(taskId, userId, task.Daily)
// 有initdata必须为appbase premiunsignin
if task.Platform == constant.TaskPlatformAppbase && task.Action != constant.TaskActionPremiumSignIn && initData == "" {
c.JSON(200, withError(constant.InvalidParam))
return
}
// 没有initdata,sync模块处理状态
if initData == "" {
_, err = srv.SubmitTask(taskId, userId, task.Daily, constant.TaskHistoryStatusPending)
if err != nil {
c.JSON(200, withError(constant.InternalError))
return
}
c.JSON(200, withSuccess(gin.H{}))
}
// appbase tg会员签到, 直接在此处确定任务完成状态
ok, isPremium, _, tgUserId := util.VerifyInitData(initData, conf.TGTask.BOTToken)
telegramUserId, err := d.GetProviderId(userId, constant.TaskPlatformTelegram)
if err != nil {
log.WithError(err).Error("get provider telegram user id error")
c.JSON(200, withError(constant.InternalError))
return
}
if !ok {
c.JSON(200, withError("invalid initData"))
return
}
if tgUserId != telegramUserId {
log.WithField(tgUserId, telegramUserId).Error("tgUserId != telegramUserId")
c.JSON(200, withError("invalid initData"))
return
}
taskStatus := constant.TaskHistoryStatusRetry
if isPremium {
taskStatus = constant.TaskHistoryStatusSuccess
}
_, err = srv.SubmitTask(taskId, userId, task.Daily, taskStatus)
if err != nil {
c.JSON(200, withError(constant.InternalError))
return
}
c.JSON(200, withSuccess(gin.H{}))
return
}
......@@ -150,8 +150,8 @@ func (s *Service) GetTaskResult(taskId int, userId string) (status string, err e
return
}
func (s *Service) SubmitTask(taskId int, userId string, isDailyTask bool) (exist bool, err error) {
exist, err = s.d.CreateTaskHistory(taskId, userId, isDailyTask)
func (s *Service) SubmitTask(taskId int, userId string, isDailyTask bool, status string) (exist bool, err error) {
exist, err = s.d.CreateTaskHistory(taskId, userId, isDailyTask, status)
if err != nil {
log.WithError(err).Error("create task history error")
}
......
......@@ -128,6 +128,7 @@ func (s *Sync) SyncTask(taskId int, userId string) (ok bool, err error) {
// 签到直接成功
return true, nil
case constant.TaskActionPremiumSignIn:
// 会员签到,当前在api端直接检查
telegramUserId, err := s.d.GetProviderId(userId, constant.TaskPlatformTelegram)
if err != nil {
log.WithError(err).Error("get provider telegram user id error")
......
package util
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
"net/url"
"sort"
"strconv"
"strings"
"time"
"github.com/tidwall/gjson"
)
func VerifyInitData(initData, botToken string) (ok, isPremium bool, botId, userId string) {
h := hmac.New(sha256.New, []byte("WebAppData"))
h.Write([]byte(botToken))
secret := h.Sum(nil)
h2 := hmac.New(sha256.New, secret)
params, err := url.ParseQuery(initData)
if err != nil {
return
}
var hashval string
var keys []string
for key := range params {
if key == "hash" {
hashval = params.Get(key)
continue
}
if key == "auth_date" {
authDate, _ := strconv.Atoi(params.Get(key))
if int64(authDate) < time.Now().Unix()-3600*24 || int64(authDate) > time.Now().Unix()+300 {
// todo 可以限制超时时间
return false, false, "", ""
}
}
if key == "user" {
userId = gjson.Get(params.Get(key), "id").String()
}
if key == "is_premium" {
isPremium = gjson.Get(params.Get(key), "is_premium").Bool()
}
keys = append(keys, key)
}
sort.Strings(keys)
var payloads []string
for _, key := range keys {
payloads = append(payloads, fmt.Sprintf("%s=%s", key, params.Get(key)))
}
payload := strings.Join(payloads, "\n")
h2.Write([]byte(payload))
h2sum := h2.Sum(nil)
items := strings.Split(botToken, ":")
if len(items) != 2 {
return
}
ok = fmt.Sprintf("%x", h2sum) == hashval
botId = items[0]
return
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment