webfinger.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strings"
  6. "github.com/owncast/owncast/activitypub/apmodels"
  7. "github.com/owncast/owncast/core/data"
  8. "github.com/owncast/owncast/utils"
  9. log "github.com/sirupsen/logrus"
  10. )
  11. // WebfingerHandler will handle webfinger lookup requests.
  12. func WebfingerHandler(w http.ResponseWriter, r *http.Request) {
  13. if !data.GetFederationEnabled() {
  14. w.WriteHeader(http.StatusMethodNotAllowed)
  15. log.Debugln("webfinger request rejected! Federation is not enabled")
  16. return
  17. }
  18. instanceHostURL := data.GetServerURL()
  19. if instanceHostURL == "" {
  20. w.WriteHeader(http.StatusNotFound)
  21. log.Warnln("webfinger request rejected! Federation is enabled but server URL is empty.")
  22. return
  23. }
  24. instanceHostString := utils.GetHostnameFromURLString(instanceHostURL)
  25. if instanceHostString == "" {
  26. w.WriteHeader(http.StatusNotFound)
  27. log.Warnln("webfinger request rejected! Federation is enabled but server URL is not set properly. data.GetServerURL(): " + data.GetServerURL())
  28. return
  29. }
  30. resource := r.URL.Query().Get("resource")
  31. preAcct, account, foundAcct := strings.Cut(resource, "acct:")
  32. if !foundAcct || preAcct != "" {
  33. w.WriteHeader(http.StatusBadRequest)
  34. log.Debugln("webfinger request rejected! Malformed resource in query: " + resource)
  35. return
  36. }
  37. userComponents := strings.Split(account, "@")
  38. if len(userComponents) != 2 {
  39. w.WriteHeader(http.StatusBadRequest)
  40. log.Debugln("webfinger request rejected! Malformed account in query: " + account)
  41. return
  42. }
  43. host := userComponents[1]
  44. user := userComponents[0]
  45. if _, valid := data.GetFederatedInboxMap()[user]; !valid {
  46. w.WriteHeader(http.StatusNotFound)
  47. log.Debugln("webfinger request rejected! Invalid user: " + user)
  48. return
  49. }
  50. // If the webfinger request doesn't match our server then it
  51. // should be rejected.
  52. if instanceHostString != host {
  53. w.WriteHeader(http.StatusNotImplemented)
  54. log.Debugln("webfinger request rejected! Invalid query host: " + host + " instanceHostString: " + instanceHostString)
  55. return
  56. }
  57. webfingerResponse := apmodels.MakeWebfingerResponse(user, user, host)
  58. w.Header().Set("Content-Type", "application/jrd+json")
  59. if err := json.NewEncoder(w).Encode(webfingerResponse); err != nil {
  60. log.Errorln("unable to write webfinger response", err)
  61. }
  62. }