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