123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- <?php
- if (!defined('GNUSOCIAL')) { exit(1); }
- class WebFingerPlugin extends Plugin
- {
- const PLUGIN_VERSION = '2.0.0';
- const OAUTH_ACCESS_TOKEN_REL = 'http://apinamespace.org/oauth/access_token';
- const OAUTH_REQUEST_TOKEN_REL = 'http://apinamespace.org/oauth/request_token';
- const OAUTH_AUTHORIZE_REL = 'http://apinamespace.org/oauth/authorize';
- public function onRouterInitialized(URLMapper $m)
- {
- $m->connect('.well-known/host-meta', ['action' => 'hostmeta']);
- $m->connect('.well-known/host-meta.:format',
- ['action' => 'hostmeta'],
- ['format' => '(xml|json)']);
-
- $m->connect('.well-known/webfinger', ['action' => 'webfinger']);
- $m->connect('.well-known/webfinger.:format',
- ['action' => 'webfinger'],
- ['format' => '(xml|json)']);
- $m->connect('main/ownerxrd', ['action' => 'ownerxrd']);
- return true;
- }
- public function onLoginAction($action, &$login)
- {
- switch ($action) {
- case 'hostmeta':
- case 'webfinger':
- $login = true;
- return false;
- }
-
- return true;
- }
- public function onStartGetProfileAcctUri(Profile $profile, &$acct)
- {
- $wfr = new WebFingerResource_Profile($profile);
- try {
- $acct = $wfr->reconstructAcct();
- } catch (Exception $e) {
- return true;
- }
- return false;
- }
- public function onEndGetWebFingerResource($resource, WebFingerResource &$target=null, array $args=array())
- {
- $profile = null;
- if (Discovery::isAcct($resource)) {
- $parts = explode('@', substr(urldecode($resource), 5));
- if (count($parts) == 2) {
- list($nick, $domain) = $parts;
- if ($domain !== common_config('site', 'server')) {
- throw new Exception(_('Remote profiles not supported via WebFinger yet.'));
- }
- $nick = common_canonical_nickname($nick);
- $user = User::getKV('nickname', $nick);
- if (!($user instanceof User)) {
- throw new NoSuchUserException(array('nickname'=>$nick));
- }
- $profile = $user->getProfile();
- }
- } elseif (!common_valid_http_url($resource)) {
-
-
- try {
- $user = User::getByUri($resource);
- $profile = $user->getProfile();
- } catch (NoResultException $e) {
-
- }
- } else {
-
-
- $alt_urls = [$resource => true];
- if (strtolower(parse_url($resource, PHP_URL_SCHEME)) === 'https'
- && common_config('fix', 'legacy_http')) {
- $alt_urls[preg_replace('/^https:/i', 'http:', $resource, 1)] = true;
- }
- if (common_config('fix', 'fancyurls')) {
- foreach (array_keys($alt_urls) as $url) {
- try {
-
- $alt_url = common_fake_local_fancy_url($url);
- } catch (Exception $e) {
-
- $alt_url = common_fake_local_nonfancy_url($url);
- }
- $alt_urls[$alt_url] = true;
- }
- }
- common_debug(__METHOD__.': Generated these alternative URLs for various federation fixes: '._ve(array_keys($alt_urls)));
- try {
- common_debug(__METHOD__.': Finding User URI for WebFinger lookup on resource=='._ve($resource));
- $user = new User();
- $user->whereAddIn('uri', array_keys($alt_urls), $user->columnType('uri'));
- $user->limit(1);
- if ($user->find(true)) {
- $profile = $user->getProfile();
- }
- unset($user);
- } catch (Exception $e) {
-
-
- common_log(LOG_ERR, get_class($e).': '._ve($e->getMessage()));
- throw $e;
- }
- try {
- common_debug(__METHOD__.': Finding User_group URI for WebFinger lookup on resource=='._ve($resource));
- $group = new User_group();
- $group->whereAddIn('uri', array_keys($alt_urls), $group->columnType('uri'));
- $group->limit(1);
- if ($group->find(true)) {
- $profile = $group->getProfile();
- }
- unset($group);
- } catch (Exception $e) {
- common_log(LOG_ERR, get_class($e).': '._ve($e->getMessage()));
- throw $e;
- }
-
- if (!$profile instanceof Profile) {
- common_debug(__METHOD__.': Finding Profile URLs for WebFinger lookup on resource=='._ve($resource));
-
- $profile = new Profile();
- $profile->whereAddIn('profileurl', array_keys($alt_urls), $profile->columnType('profileurl'));
- $profile->limit(1);
- if (!$profile->find(true) || !$profile->isLocal()) {
-
-
-
-
-
-
- $profile = null;
- }
- }
- }
- if ($profile instanceof Profile) {
- common_debug(__METHOD__.': Found Profile with ID=='._ve($profile->getID()).' for resource=='._ve($resource));
- $target = new WebFingerResource_Profile($profile);
- return false;
- }
- $notice = Notice::getKV('uri', $resource);
- if ($notice instanceof Notice) {
- $target = new WebFingerResource_Notice($notice);
- return false;
- }
- return true;
- }
- public function onStartHostMetaLinks(array &$links)
- {
- foreach (Discovery::supportedMimeTypes() as $type) {
- $links[] = new XML_XRD_Element_Link(Discovery::LRDD_REL,
- common_local_url('webfinger') . '?resource={uri}',
- $type,
- true);
- }
-
- $links[] = new XML_XRD_Element_link(self::OAUTH_ACCESS_TOKEN_REL, common_local_url('ApiOAuthAccessToken'));
- $links[] = new XML_XRD_Element_link(self::OAUTH_REQUEST_TOKEN_REL, common_local_url('ApiOAuthRequestToken'));
- $links[] = new XML_XRD_Element_link(self::OAUTH_AUTHORIZE_REL, common_local_url('ApiOAuthAuthorize'));
- }
-
- public function onStartShowHTML($action)
- {
- if ($action instanceof ShowstreamAction) {
- $resource = $action->getTarget()->getUri();
- $url = common_local_url('webfinger') . '?resource='.urlencode($resource);
- foreach (array(Discovery::JRD_MIMETYPE, Discovery::XRD_MIMETYPE) as $type) {
- header('Link: <'.$url.'>; rel="'. Discovery::LRDD_REL.'"; type="'.$type.'"', false);
- }
- }
- }
- public function onPluginVersion(array &$versions): bool
- {
- $versions[] = array('name' => 'WebFinger',
- 'version' => self::PLUGIN_VERSION,
- 'author' => 'Mikael Nordfeldth',
- 'homepage' => GNUSOCIAL_ENGINE_URL,
-
- 'rawdescription' => _m('Adds WebFinger lookup to GNU Social'));
- return true;
- }
- }
|