WebFingerPlugin.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /*
  3. * GNU Social - a federating social network
  4. * Copyright (C) 2013, Free Software Foundation, Inc.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * Implements WebFinger for GNU Social, as well as support for the
  21. * '.well-known/host-meta' resource.
  22. *
  23. * Depends on: LRDD plugin
  24. *
  25. * @package GNUsocial
  26. * @author Mikael Nordfeldth <mmn@hethane.se>
  27. */
  28. if (!defined('GNUSOCIAL')) { exit(1); }
  29. class WebFingerPlugin extends Plugin
  30. {
  31. public function onRouterInitialized($m)
  32. {
  33. $m->connect('.well-known/host-meta', array('action' => 'hostmeta'));
  34. $m->connect('.well-known/host-meta.:format',
  35. array('action' => 'hostmeta',
  36. 'format' => '(xml|json)'));
  37. // the resource GET parameter can be anywhere, so don't mention it here
  38. $m->connect('.well-known/webfinger', array('action' => 'webfinger'));
  39. $m->connect('.well-known/webfinger.:format',
  40. array('action' => 'webfinger',
  41. 'format' => '(xml|json)'));
  42. $m->connect('main/ownerxrd', array('action' => 'ownerxrd'));
  43. return true;
  44. }
  45. public function onLoginAction($action, &$login)
  46. {
  47. switch ($action) {
  48. case 'hostmeta':
  49. case 'webfinger':
  50. $login = true;
  51. return false;
  52. }
  53. return true;
  54. }
  55. public function onStartGetProfileAcctUri(Profile $profile, &$acct)
  56. {
  57. $wfr = new WebFingerResource_Profile($profile);
  58. try {
  59. $acct = $wfr->reconstructAcct();
  60. } catch (Exception $e) {
  61. return true;
  62. }
  63. return false;
  64. }
  65. public function onEndGetWebFingerResource($resource, WebFingerResource &$target=null, array $args=array())
  66. {
  67. $profile = null;
  68. if (Discovery::isAcct($resource)) {
  69. $parts = explode('@', substr(urldecode($resource), 5)); // 5 is strlen of 'acct:'
  70. if (count($parts) == 2) {
  71. list($nick, $domain) = $parts;
  72. if ($domain === common_config('site', 'server')) {
  73. $nick = common_canonical_nickname($nick);
  74. $user = User::getKV('nickname', $nick);
  75. if (!($user instanceof User)) {
  76. throw new NoSuchUserException(array('nickname'=>$nick));
  77. }
  78. $profile = $user->getProfile();
  79. } else {
  80. throw new Exception(_('Remote profiles not supported via WebFinger yet.'));
  81. }
  82. }
  83. } else {
  84. $user = User::getKV('uri', $resource);
  85. if ($user instanceof User) {
  86. $profile = $user->getProfile();
  87. } else {
  88. // try and get it by profile url
  89. $profile = Profile::getKV('profileurl', $resource);
  90. }
  91. }
  92. if ($profile instanceof Profile) {
  93. $target = new WebFingerResource_Profile($profile);
  94. return false; // We got our target, stop handler execution
  95. }
  96. $notice = Notice::getKV('uri', $resource);
  97. if ($notice instanceof Notice) {
  98. $target = new WebFingerResource_Notice($notice);
  99. return false;
  100. }
  101. return true;
  102. }
  103. public function onStartHostMetaLinks(array &$links)
  104. {
  105. foreach (Discovery::supportedMimeTypes() as $type) {
  106. $links[] = new XML_XRD_Element_Link(Discovery::LRDD_REL,
  107. common_local_url('webfinger') . '?resource={uri}',
  108. $type,
  109. true); // isTemplate
  110. }
  111. }
  112. /**
  113. * Add a link header for LRDD Discovery
  114. */
  115. public function onStartShowHTML($action)
  116. {
  117. if ($action instanceof ShowstreamAction) {
  118. $acct = 'acct:'. $action->profile->nickname .'@'. common_config('site', 'server');
  119. $url = common_local_url('webfinger') . '?resource='.$acct;
  120. foreach (array(Discovery::JRD_MIMETYPE, Discovery::XRD_MIMETYPE) as $type) {
  121. header('Link: <'.$url.'>; rel="'. Discovery::LRDD_REL.'"; type="'.$type.'"');
  122. }
  123. }
  124. }
  125. public function onPluginVersion(&$versions)
  126. {
  127. $versions[] = array('name' => 'WebFinger',
  128. 'version' => GNUSOCIAL_VERSION,
  129. 'author' => 'Mikael Nordfeldth',
  130. 'homepage' => 'http://www.gnu.org/software/social/',
  131. // TRANS: Plugin description.
  132. 'rawdescription' => _m('Adds WebFinger lookup to GNU Social'));
  133. return true;
  134. }
  135. }