locate.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package handler
  2. import (
  3. "context"
  4. "io"
  5. "log/slog"
  6. "github.com/mk6i/retro-aim-server/server/oscar"
  7. "github.com/mk6i/retro-aim-server/server/oscar/middleware"
  8. "github.com/mk6i/retro-aim-server/state"
  9. "github.com/mk6i/retro-aim-server/wire"
  10. )
  11. type LocateService interface {
  12. DirInfo(ctx context.Context, frame wire.SNACFrame, body wire.SNAC_0x02_0x0B_LocateGetDirInfo) (wire.SNACMessage, error)
  13. RightsQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage
  14. SetDirInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x02_0x09_LocateSetDirInfo) (wire.SNACMessage, error)
  15. SetInfo(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x02_0x04_LocateSetInfo) error
  16. SetKeywordInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, body wire.SNAC_0x02_0x0F_LocateSetKeywordInfo) (wire.SNACMessage, error)
  17. UserInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x02_0x05_LocateUserInfoQuery) (wire.SNACMessage, error)
  18. }
  19. func NewLocateHandler(locateService LocateService, logger *slog.Logger) LocateHandler {
  20. return LocateHandler{
  21. LocateService: locateService,
  22. RouteLogger: middleware.RouteLogger{
  23. Logger: logger,
  24. },
  25. }
  26. }
  27. type LocateHandler struct {
  28. LocateService
  29. middleware.RouteLogger
  30. }
  31. func (h LocateHandler) RightsQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw oscar.ResponseWriter) error {
  32. outSNAC := h.LocateService.RightsQuery(ctx, inFrame)
  33. h.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  34. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  35. }
  36. func (h LocateHandler) SetInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  37. inBody := wire.SNAC_0x02_0x04_LocateSetInfo{}
  38. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  39. return err
  40. }
  41. h.LogRequest(ctx, inFrame, inBody)
  42. return h.LocateService.SetInfo(ctx, sess, inBody)
  43. }
  44. func (h LocateHandler) SetDirInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  45. inBody := wire.SNAC_0x02_0x09_LocateSetDirInfo{}
  46. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  47. return err
  48. }
  49. outSNAC, err := h.LocateService.SetDirInfo(ctx, sess, inFrame, inBody)
  50. if err != nil {
  51. return err
  52. }
  53. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  54. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  55. }
  56. func (h LocateHandler) GetDirInfo(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  57. inBody := wire.SNAC_0x02_0x0B_LocateGetDirInfo{}
  58. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  59. return err
  60. }
  61. outSNAC, err := h.LocateService.DirInfo(ctx, inFrame, inBody)
  62. if err != nil {
  63. return err
  64. }
  65. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  66. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  67. }
  68. func (h LocateHandler) SetKeywordInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  69. inBody := wire.SNAC_0x02_0x0F_LocateSetKeywordInfo{}
  70. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  71. return err
  72. }
  73. outSNAC, err := h.LocateService.SetKeywordInfo(ctx, sess, inFrame, inBody)
  74. if err != nil {
  75. return err
  76. }
  77. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  78. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  79. }
  80. func (h LocateHandler) UserInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  81. inBody := wire.SNAC_0x02_0x05_LocateUserInfoQuery{}
  82. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  83. return err
  84. }
  85. outSNAC, err := h.LocateService.UserInfoQuery(ctx, sess, inFrame, inBody)
  86. if err != nil {
  87. return err
  88. }
  89. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  90. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  91. }
  92. func (h LocateHandler) UserInfoQuery2(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  93. inBody := wire.SNAC_0x02_0x15_LocateUserInfoQuery2{}
  94. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  95. return err
  96. }
  97. // SNAC functionality for LocateUserInfoQuery and LocateUserInfoQuery2 is
  98. // identical except for the Type field data type (uint16 vs uint32).
  99. wrappedBody := wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  100. Type: uint16(inBody.Type2),
  101. ScreenName: inBody.ScreenName,
  102. }
  103. outSNAC, err := h.LocateService.UserInfoQuery(ctx, sess, inFrame, wrappedBody)
  104. if err != nil {
  105. return err
  106. }
  107. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  108. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  109. }