A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

92 lines
2.2 KiB

  1. /*
  2. * Copyright © 2018 A Bunch Tell LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package writefreely
  11. import (
  12. "net/http"
  13. "github.com/writeas/go-webfinger"
  14. "github.com/writeas/impart"
  15. "github.com/writeas/web-core/log"
  16. "github.com/writeas/writefreely/config"
  17. )
  18. type wfResolver struct {
  19. db *datastore
  20. cfg *config.Config
  21. }
  22. var wfUserNotFoundErr = impart.HTTPError{http.StatusNotFound, "User not found."}
  23. func (wfr wfResolver) FindUser(username string, host, requestHost string, r []webfinger.Rel) (*webfinger.Resource, error) {
  24. var c *Collection
  25. var err error
  26. if wfr.cfg.App.SingleUser {
  27. c, err = wfr.db.GetCollectionByID(1)
  28. } else {
  29. c, err = wfr.db.GetCollection(username)
  30. }
  31. if err != nil {
  32. log.Error("Unable to get blog: %v", err)
  33. return nil, err
  34. }
  35. suspended, err := wfr.db.IsUserSuspended(c.OwnerID)
  36. if err != nil {
  37. log.Error("webfinger find user: check is suspended: %v", err)
  38. return nil, err
  39. }
  40. if suspended {
  41. return nil, wfUserNotFoundErr
  42. }
  43. c.hostName = wfr.cfg.App.Host
  44. if wfr.cfg.App.SingleUser {
  45. // Ensure handle matches user-chosen one on single-user blogs
  46. if username != c.Alias {
  47. log.Info("Username '%s' is not handle '%s'", username, c.Alias)
  48. return nil, wfUserNotFoundErr
  49. }
  50. }
  51. // Only return information if site has federation enabled.
  52. // TODO: enable two levels of federation? Unlisted or Public on timelines?
  53. if !wfr.cfg.App.Federation {
  54. return nil, wfUserNotFoundErr
  55. }
  56. res := webfinger.Resource{
  57. Subject: "acct:" + username + "@" + host,
  58. Aliases: []string{
  59. c.CanonicalURL(),
  60. c.FederatedAccount(),
  61. },
  62. Links: []webfinger.Link{
  63. {
  64. HRef: c.CanonicalURL(),
  65. Type: "text/html",
  66. Rel: "https://webfinger.net/rel/profile-page",
  67. },
  68. {
  69. HRef: c.FederatedAccount(),
  70. Type: "application/activity+json",
  71. Rel: "self",
  72. },
  73. },
  74. }
  75. return &res, nil
  76. }
  77. func (wfr wfResolver) DummyUser(username string, hostname string, r []webfinger.Rel) (*webfinger.Resource, error) {
  78. return nil, wfUserNotFoundErr
  79. }
  80. func (wfr wfResolver) IsNotFoundError(err error) bool {
  81. return err == wfUserNotFoundErr
  82. }