user.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package bridge
  2. import (
  3. "github.com/skip2/go-qrcode"
  4. log "maunium.net/go/maulogger/v2"
  5. "maunium.net/go/mautrix/appservice"
  6. "maunium.net/go/mautrix/event"
  7. "maunium.net/go/mautrix/id"
  8. "gitlab.com/beeper/discord/database"
  9. )
  10. type User struct {
  11. *database.User
  12. bridge *Bridge
  13. log log.Logger
  14. }
  15. func (b *Bridge) loadUser(dbUser *database.User, mxid *id.UserID) *User {
  16. // If we weren't passed in a user we attempt to create one if we were given
  17. // a matrix id.
  18. if dbUser == nil {
  19. if mxid == nil {
  20. return nil
  21. }
  22. dbUser = b.db.User.New()
  23. dbUser.MXID = *mxid
  24. dbUser.Insert()
  25. }
  26. user := b.NewUser(dbUser)
  27. // We assume the usersLock was acquired by our caller.
  28. b.usersByMXID[user.MXID] = user
  29. if user.ID != "" {
  30. b.usersByID[user.ID] = user
  31. }
  32. if user.ManagementRoom != "" {
  33. // Lock the management rooms for our update
  34. b.managementRoomsLock.Lock()
  35. b.managementRooms[user.ManagementRoom] = user
  36. b.managementRoomsLock.Unlock()
  37. }
  38. return user
  39. }
  40. func (b *Bridge) GetUserByMXID(userID id.UserID) *User {
  41. // TODO: check if puppet
  42. b.usersLock.Lock()
  43. defer b.usersLock.Unlock()
  44. user, ok := b.usersByMXID[userID]
  45. if !ok {
  46. return b.loadUser(b.db.User.GetByMXID(userID), &userID)
  47. }
  48. return user
  49. }
  50. func (b *Bridge) NewUser(dbUser *database.User) *User {
  51. user := &User{
  52. User: dbUser,
  53. bridge: b,
  54. log: b.log.Sub("User").Sub(string(dbUser.MXID)),
  55. }
  56. return user
  57. }
  58. func (u *User) SetManagementRoom(roomID id.RoomID) {
  59. u.bridge.managementRoomsLock.Lock()
  60. defer u.bridge.managementRoomsLock.Unlock()
  61. existing, ok := u.bridge.managementRooms[roomID]
  62. if ok {
  63. // If there's a user already assigned to this management room, clear it
  64. // out.
  65. // I think this is due a name change or something? I dunno, leaving it
  66. // for now.
  67. existing.ManagementRoom = ""
  68. existing.Update()
  69. }
  70. u.ManagementRoom = roomID
  71. u.bridge.managementRooms[u.ManagementRoom] = u
  72. u.Update()
  73. }
  74. func (u *User) HasSession() bool {
  75. return u.User.Session != nil
  76. }
  77. func (u *User) sendQRCode(bot *appservice.IntentAPI, roomID id.RoomID, code string) (id.EventID, error) {
  78. url, err := u.uploadQRCode(code)
  79. if err != nil {
  80. return "", err
  81. }
  82. content := event.MessageEventContent{
  83. MsgType: event.MsgImage,
  84. Body: code,
  85. URL: url.CUString(),
  86. }
  87. resp, err := bot.SendMessageEvent(roomID, event.EventMessage, &content)
  88. if err != nil {
  89. return "", err
  90. }
  91. return resp.EventID, nil
  92. }
  93. func (u *User) uploadQRCode(code string) (id.ContentURI, error) {
  94. qrCode, err := qrcode.Encode(code, qrcode.Low, 256)
  95. if err != nil {
  96. u.log.Errorln("Failed to encode QR code:", err)
  97. return id.ContentURI{}, err
  98. }
  99. bot := u.bridge.as.BotClient()
  100. resp, err := bot.UploadBytes(qrCode, "image/png")
  101. if err != nil {
  102. u.log.Errorln("Failed to upload QR code:", err)
  103. return id.ContentURI{}, err
  104. }
  105. return resp.ContentURI, nil
  106. }