Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 2
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();
 }
Ejemplo n.º 3
0
 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;
     }
 }
Ejemplo n.º 4
0
 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;
 }
Ejemplo n.º 5
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;
 }
Ejemplo n.º 6
0
 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;
 }
Ejemplo n.º 7
0
 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();
 }
Ejemplo n.º 8
0
 function handle($object)
 {
     list($user, $remote, $password) = $object;
     $remote = Discovery::normalize($remote);
     $oprofile = Ostatus_profile::ensureProfileURI($remote);
     if (empty($oprofile)) {
         // 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(_("Cannot locate account %s."), $remote));
     }
     list($svcDocUrl, $username) = self::getServiceDocument($remote);
     $sink = new ActivitySink($svcDocUrl, $username, $password);
     $this->log(LOG_INFO, "Moving user {$user->nickname} " . "to {$remote}.");
     $stream = new UserActivityStream($user);
     // Reverse activities to run in correct chron order
     $acts = array_reverse($stream->activities);
     $this->log(LOG_INFO, "Got " . count($acts) . " activities " . "for {$user->nickname}.");
     $qm = QueueManager::get();
     foreach ($acts as $act) {
         $qm->enqueue(array($act, $sink, $user->uri, $remote), 'actmove');
     }
     $this->log(LOG_INFO, "Finished moving user {$user->nickname} " . "to {$remote}.");
 }
Ejemplo n.º 9
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));
 }
Ejemplo n.º 10
0
 public static function isWebfinger($user_id)
 {
     $uri = Discovery::normalize($user_id);
     return substr($uri, 0, 5) == 'acct:';
 }