4
0

stub_handler.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package webapi
  2. import (
  3. "log/slog"
  4. "net/http"
  5. )
  6. // ServiceStubHandler serves the /service/* endpoints that manage third-party
  7. // service linking (Google Talk, Facebook), none of which this server federates.
  8. type ServiceStubHandler struct {
  9. Logger *slog.Logger
  10. }
  11. // GetAttributes reports that the requested third-party service is not linked.
  12. func (h *ServiceStubHandler) GetAttributes(w http.ResponseWriter, r *http.Request) {
  13. SendEnvelopeStatus(w, r, statusNoSuchService, "Service not available", h.Logger)
  14. }
  15. type UserInfoStubHandler struct {
  16. Logger *slog.Logger
  17. }
  18. // UserDetailsData reports which third-party services the account is linked to.
  19. type UserDetailsData struct {
  20. UserDetails UserDetails `json:"userDetails" xml:"userDetails"`
  21. }
  22. // UserDetails lists the linked services.
  23. type UserDetails struct {
  24. Services []UserService `json:"services" xml:"services>service"`
  25. }
  26. // UserService names one linked service.
  27. type UserService struct {
  28. Service string `json:"service" xml:"service"`
  29. }
  30. // NotificationsData is the social-notification feed, which this server does not
  31. // keep.
  32. type NotificationsData struct {
  33. // Activities is always sent, empty included: the client maps over it
  34. // unconditionally on a 200.
  35. Activities []string `json:"activities" xml:"activities>activity"`
  36. }
  37. // ServicesData lists the IM services the account can sign on to.
  38. type ServicesData struct {
  39. // Services is always sent, empty included: the client iterates it
  40. // unconditionally on a 200.
  41. Services []Service `json:"services" xml:"services>service"`
  42. }
  43. // Service describes one signed-on or linkable IM service. Every field is sent
  44. // even when false or empty, because the client reads each one unconditionally
  45. // rather than testing for its presence.
  46. type Service struct {
  47. Name string `json:"name" xml:"name"`
  48. Service string `json:"service" xml:"service"`
  49. Associated bool `json:"associated" xml:"associated"`
  50. Online bool `json:"online" xml:"online"`
  51. // Roster is a third-party friend list available to import, not the buddy
  52. // list; this server federates with nothing, so there is never one.
  53. Roster bool `json:"roster" xml:"roster"`
  54. HaveRoster bool `json:"haveRoster" xml:"haveRoster"`
  55. AutoLogin bool `json:"autoLogin" xml:"autoLogin"`
  56. SignupURL string `json:"signupURL" xml:"signupURL"`
  57. }
  58. // GetServices advertises AIM as the only service, already signed on. The client
  59. // asks at sign-on to build its service list and to decide whether to offer a
  60. // link-account prompt for the others.
  61. func (h *UserInfoStubHandler) GetServices(w http.ResponseWriter, r *http.Request) {
  62. SendOK(w, r, &ServicesData{
  63. Services: []Service{
  64. {
  65. Name: "aim",
  66. Service: "aim",
  67. Associated: true,
  68. Online: true,
  69. },
  70. },
  71. }, h.Logger)
  72. }
  73. func (h *UserInfoStubHandler) GetUserDetails(w http.ResponseWriter, r *http.Request) {
  74. SendOK(w, r, &UserDetailsData{
  75. UserDetails: UserDetails{Services: []UserService{{Service: "aim"}}},
  76. }, h.Logger)
  77. }
  78. // HeyGetNotifications returns an empty social-notification feed.
  79. //
  80. // The activities array must be present even when empty: the client maps over
  81. // response.data.activities unconditionally on a 200, so omitting it raises
  82. // "Array.prototype.map called on null or undefined" and aborts the rest of the
  83. // notification setup.
  84. func (h *UserInfoStubHandler) HeyGetNotifications(w http.ResponseWriter, r *http.Request) {
  85. SendOK(w, r, &NotificationsData{Activities: []string{}}, h.Logger)
  86. }
  87. func (h *UserInfoStubHandler) EmptyOK(w http.ResponseWriter, r *http.Request) {
  88. SendOK(w, r, nil, h.Logger)
  89. }