You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

wechat.go 3.6 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package authentication
  2. import (
  3. "code.gitea.io/gitea/modules/auth/wechat"
  4. "code.gitea.io/gitea/modules/base"
  5. "code.gitea.io/gitea/modules/context"
  6. "code.gitea.io/gitea/modules/log"
  7. "code.gitea.io/gitea/modules/redis/redis_client"
  8. "code.gitea.io/gitea/modules/redis/redis_key"
  9. "code.gitea.io/gitea/modules/setting"
  10. "code.gitea.io/gitea/routers/response"
  11. "encoding/json"
  12. "errors"
  13. gouuid "github.com/satori/go.uuid"
  14. "strconv"
  15. "time"
  16. )
  17. const tplBindPage base.TplName = "repo/wx_autorize"
  18. type QRCodeResponse struct {
  19. Url string
  20. Ticket string
  21. SceneStr string
  22. ExpireSeconds int
  23. }
  24. // GetQRCode4Bind get QR code for wechat binding
  25. func GetQRCode4Bind(ctx *context.Context) {
  26. userId := ctx.User.ID
  27. r, err := createQRCode4Bind(userId)
  28. if err != nil {
  29. ctx.JSON(200, map[string]interface{}{
  30. "code": "9999",
  31. "msg": "Get QR code failed",
  32. })
  33. return
  34. }
  35. ctx.JSON(200, map[string]interface{}{
  36. "code": "00",
  37. "msg": "success",
  38. "data": r,
  39. })
  40. }
  41. // GetBindStatus the web page will poll the service to get bind status
  42. func GetBindStatus(ctx *context.Context) {
  43. sceneStr := ctx.Query("sceneStr")
  44. val, _ := redis_client.Get(redis_key.WechatBindingUserIdKey(sceneStr))
  45. if val == "" {
  46. ctx.JSON(200, map[string]interface{}{
  47. "code": "00",
  48. "msg": "QR code expired",
  49. "data": map[string]interface{}{
  50. "status": wechat.BIND_STATUS_EXPIRED,
  51. },
  52. })
  53. return
  54. }
  55. qrCache := new(wechat.QRCode4BindCache)
  56. json.Unmarshal([]byte(val), qrCache)
  57. ctx.JSON(200, map[string]interface{}{
  58. "code": "00",
  59. "msg": "success",
  60. "data": map[string]interface{}{
  61. "status": qrCache.Status,
  62. },
  63. })
  64. }
  65. // UnbindWechat
  66. func UnbindWechat(ctx *context.Context) {
  67. if ctx.User.WechatOpenId != "" {
  68. wechat.UnbindWechat(ctx.User.ID, ctx.User.WechatOpenId)
  69. }
  70. ctx.JSON(200, map[string]interface{}{
  71. "code": "00",
  72. "msg": "success",
  73. })
  74. }
  75. // GetBindPage
  76. func GetBindPage(ctx *context.Context) {
  77. userId := ctx.User.ID
  78. r, _ := createQRCode4Bind(userId)
  79. if r != nil {
  80. ctx.Data["qrcode"] = r
  81. }
  82. redirectUrl := ctx.Query("redirect_to")
  83. if redirectUrl != "" {
  84. ctx.SetCookie("redirect_to", setting.AppSubURL+redirectUrl, 0, setting.AppSubURL)
  85. }
  86. ctx.HTML(200, tplBindPage)
  87. }
  88. func createQRCode4Bind(userId int64) (*QRCodeResponse, error) {
  89. log.Info("start to create qr-code for binding.userId=%d", userId)
  90. sceneStr := gouuid.NewV4().String()
  91. r := wechat.GetWechatQRCode4Bind(sceneStr)
  92. if r == nil {
  93. return nil, errors.New("createQRCode4Bind failed")
  94. }
  95. jsonStr, _ := json.Marshal(&wechat.QRCode4BindCache{
  96. UserId: userId,
  97. Status: wechat.BIND_STATUS_UNBIND,
  98. })
  99. isOk, err := redis_client.Setex(redis_key.WechatBindingUserIdKey(sceneStr), string(jsonStr), time.Duration(setting.WechatQRCodeExpireSeconds)*time.Second)
  100. if err != nil {
  101. log.Error("createQRCode4Bind failed.e=%+v", err)
  102. return nil, err
  103. }
  104. if !isOk {
  105. log.Error("createQRCode4Bind failed.redis reply is not ok")
  106. return nil, errors.New("reply is not ok when set WechatBindingUserIdKey")
  107. }
  108. result := &QRCodeResponse{
  109. Url: r.Url,
  110. Ticket: r.Ticket,
  111. SceneStr: sceneStr,
  112. ExpireSeconds: setting.WechatQRCodeExpireSeconds,
  113. }
  114. return result, nil
  115. }
  116. // GetMaterial
  117. func GetMaterial(ctx *context.Context) {
  118. mType := ctx.Query("type")
  119. offsetStr := ctx.Query("offset")
  120. countStr := ctx.Query("count")
  121. var offset, count int
  122. if offsetStr == "" {
  123. offset = 0
  124. } else {
  125. offset, _ = strconv.Atoi(offsetStr)
  126. }
  127. if countStr == "" {
  128. count = 20
  129. } else {
  130. count, _ = strconv.Atoi(countStr)
  131. }
  132. r := wechat.GetWechatMaterial(mType, offset, count)
  133. ctx.JSON(200, response.SuccessWithData(r))
  134. }