コード例 #1
0
 static function getServiceDocument($remote)
 {
     $discovery = new Discovery();
     $xrd = $discovery->lookup($remote);
     if (empty($xrd)) {
         // TRANS: Exception thrown when a service document could not be located account move.
         // TRANS: %s is the remote site.
         throw new Exception(sprintf(_("Cannot find XRD for %s."), $remote));
     }
     $svcDocUrl = null;
     $username = null;
     foreach ($xrd->links as $link) {
         if ($link['rel'] == 'http://apinamespace.org/atom' && $link['type'] == 'application/atomsvc+xml') {
             $svcDocUrl = $link['href'];
             if (!empty($link['property'])) {
                 foreach ($link['property'] as $property) {
                     if ($property['type'] == 'http://apinamespace.org/atom/username') {
                         $username = $property['value'];
                         break;
                     }
                 }
             }
             break;
         }
     }
     if (empty($svcDocUrl)) {
         // TRANS: Exception thrown when an account could not be located when it should be moved.
         // TRANS: %s is the remote site.
         throw new Exception(sprintf(_("No AtomPub API service for %s."), $remote));
     }
     return array($svcDocUrl, $username);
 }
コード例 #2
0
 public function getKeyPair($signer_uri)
 {
     $disco = new Discovery();
     try {
         $xrd = $disco->lookup($signer_uri);
     } catch (Exception $e) {
         return false;
     }
     if ($xrd->links) {
         if ($link = Discovery::getService($xrd->links, Magicsig::PUBLICKEYREL)) {
             $keypair = false;
             $parts = explode(',', $link['href']);
             if (count($parts) == 2) {
                 $keypair = $parts[1];
             } else {
                 // Backwards compatibility check for separator bug in 0.9.0
                 $parts = explode(';', $link['href']);
                 if (count($parts) == 2) {
                     $keypair = $parts[1];
                 }
             }
             if ($keypair) {
                 return $keypair;
             }
         }
     }
     throw new Exception('Unable to locate signer public key');
 }
コード例 #3
0
 static function getServiceDocument($remote)
 {
     $discovery = new Discovery();
     $xrd = $discovery->lookup($remote);
     if (empty($xrd)) {
         // TRANS: Exception thrown when a service document could not be located account move.
         // TRANS: %s is the remote site.
         throw new Exception(sprintf(_("Cannot find XRD for %s."), $remote));
     }
     $svcDocUrl = null;
     $username = null;
     $link = $xrd->links->get('http://apinamespace.org/atom', 'application/atomsvc+xml');
     if (!is_null($link)) {
         $svcDocUrl = $link->href;
         if (isset($link['http://apinamespace.org/atom/username'])) {
             $username = $link['http://apinamespace.org/atom/username'];
             break;
         }
     }
     if (empty($svcDocUrl)) {
         // TRANS: Exception thrown when an account could not be located when it should be moved.
         // TRANS: %s is the remote site.
         throw new Exception(sprintf(_("No AtomPub API service for %s."), $remote));
     }
     return array($svcDocUrl, $username);
 }
コード例 #4
0
ファイル: hostmeta.php プロジェクト: bashrc/gnusocial-debian
 /**
  * For RFC6415 and HTTP URIs, fetch the host-meta file
  * and look for LRDD templates
  */
 public function discover($uri)
 {
     // This is allowed for RFC6415 but not the 'WebFinger' RFC7033.
     $try_schemes = array('https', 'http');
     $scheme = mb_strtolower(parse_url($uri, PHP_URL_SCHEME));
     switch ($scheme) {
         case 'acct':
             if (!Discovery::isAcct($uri)) {
                 throw new Exception('Bad resource URI: ' . $uri);
             }
             // We can't use parse_url data for this, since the 'host'
             // entry is only set if the scheme has '://' after it.
             list($user, $domain) = explode('@', parse_url($uri, PHP_URL_PATH));
             break;
         case 'http':
         case 'https':
             $domain = mb_strtolower(parse_url($uri, PHP_URL_HOST));
             $try_schemes = array($scheme);
             break;
         default:
             throw new Exception('Unable to discover resource descriptor endpoint.');
     }
     foreach ($try_schemes as $scheme) {
         $url = $scheme . '://' . $domain . '/.well-known/host-meta';
         try {
             $response = self::fetchUrl($url);
             $this->xrd->loadString($response->getBody());
         } catch (Exception $e) {
             common_debug('LRDD could not load resource descriptor: ' . $url . ' (' . $e->getMessage() . ')');
             continue;
         }
         return $this->xrd->links;
     }
     throw new Exception('Unable to retrieve resource descriptor links.');
 }
コード例 #5
0
ファイル: web.php プロジェクト: noccy80/lepton-ng
 /**
  * @description Service Discovery
  */
 function discover()
 {
     using('lepton.net.httprequest');
     using('lepton.web.discovery');
     $d = Discovery::discover('http://127.0.0.1');
     $this->assertNotNull($d);
 }
コード例 #6
0
ファイル: userxrd.php プロジェクト: stevertiqo/StatusNet
 function prepare($args)
 {
     parent::prepare($args);
     $this->uri = $this->trimmed('uri');
     $this->uri = Discovery::normalize($this->uri);
     if (Discovery::isWebfinger($this->uri)) {
         $parts = explode('@', substr(urldecode($this->uri), 5));
         if (count($parts) == 2) {
             list($nick, $domain) = $parts;
             // @fixme confirm the domain too
             // @fixme if domain checking is added, ensure that it will not
             //        cause problems with sites that have changed domains!
             $nick = common_canonical_nickname($nick);
             $this->user = User::staticGet('nickname', $nick);
         }
     } else {
         $this->user = User::staticGet('uri', $this->uri);
         if (empty($this->user)) {
             // try and get it by profile url
             $profile = Profile::staticGet('profileurl', $this->uri);
             if (!empty($profile)) {
                 $this->user = User::staticGet('id', $profile->id);
             }
         }
     }
     if (!$this->user) {
         $this->clientError(_m('No such user.'), 404);
         return false;
     }
     return true;
 }
コード例 #7
0
 function connectWebfinger($acct)
 {
     $target_profile = $this->targetProfile();
     $disco = new Discovery();
     $xrd = $disco->lookup($acct);
     $link = $xrd->get('http://ostatus.org/schema/1.0/tag');
     if (!is_null($link)) {
         // We found a URL - let's redirect!
         if (!empty($link->template)) {
             $url = Discovery::applyTemplate($link->template, $target_profile);
         } else {
             $url = $link->href;
         }
         common_log(LOG_INFO, "Sending remote subscriber {$acct} to {$url}");
         common_redirect($url, 303);
     }
     // TRANS: Client error displayed when remote profile address could not be confirmed.
     $this->clientError(_m('Could not confirm remote profile address.'));
 }
コード例 #8
0
 function handle()
 {
     $nick = $this->user->nickname;
     $profile = $this->user->getProfile();
     if (empty($this->xrd)) {
         $xrd = new XRD();
     } else {
         $xrd = $this->xrd;
     }
     if (empty($xrd->subject)) {
         $xrd->subject = Discovery::normalize($this->uri);
     }
     // Possible aliases for the user
     $uris = array($this->user->uri, $profile->profileurl);
     // FIXME: Webfinger generation code should live somewhere on its own
     $path = common_config('site', 'path');
     if (empty($path)) {
         $uris[] = sprintf('acct:%s@%s', $nick, common_config('site', 'server'));
     }
     foreach ($uris as $uri) {
         if ($uri != $xrd->subject) {
             $xrd->alias[] = $uri;
         }
     }
     $xrd->links[] = array('rel' => Discovery::PROFILEPAGE, 'type' => 'text/html', 'href' => $profile->profileurl);
     $xrd->links[] = array('rel' => Discovery::UPDATESFROM, 'href' => common_local_url('ApiTimelineUser', array('id' => $this->user->id, 'format' => 'atom')), 'type' => 'application/atom+xml');
     // hCard
     $xrd->links[] = array('rel' => Discovery::HCARD, 'type' => 'text/html', 'href' => common_local_url('hcard', array('nickname' => $nick)));
     // XFN
     $xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11', 'type' => 'text/html', 'href' => $profile->profileurl);
     // FOAF
     $xrd->links[] = array('rel' => 'describedby', 'type' => 'application/rdf+xml', 'href' => common_local_url('foaf', array('nickname' => $nick)));
     // Salmon
     $salmon_url = common_local_url('usersalmon', array('id' => $this->user->id));
     $xrd->links[] = array('rel' => Salmon::REL_SALMON, 'href' => $salmon_url);
     // XXX : Deprecated - to be removed.
     $xrd->links[] = array('rel' => Salmon::NS_REPLIES, 'href' => $salmon_url);
     $xrd->links[] = array('rel' => Salmon::NS_MENTIONS, 'href' => $salmon_url);
     // Get this user's keypair
     $magickey = Magicsig::staticGet('user_id', $this->user->id);
     if (!$magickey) {
         // No keypair yet, let's generate one.
         $magickey = new Magicsig();
         $magickey->generate($this->user->id);
     }
     $xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL, 'href' => 'data:application/magic-public-key,' . $magickey->toString(false));
     // TODO - finalize where the redirect should go on the publisher
     $url = common_local_url('ostatussub') . '?profile={uri}';
     $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/subscribe', 'template' => $url);
     $url = common_local_url('tagprofile') . '?uri={uri}';
     $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/tag', 'template' => $url);
     header('Content-type: application/xrd+xml');
     print $xrd->toXML();
 }
コード例 #9
0
 function connectWebfinger($acct)
 {
     $target_profile = $this->targetProfile();
     $disco = new Discovery();
     $result = $disco->lookup($acct);
     if (!$result) {
         // TRANS: Client error displayed when remote profile could not be looked up.
         $this->clientError(_m('Could not look up OStatus account profile.'));
     }
     foreach ($result->links as $link) {
         if ($link['rel'] == 'http://ostatus.org/schema/1.0/tag') {
             // We found a URL - let's redirect!
             $url = Discovery::applyTemplate($link['template'], $target_profile);
             common_log(LOG_INFO, "Sending remote subscriber {$acct} to {$url}");
             common_redirect($url, 303);
         }
     }
     // TRANS: Client error displayed when remote profile address could not be confirmed.
     $this->clientError(_m('Could not confirm remote profile address.'));
 }
コード例 #10
0
ファイル: ownerxrd.php プロジェクト: bashrc/gnusocial-debian
 protected function setXRD()
 {
     parent::setXRD();
     // Check to see if a $config['webfinger']['owner'] has been set
     // and then make sure 'subject' is set to that primary identity.
     if ($owner = common_config('webfinger', 'owner')) {
         $this->xrd->aliases[] = $this->xrd->subject;
         $this->xrd->subject = Discovery::normalize($owner);
     } else {
         $this->xrd->subject = $this->resource;
     }
 }
コード例 #11
0
ファイル: webfinger.php プロジェクト: bashrc/gnusocial-debian
 /**
  * Simply returns the WebFinger URL over HTTPS at the uri's domain:
  * https://{domain}/.well-known/webfinger?resource={uri}
  */
 public function discover($uri)
 {
     if (!Discovery::isAcct($uri)) {
         throw new Exception('Bad resource URI: ' . $uri);
     }
     list($user, $domain) = explode('@', parse_url($uri, PHP_URL_PATH));
     if (!filter_var($domain, FILTER_VALIDATE_IP) && !filter_var(gethostbyname($domain), FILTER_VALIDATE_IP)) {
         throw new Exception('Bad resource host.');
     }
     $link = new XML_XRD_Element_Link(Discovery::LRDD_REL, 'https://' . $domain . '/.well-known/webfinger?resource={uri}', Discovery::JRD_MIMETYPE, true);
     //isTemplate
     return array($link);
 }
コード例 #12
0
ファイル: webfinger.php プロジェクト: bashrc/gnusocial-debian
 protected function prepare(array $args = array())
 {
     parent::prepare($args);
     // throws exception if resource is empty
     $this->resource = Discovery::normalize($this->trimmed('resource'));
     try {
         if (Event::handle('StartGetWebFingerResource', array($this->resource, &$this->target, $this->args))) {
             Event::handle('EndGetWebFingerResource', array($this->resource, &$this->target, $this->args));
         }
     } catch (NoSuchUserException $e) {
         throw new ServerException($e->getMessage(), 404);
     }
     if (!$this->target instanceof WebFingerResource) {
         // TRANS: Error message when an object URI which we cannot find was requested
         throw new ServerException(_m('Resource not found in local database.'), 404);
     }
     return true;
 }
コード例 #13
0
 function prepare($args)
 {
     $this->user = User::siteOwner();
     if (!$this->user) {
         $this->clientError(_('No such user.'), 404);
         return false;
     }
     $nick = common_canonical_nickname($this->user->nickname);
     $acct = 'acct:' . $nick . '@' . common_config('site', 'server');
     $this->xrd = new XRD();
     // Check to see if a $config['webfinger']['owner'] has been set
     if ($owner = common_config('webfinger', 'owner')) {
         $this->xrd->subject = Discovery::normalize($owner);
         $this->xrd->alias[] = $acct;
     } else {
         $this->xrd->subject = $acct;
     }
     return true;
 }
コード例 #14
0
ファイル: userxrd.php プロジェクト: himmelex/NTW
 function prepare($args)
 {
     parent::prepare($args);
     $this->uri = $this->trimmed('uri');
     $this->uri = Discovery::normalize($this->uri);
     if (Discovery::isWebfinger($this->uri)) {
         $parts = explode('@', substr(urldecode($this->uri), 5));
         if (count($parts) == 2) {
             list($nick, $domain) = $parts;
             // @fixme confirm the domain too
             $nick = common_canonical_nickname($nick);
             $this->user = User::staticGet('nickname', $nick);
         }
     } else {
         $this->user = User::staticGet('uri', $this->uri);
     }
     if (!$this->user) {
         $this->clientError(_('用户不存在'), 404);
         return false;
     }
     return true;
 }
コード例 #15
0
ファイル: xrdaction.php プロジェクト: himmelex/NTW
 function handle()
 {
     $nick = $this->user->nickname;
     if (empty($this->xrd)) {
         $xrd = new XRD();
     } else {
         $xrd = $this->xrd;
     }
     if (empty($xrd->subject)) {
         $xrd->subject = Discovery::normalize($this->uri);
     }
     $xrd->alias[] = $this->user->uri;
     $xrd->links[] = array('rel' => Discovery::PROFILEPAGE, 'type' => 'text/html', 'href' => $this->user->uri);
     $xrd->links[] = array('rel' => Discovery::UPDATESFROM, 'href' => common_local_url('ApiTimelineUser', array('id' => $this->user->id, 'format' => 'atom')), 'type' => 'application/atom+xml');
     // hCard
     $xrd->links[] = array('rel' => Discovery::HCARD, 'type' => 'text/html', 'href' => common_local_url('hcard', array('nickname' => $nick)));
     // XFN
     $xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11', 'type' => 'text/html', 'href' => $this->user->uri);
     // FOAF
     $xrd->links[] = array('rel' => 'describedby', 'type' => 'application/rdf+xml', 'href' => common_local_url('foaf', array('nickname' => $nick)));
     // Salmon
     $salmon_url = common_local_url('usersalmon', array('id' => $this->user->id));
     $xrd->links[] = array('rel' => Salmon::NS_REPLIES, 'href' => $salmon_url);
     $xrd->links[] = array('rel' => Salmon::NS_MENTIONS, 'href' => $salmon_url);
     // Get this user's keypair
     $magickey = Magicsig::staticGet('user_id', $this->user->id);
     if (!$magickey) {
         // No keypair yet, let's generate one.
         $magickey = new Magicsig();
         $magickey->generate($this->user->id);
     }
     $xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL, 'href' => 'data:application/magic-public-key,' . $magickey->toString(false));
     // TODO - finalize where the redirect should go on the publisher
     $url = common_local_url('ostatussub') . '?profile={uri}';
     $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/subscribe', 'template' => $url);
     header('Content-type: text/xml');
     print $xrd->toXML();
 }
コード例 #16
0
 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);
         // isTemplate
     }
     // OAuth connections
     $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'));
 }
コード例 #17
0
 /**
  * Get the Salmon keypair from a URI, uses XRD Discovery etc. Reasonably
  * you'll only get the public key ;)
  *
  * The string will (hopefully) be formatted as described in Magicsig specification:
  * https://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-01.html#anchor13
  *
  * @return string formatted as Magicsig keypair
  */
 public function discoverKeyPair(Profile $profile)
 {
     $signer_uri = $profile->getUri();
     if (empty($signer_uri)) {
         throw new ServerException(sprintf('Profile missing URI (id==%d)', $profile->id));
     }
     $disco = new Discovery();
     // Throws exception on lookup problems
     $xrd = $disco->lookup($signer_uri);
     $link = $xrd->get(Magicsig::PUBLICKEYREL);
     if (is_null($link)) {
         // TRANS: Exception.
         throw new Exception(_m('Unable to locate signer public key.'));
     }
     // We have a public key element, let's hope it has proper key data.
     $keypair = false;
     $parts = explode(',', $link->href);
     if (count($parts) == 2) {
         $keypair = $parts[1];
     } else {
         // Backwards compatibility check for separator bug in 0.9.0
         $parts = explode(';', $link->href);
         if (count($parts) == 2) {
             $keypair = $parts[1];
         }
     }
     if ($keypair === false) {
         // For debugging clarity. Keypair did not pass count()-check above.
         // TRANS: Exception when public key was not properly formatted.
         throw new Exception(_m('Incorrectly formatted public key element.'));
     }
     return $keypair;
 }
コード例 #18
0
 function ensureProfiles()
 {
     try {
         $this->oprofile = Ostatus_profile::getActorProfile($this->activity);
         if (!$this->oprofile instanceof Ostatus_profile) {
             throw new UnknownUriException($this->activity->actor->id);
         }
     } catch (UnknownUriException $e) {
         // Apparently we didn't find the Profile object based on our URI,
         // so OStatus doesn't have it with this URI in ostatus_profile.
         // Try to look it up again, remote side may have changed from http to https
         // or maybe publish an acct: URI now instead of an http: URL.
         //
         // Steps:
         // 1. Check the newly received URI. Who does it say it is?
         // 2. Compare these alleged identities to our local database.
         // 3. If we found any locally stored identities, ask it about its aliases.
         // 4. Do any of the aliases from our known identity match the recently introduced one?
         //
         // Example: We have stored http://example.com/user/1 but this URI says https://example.com/user/1
         common_debug('No local Profile object found for a magicsigned activity author URI: ' . $e->object_uri);
         $disco = new Discovery();
         $xrd = $disco->lookup($e->object_uri);
         // Step 1: We got a bunch of discovery data for https://example.com/user/1 which includes
         //         aliases https://example.com/user and hopefully our original http://example.com/user/1 too
         $all_ids = array_merge(array($xrd->subject), $xrd->aliases);
         if (!in_array($e->object_uri, $all_ids)) {
             common_debug('The activity author URI we got was not listed itself when doing discovery on it.');
             throw $e;
         }
         // Go through each reported alias from lookup to see if we know this already
         foreach ($all_ids as $aliased_uri) {
             $oprofile = Ostatus_profile::getKV('uri', $aliased_uri);
             if (!$oprofile instanceof Ostatus_profile) {
                 continue;
                 // unknown locally, check the next alias
             }
             // Step 2: We found the alleged http://example.com/user/1 URI in our local database,
             //         but this can't be trusted yet because anyone can publish any alias.
             common_debug('Found a local Ostatus_profile for "' . $e->object_uri . '" with this URI: ' . $aliased_uri);
             // We found an existing OStatus profile, but is it really the same? Do a callback to the URI's origin
             // Step 3: lookup our previously known http://example.com/user/1 webfinger etc.
             $xrd = $disco->lookup($oprofile->getUri());
             // getUri returns ->uri, which we filtered on earlier
             $doublecheck_aliases = array_merge(array($xrd->subject), $xrd->aliases);
             common_debug('Trying to match known "' . $aliased_uri . '" against its returned aliases: ' . implode(' ', $doublecheck_aliases));
             // if we find our original URI here, it is a legitimate alias
             // Step 4: Is the newly introduced https://example.com/user/1 URI in the list of aliases
             //         presented by http://example.com/user/1 (i.e. do they both say they are the same identity?)
             if (in_array($e->object_uri, $doublecheck_aliases)) {
                 $oprofile->updateUriKeys($e->object_uri, DiscoveryHints::fromXRD($xrd));
                 $this->oprofile = $oprofile;
                 break;
                 // don't iterate through aliases anymore
             }
         }
         // We might end up here after $all_ids is iterated through without a $this->oprofile value,
         if (!$this->oprofile instanceof Ostatus_profile) {
             common_debug("We do not have a local profile to connect to this activity's author. Let's create one.");
             // ensureActivityObjectProfile throws exception on failure
             $this->oprofile = Ostatus_profile::ensureActivityObjectProfile($this->activity->actor);
         }
     }
     assert($this->oprofile instanceof Ostatus_profile);
     $this->actor = $this->oprofile->localProfile();
 }
コード例 #19
0
ファイル: Simple.php プロジェクト: rupertj/alb-oembed
 public static function getProvider($url)
 {
     $discovery = new Discovery();
     return $discovery->discover($url);
 }
コード例 #20
0
 /**
  * Look up, and if necessary create, an Ostatus_profile for the remote
  * entity with the given webfinger address.
  * This should never return null -- you will either get an object or
  * an exception will be thrown.
  *
  * @param string $addr webfinger address
  * @return Ostatus_profile
  * @throws Exception on error conditions
  * @throws OStatusShadowException if this reference would obscure a local user/group
  */
 public static function updateWebfinger($addr)
 {
     $disco = new Discovery();
     try {
         $xrd = $disco->lookup($addr);
     } catch (Exception $e) {
         // Save negative cache entry so we don't waste time looking it up again.
         // @fixme distinguish temporary failures?
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null);
         // TRANS: Exception.
         throw new Exception(_m('Not a valid webfinger address.'));
     }
     $hints = array('webfinger' => $addr);
     $dhints = DiscoveryHints::fromXRD($xrd);
     $hints = array_merge($hints, $dhints);
     // If there's an Hcard, let's grab its info
     if (array_key_exists('hcard', $hints)) {
         if (!array_key_exists('profileurl', $hints) || $hints['hcard'] != $hints['profileurl']) {
             $hcardHints = DiscoveryHints::fromHcardUrl($hints['hcard']);
             $hints = array_merge($hcardHints, $hints);
         }
     }
     // If we got a feed URL, try that
     if (array_key_exists('feedurl', $hints)) {
         try {
             common_log(LOG_INFO, "Discovery on acct:{$addr} with feed URL " . $hints['feedurl']);
             $oprofile = self::ensureFeedURL($hints['feedurl'], $hints);
             self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
             return $oprofile;
         } catch (Exception $e) {
             common_log(LOG_WARNING, "Failed creating profile from feed URL '{$feedUrl}': " . $e->getMessage());
             // keep looking
         }
     }
     // If we got a profile page, try that!
     if (array_key_exists('profileurl', $hints)) {
         try {
             common_log(LOG_INFO, "Discovery on acct:{$addr} with profile URL {$profileUrl}");
             $oprofile = self::ensureProfileURL($hints['profileurl'], $hints);
             self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
             return $oprofile;
         } catch (OStatusShadowException $e) {
             // We've ended up with a remote reference to a local user or group.
             // @fixme ideally we should be able to say who it was so we can
             // go back and refer to it the regular way
             throw $e;
         } catch (Exception $e) {
             common_log(LOG_WARNING, "Failed creating profile from profile URL '{$profileUrl}': " . $e->getMessage());
             // keep looking
             //
             // @fixme this means an error discovering from profile page
             // may give us a corrupt entry using the webfinger URI, which
             // will obscure the correct page-keyed profile later on.
         }
     }
     throw new Exception(sprintf(_m('Could not find a valid profile for "%s".'), $addr));
 }
コード例 #21
0
ファイル: discovery_new.php プロジェクト: bmchun/sunset
<?php

//发现页面数据调用接口
require_once '../../models/Response.php';
require_once '../..//models/Discovery.php';
$style = new Response();
//$gender = isset($_GET['gender'])?$_GET['gender']:0;
$pageId = isset($_GET['pageId']) ? $_GET['pageId'] : 1;
$re = new Discovery();
$data = $re->presentForHuman2($pageId);
echo $style->show('200', $data);
コード例 #22
0
 /**
  * Get the Salmon keypair from a URI, uses XRD Discovery etc. Reasonably
  * you'll only get the public key ;)
  *
  * The string will (hopefully) be formatted as described in Magicsig specification:
  * https://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-01.html#anchor13
  *
  * @return string formatted as Magicsig keypair
  */
 public function discoverKeyPair(Profile $profile)
 {
     $signer_uri = $profile->getUri();
     if (empty($signer_uri)) {
         throw new ServerException(sprintf('Profile missing URI (id==%d)', $profile->getID()));
     }
     $disco = new Discovery();
     // Throws exception on lookup problems
     try {
         $xrd = $disco->lookup($signer_uri);
     } catch (Exception $e) {
         // Diaspora seems to require us to request the acct: uri
         $xrd = $disco->lookup($profile->getAcctUri());
     }
     common_debug('Will try to find magic-public-key from XRD of profile id==' . $profile->getID());
     $pubkey = null;
     if (Event::handle('MagicsigPublicKeyFromXRD', array($xrd, &$pubkey))) {
         $link = $xrd->get(Magicsig::PUBLICKEYREL);
         if (is_null($link)) {
             // TRANS: Exception.
             throw new Exception(_m('Unable to locate signer public key.'));
         }
         $pubkey = $link->href;
     }
     if (empty($pubkey)) {
         throw new ServerException('Empty Magicsig public key. A bug?');
     }
     // We have a public key element, let's hope it has proper key data.
     $keypair = false;
     $parts = explode(',', $pubkey);
     if (count($parts) == 2) {
         $keypair = $parts[1];
     } else {
         // Backwards compatibility check for separator bug in 0.9.0
         $parts = explode(';', $pubkey);
         if (count($parts) == 2) {
             $keypair = $parts[1];
         }
     }
     if ($keypair === false) {
         // For debugging clarity. Keypair did not pass count()-check above.
         // TRANS: Exception when public key was not properly formatted.
         throw new Exception(_m('Incorrectly formatted public key element.'));
     }
     return $keypair;
 }
コード例 #23
0
ファイル: presentnumber.php プロジェクト: bmchun/sunset
<?php

require_once '../..//models/Discovery.php';
require_once '../..//models/Response.php';
//获取发现页中的给爸/妈礼物数量
$re = new Discovery();
$data['father'] = $re->numForHuman(1);
$data['mother'] = $re->numForHuman(0);
echo Response::show('200', $data);
コード例 #24
0
print "Re-running feed discovery for profile URL {$oprofile->uri}\n";
$feedurl = null;
$salmonuri = null;
// @fixme will bork where the URI isn't the profile URL for now
$discover = new FeedDiscovery();
try {
    $feedurl = $discover->discoverFromURL($oprofile->uri);
    $salmonuri = $discover->getAtomLink(Salmon::REL_SALMON) ?: $discover->getAtomLink(Salmon::NS_REPLIES);
    // NS_REPLIES is deprecated
    if (empty($salmonuri)) {
        throw new FeedSubNoSalmonException('No salmon upstream URI was found');
    }
} catch (FeedSubException $e) {
    $acct = $oprofile->localProfile()->getAcctUri();
    print "Could not discover feeds HTML response, trying reconstructed acct URI: {$acct}\n";
    $disco = new Discovery();
    $xrd = $disco->lookup($acct);
    $hints = DiscoveryHints::fromXRD($xrd);
    if (empty($feedurl) && !array_key_exists('feedurl', $hints)) {
        throw new FeedSubNoFeedException($acct);
    }
    $feedurl = $feedurl ?: $hints['feedurl'];
    $salmonuri = array_key_exists('salmon', $hints) ? $hints['salmon'] : $salmonuri;
    // get the hub data too and put it in the FeedDiscovery object
    $discover->discoverFromFeedUrl($feedurl);
}
$huburi = $discover->getHubLink();
print "  Feed URL: {$feedurl}\n";
print "  Hub URL: {$huburi}\n";
print "  Salmon URL: {$salmonuri}\n";
if ($feedurl != $oprofile->feeduri || $salmonuri != $oprofile->salmonuri) {
コード例 #25
0
ファイル: discovery.php プロジェクト: bmchun/sunset
<?php

//发现页面数据调用接口
require_once '../../models/Response.php';
require_once '../..//models/Discovery.php';
$style = new Response();
$gender = isset($_GET['gender']) ? $_GET['gender'] : NULL;
$pageId = isset($_GET['page']) ? $_GET['page'] : 1;
$uid = isset($_GET['uid']) ? $_GET['uid'] : 1;
$type = isset($_GET['type']) ? $_GET['type'] : NULL;
$re = new Discovery();
$data = $re->presentForHuman($gender, $type, $pageId, $uid);
echo $style->show('200', $data);
コード例 #26
0
ファイル: discovery.php プロジェクト: bashrc/gnusocial-debian
 /**
  * Given a user ID, return the first available resource descriptor
  *
  * @param string $id User ID URI
  *
  * @return XML_XRD object for the resource descriptor of the id
  */
 public function lookup($id)
 {
     // Normalize the incoming $id to make sure we have a uri
     $uri = self::normalize($id);
     foreach ($this->methods as $class) {
         try {
             $xrd = new XML_XRD();
             common_debug("LRDD discovery method for '{$uri}': {$class}");
             $lrdd = new $class();
             $links = call_user_func(array($lrdd, 'discover'), $uri);
             $link = Discovery::getService($links, Discovery::LRDD_REL);
             // Load the LRDD XRD
             if (!empty($link->template)) {
                 $xrd_uri = Discovery::applyTemplate($link->template, $uri);
             } elseif (!empty($link->href)) {
                 $xrd_uri = $link->href;
             } else {
                 throw new Exception('No resource descriptor URI in link.');
             }
             $client = new HTTPClient();
             $headers = array();
             if (!is_null($link->type)) {
                 $headers[] = "Accept: {$link->type}";
             }
             $response = $client->get($xrd_uri, $headers);
             if ($response->getStatus() != 200) {
                 throw new Exception('Unexpected HTTP status code.');
             }
             $xrd->loadString($response->getBody());
             return $xrd;
         } catch (Exception $e) {
             continue;
         }
     }
     // TRANS: Exception. %s is an ID.
     throw new Exception(sprintf(_('Unable to find services for %s.'), $id));
 }
コード例 #27
0
 public function onEndDiscoveryMethodRegistration(Discovery $disco)
 {
     $disco->registerMethod('LRDDMethod_HostMeta');
     $disco->registerMethod('LRDDMethod_LinkHeader');
     $disco->registerMethod('LRDDMethod_LinkHTML');
 }
コード例 #28
0
ファイル: discovery.php プロジェクト: stevertiqo/StatusNet
 public function discover($uri)
 {
     if (Discovery::isWebfinger($uri)) {
         // We have a webfinger acct: - start with host-meta
         list($name, $domain) = explode('@', $uri);
     } else {
         $domain = parse_url($uri, PHP_URL_HOST);
     }
     $url = 'http://' . $domain . '/.well-known/host-meta';
     $xrd = Discovery::fetchXrd($url);
     if ($xrd) {
         if ($xrd->host != $domain) {
             return false;
         }
         return $xrd->links;
     }
 }
コード例 #29
0
 /**
  * Look up, and if necessary create, an Ostatus_profile for the remote
  * entity with the given webfinger address.
  * This should never return null -- you will either get an object or
  * an exception will be thrown.
  *
  * @param string $addr webfinger address
  * @return Ostatus_profile
  * @throws Exception on error conditions
  * @throws OStatusShadowException if this reference would obscure a local user/group
  */
 public static function ensureWebfinger($addr)
 {
     // First, try the cache
     $uri = self::cacheGet(sprintf('ostatus_profile:webfinger:%s', $addr));
     if ($uri !== false) {
         if (is_null($uri)) {
             // Negative cache entry
             // TRANS: Exception.
             throw new Exception(_m('Not a valid webfinger address.'));
         }
         $oprofile = Ostatus_profile::getKV('uri', $uri);
         if ($oprofile instanceof Ostatus_profile) {
             return $oprofile;
         }
     }
     // Try looking it up
     $oprofile = Ostatus_profile::getKV('uri', Discovery::normalize($addr));
     if ($oprofile instanceof Ostatus_profile) {
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri());
         return $oprofile;
     }
     // Now, try some discovery
     $disco = new Discovery();
     try {
         $xrd = $disco->lookup($addr);
     } catch (Exception $e) {
         // Save negative cache entry so we don't waste time looking it up again.
         // @todo FIXME: Distinguish temporary failures?
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null);
         // TRANS: Exception.
         throw new Exception(_m('Not a valid webfinger address.'));
     }
     $hints = array_merge(array('webfinger' => $addr), DiscoveryHints::fromXRD($xrd));
     // If there's an Hcard, let's grab its info
     if (array_key_exists('hcard', $hints)) {
         if (!array_key_exists('profileurl', $hints) || $hints['hcard'] != $hints['profileurl']) {
             $hcardHints = DiscoveryHints::fromHcardUrl($hints['hcard']);
             $hints = array_merge($hcardHints, $hints);
         }
     }
     // If we got a feed URL, try that
     $feedUrl = null;
     if (array_key_exists('feedurl', $hints)) {
         $feedUrl = $hints['feedurl'];
         try {
             common_log(LOG_INFO, "Discovery on acct:{$addr} with feed URL " . $hints['feedurl']);
             $oprofile = self::ensureFeedURL($hints['feedurl'], $hints);
             self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri());
             return $oprofile;
         } catch (Exception $e) {
             common_log(LOG_WARNING, "Failed creating profile from feed URL '{$feedUrl}': " . $e->getMessage());
             // keep looking
         }
     }
     // If we got a profile page, try that!
     $profileUrl = null;
     if (array_key_exists('profileurl', $hints)) {
         $profileUrl = $hints['profileurl'];
         try {
             common_log(LOG_INFO, "Discovery on acct:{$addr} with profile URL {$profileUrl}");
             $oprofile = self::ensureProfileURL($hints['profileurl'], $hints);
             self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri());
             return $oprofile;
         } catch (OStatusShadowException $e) {
             // We've ended up with a remote reference to a local user or group.
             // @todo FIXME: Ideally we should be able to say who it was so we can
             // go back and refer to it the regular way
             throw $e;
         } catch (Exception $e) {
             common_log(LOG_WARNING, "Failed creating profile from profile URL '{$profileUrl}': " . $e->getMessage());
             // keep looking
             //
             // @todo FIXME: This means an error discovering from profile page
             // may give us a corrupt entry using the webfinger URI, which
             // will obscure the correct page-keyed profile later on.
         }
     }
     // XXX: try hcard
     // XXX: try FOAF
     if (array_key_exists('salmon', $hints)) {
         $salmonEndpoint = $hints['salmon'];
         // An account URL, a salmon endpoint, and a dream? Not much to go
         // on, but let's give it a try
         $uri = 'acct:' . $addr;
         $profile = new Profile();
         $profile->nickname = self::nicknameFromUri($uri);
         $profile->created = common_sql_now();
         if (!is_null($profileUrl)) {
             $profile->profileurl = $profileUrl;
         }
         $profile_id = $profile->insert();
         if ($profile_id === false) {
             common_log_db_error($profile, 'INSERT', __FILE__);
             // TRANS: Exception. %s is a webfinger address.
             throw new Exception(sprintf(_m('Could not save profile for "%s".'), $addr));
         }
         $oprofile = new Ostatus_profile();
         $oprofile->uri = $uri;
         $oprofile->salmonuri = $salmonEndpoint;
         $oprofile->profile_id = $profile_id;
         $oprofile->created = common_sql_now();
         if (!is_null($feedUrl)) {
             $oprofile->feeduri = $feedUrl;
         }
         $result = $oprofile->insert();
         if ($result === false) {
             $profile->delete();
             common_log_db_error($oprofile, 'INSERT', __FILE__);
             // TRANS: Exception. %s is a webfinger address.
             throw new Exception(sprintf(_m('Could not save OStatus profile for "%s".'), $addr));
         }
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri());
         return $oprofile;
     }
     // TRANS: Exception. %s is a webfinger address.
     throw new Exception(sprintf(_m('Could not find a valid profile for "%s".'), $addr));
 }
コード例 #30
0
ファイル: xrdaction.php プロジェクト: bashrc/gnusocial-debian
 protected function checkAccept()
 {
     $type = null;
     $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null;
     $useragent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
     if ($httpaccept !== null && $httpaccept != '*/*') {
         $can_serve = implode(',', Discovery::supportedMimeTypes());
         $type = common_negotiate_type(common_accept_to_prefs($httpaccept), common_accept_to_prefs($can_serve));
     } else {
         /*
          * HACK: for StatusNet to work against us, we must always serve an
          * XRD to at least versions <1.1.1 (at time of writing) since they
          * don't send Accept headers (in their 'Discovery::fetchXrd' calls)
          */
         $matches = array();
         preg_match('/(StatusNet)\\/(\\d+\\.\\d+(\\.\\d+)?)/', $useragent, $browser);
         if (count($browser) > 2 && $browser[1] === 'StatusNet' && version_compare($browser[2], '1.1.1') < 1) {
             return Discovery::XRD_MIMETYPE;
         }
     }
     if (empty($type)) {
         throw new Exception(_('No specified MIME type in Accept header.'));
     }
     return $type;
 }