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

update retry msg, initdata verify

parent df865d95
...@@ -34,7 +34,8 @@ type PGSQLConfig struct { ...@@ -34,7 +34,8 @@ type PGSQLConfig struct {
} }
type TGTaskConfig struct { type TGTaskConfig struct {
URL string `toml:"url"` URL string `toml:"url"`
BOTToken string `toml:"bot_token"`
} }
type TwitterTaskConfig struct { type TwitterTaskConfig struct {
......
...@@ -160,7 +160,7 @@ func (d *Dao) GetTaskResult(tid int, userId string) (status string, err error) { ...@@ -160,7 +160,7 @@ func (d *Dao) GetTaskResult(tid int, userId string) (status string, err error) {
return temp.Status, err 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() tx := d.db.Begin()
defer func() { defer func() {
...@@ -179,7 +179,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex ...@@ -179,7 +179,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
Id: util.GenFlakeID(), Id: util.GenFlakeID(),
TaskId: taskId, TaskId: taskId,
UserId: userId, UserId: userId,
Status: constant.TaskHistoryStatusPending, Status: initStatus,
}).Error }).Error
if err != nil { if err != nil {
return false, err return false, err
...@@ -190,7 +190,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex ...@@ -190,7 +190,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
return true, tx.Model(&dbModel.TaskHistory{}). return true, tx.Model(&dbModel.TaskHistory{}).
Where("task_id = ? and user_id = ?", taskId, userId). Where("task_id = ? and user_id = ?", taskId, userId).
Limit(1). 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 return err == nil, err
...@@ -202,7 +202,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex ...@@ -202,7 +202,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
Id: util.GenFlakeID(), Id: util.GenFlakeID(),
TaskId: taskId, TaskId: taskId,
UserId: userId, UserId: userId,
Status: constant.TaskHistoryStatusPending, Status: initStatus,
}).Error }).Error
if err != nil { if err != nil {
return false, err return false, err
...@@ -213,7 +213,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex ...@@ -213,7 +213,7 @@ func (d *Dao) CreateTaskHistory(taskId int, userId string, isDailyTask bool) (ex
return true, tx.Model(&dbModel.TaskHistory{}). return true, tx.Model(&dbModel.TaskHistory{}).
Where("task_id = ? and user_id = ? and created_at >= ?", taskId, userId, time.Now().UTC().Truncate(24*time.Hour)). Where("task_id = ? and user_id = ? and created_at >= ?", taskId, userId, time.Now().UTC().Truncate(24*time.Hour)).
Limit(1). Limit(1).
Updates(map[string]interface{}{"updated_at": time.Now(), "status": constant.TaskHistoryStatusPending}). Updates(map[string]interface{}{"updated_at": time.Now(), "status": initStatus}).
Error Error
} }
return err == nil, err return err == nil, err
......
...@@ -4,8 +4,10 @@ import ( ...@@ -4,8 +4,10 @@ import (
"strconv" "strconv"
"taskcenter/constant" "taskcenter/constant"
apiModel "taskcenter/model/api" apiModel "taskcenter/model/api"
"taskcenter/util"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
) )
func createTask(c *gin.Context) { func createTask(c *gin.Context) {
...@@ -82,6 +84,10 @@ func checkTask(c *gin.Context) { ...@@ -82,6 +84,10 @@ func checkTask(c *gin.Context) {
return 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})) c.JSON(200, withSuccess(gin.H{"status": status}))
} }
...@@ -91,6 +97,7 @@ func submitTask(c *gin.Context) { ...@@ -91,6 +97,7 @@ func submitTask(c *gin.Context) {
taskId, _ := strconv.Atoi(_taskId) taskId, _ := strconv.Atoi(_taskId)
// userId := c.Query("userId") // userId := c.Query("userId")
userId := c.GetString("userId") userId := c.GetString("userId")
initData := c.Query("initData")
if taskId == 0 || userId == "" { if taskId == 0 || userId == "" {
c.JSON(200, withError(constant.InvalidParam)) c.JSON(200, withError(constant.InvalidParam))
...@@ -124,11 +131,51 @@ func submitTask(c *gin.Context) { ...@@ -124,11 +131,51 @@ func submitTask(c *gin.Context) {
return 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 { if err != nil {
log.WithError(err).Error("get provider telegram user id error")
c.JSON(200, withError(constant.InternalError)) c.JSON(200, withError(constant.InternalError))
return 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{})) c.JSON(200, withSuccess(gin.H{}))
return
} }
...@@ -150,8 +150,8 @@ func (s *Service) GetTaskResult(taskId int, userId string) (status string, err e ...@@ -150,8 +150,8 @@ func (s *Service) GetTaskResult(taskId int, userId string) (status string, err e
return return
} }
func (s *Service) SubmitTask(taskId int, userId string, isDailyTask bool) (exist bool, err error) { func (s *Service) SubmitTask(taskId int, userId string, isDailyTask bool, status string) (exist bool, err error) {
exist, err = s.d.CreateTaskHistory(taskId, userId, isDailyTask) exist, err = s.d.CreateTaskHistory(taskId, userId, isDailyTask, status)
if err != nil { if err != nil {
log.WithError(err).Error("create task history error") log.WithError(err).Error("create task history error")
} }
......
...@@ -128,6 +128,7 @@ func (s *Sync) SyncTask(taskId int, userId string) (ok bool, err error) { ...@@ -128,6 +128,7 @@ func (s *Sync) SyncTask(taskId int, userId string) (ok bool, err error) {
// 签到直接成功 // 签到直接成功
return true, nil return true, nil
case constant.TaskActionPremiumSignIn: case constant.TaskActionPremiumSignIn:
// 会员签到,当前在api端直接检查
telegramUserId, err := s.d.GetProviderId(userId, constant.TaskPlatformTelegram) telegramUserId, err := s.d.GetProviderId(userId, constant.TaskPlatformTelegram)
if err != nil { if err != nil {
log.WithError(err).Error("get provider telegram user id error") 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