function handle($notice)
 {
     assert($notice instanceof Notice);
     $this->notice = $notice;
     $this->user = User::staticGet($notice->profile_id);
     $this->pushUser();
     foreach ($notice->getGroups() as $group) {
         $oprofile = Ostatus_profile::staticGet('group_id', $group->id);
         if ($oprofile) {
             $this->pingReply($oprofile);
         } else {
             $this->pushGroup($group->id);
         }
     }
     foreach ($notice->getReplies() as $profile_id) {
         $oprofile = Ostatus_profile::staticGet('profile_id', $profile_id);
         if ($oprofile) {
             $this->pingReply($oprofile);
         }
     }
     if (!empty($this->notice->reply_to)) {
         $replyTo = Notice::staticGet('id', $this->notice->reply_to);
         if (!empty($replyTo)) {
             foreach ($replyTo->getReplies() as $profile_id) {
                 $oprofile = Ostatus_profile::staticGet('profile_id', $profile_id);
                 if ($oprofile) {
                     $this->pingReply($oprofile);
                 }
             }
         }
     }
     return true;
 }
예제 #2
0
 function prepare($args)
 {
     parent::prepare($args);
     $id = $this->trimmed('id');
     if (!$id) {
         $this->clientError(_('No ID.'));
     }
     $this->group = User_group::staticGet('id', $id);
     if (empty($this->group)) {
         $this->clientError(_('No such group.'));
     }
     $oprofile = Ostatus_profile::staticGet('group_id', $id);
     if ($oprofile) {
         $this->clientError(_m("Can't accept remote posts for a remote group."));
     }
     return true;
 }
예제 #3
0
 function handle($notice)
 {
     assert($notice instanceof Notice);
     $this->notice = $notice;
     $this->user = User::staticGet('id', $notice->profile_id);
     try {
         $profile = $this->notice->getProfile();
     } catch (Exception $e) {
         common_log(LOG_ERR, "Can't get profile for notice; skipping: " . $e->getMessage());
         return true;
     }
     $this->pushUser();
     foreach ($notice->getGroups() as $group) {
         $oprofile = Ostatus_profile::staticGet('group_id', $group->id);
         if ($oprofile) {
             $this->pingReply($oprofile);
         } else {
             $this->pushGroup($group->id);
         }
     }
     foreach ($notice->getReplies() as $profile_id) {
         $oprofile = Ostatus_profile::staticGet('profile_id', $profile_id);
         if ($oprofile) {
             $this->pingReply($oprofile);
         }
     }
     if (!empty($this->notice->reply_to)) {
         $replyTo = Notice::staticGet('id', $this->notice->reply_to);
         if (!empty($replyTo)) {
             foreach ($replyTo->getReplies() as $profile_id) {
                 $oprofile = Ostatus_profile::staticGet('profile_id', $profile_id);
                 if ($oprofile) {
                     $this->pingReply($oprofile);
                 }
             }
         }
     }
     foreach ($notice->getProfileTags() as $ptag) {
         $oprofile = Ostatus_profile::staticGet('peopletag_id', $ptag->id);
         if (!$oprofile) {
             $this->pushPeopletag($ptag);
         }
     }
     return true;
 }
예제 #4
0
 function prepare($args)
 {
     parent::prepare($args);
     $id = $this->trimmed('id');
     if (!$id) {
         // TRANS: Client error displayed trying to perform an action without providing an ID.
         $this->clientError(_m('No ID.'));
     }
     $this->peopletag = Profile_list::staticGet('id', $id);
     if (empty($this->peopletag)) {
         // TRANS: Client error displayed when referring to a non-existing list.
         $this->clientError(_m('No such list.'));
     }
     $oprofile = Ostatus_profile::staticGet('peopletag_id', $id);
     if (!empty($oprofile)) {
         // TRANS: Client error displayed when trying to send a message to a remote list.
         $this->clientError(_m('Cannot accept remote posts for a remote list.'));
     }
     return true;
 }
function fixProfile($uri)
{
    $oprofile = Ostatus_profile::staticGet('uri', $uri);
    if (!$oprofile) {
        print "No OStatus remote profile known for URI {$uri}\n";
        return false;
    }
    echo "Before:\n";
    showProfileInfo($oprofile);
    $feedurl = $oprofile->feeduri;
    $client = new HttpClient();
    $response = $client->get($feedurl);
    if ($response->isOk()) {
        echo "Updating profile from feed: {$feedurl}\n";
        $dom = new DOMDocument();
        if ($dom->loadXML($response->getBody())) {
            $feed = $dom->documentElement;
            $entries = $dom->getElementsByTagNameNS(Activity::ATOM, 'entry');
            if ($entries->length) {
                $entry = $entries->item(0);
                $activity = new Activity($entry, $feed);
                $oprofile->checkAuthorship($activity);
                echo "  (ok)\n";
            } else {
                echo "  (no entry; skipping)\n";
                return false;
            }
        } else {
            echo "  (bad feed; skipping)\n";
            return false;
        }
    } else {
        echo "Failed feed fetch: {$response->getStatus()} for {$feedurl}\n";
        return false;
    }
    echo "After:\n";
    showProfileInfo($oprofile);
    return true;
}
예제 #6
0
 static function ensureProfileURI($uri)
 {
     $oprofile = null;
     // First, try to query it
     $oprofile = Ostatus_profile::staticGet('uri', $uri);
     // If unfound, do discovery stuff
     if (empty($oprofile)) {
         if (preg_match("/^(\\w+)\\:(.*)/", $uri, $match)) {
             $protocol = $match[1];
             switch ($protocol) {
                 case 'http':
                 case 'https':
                     $oprofile = Ostatus_profile::ensureProfileURL($uri);
                     break;
                 case 'acct':
                 case 'mailto':
                     $rest = $match[2];
                     $oprofile = Ostatus_profile::ensureWebfinger($rest);
                     break;
                 default:
                     // TRANS: Server exception.
                     // TRANS: %1$s is a protocol, %2$s is a URI.
                     throw new ServerException(sprintf(_m('Unrecognized URI protocol for profile: %1$s (%2$s).'), $protocol, $uri));
                     break;
             }
         } else {
             // TRANS: Server exception. %s is a URI.
             throw new ServerException(sprintf(_m('No URI protocol for profile: %s.'), $uri));
         }
     }
     return $oprofile;
 }
예제 #7
0
 static function ensureProfileURI($uri)
 {
     $oprofile = null;
     // First, try to query it
     $oprofile = Ostatus_profile::staticGet('uri', $uri);
     // If unfound, do discovery stuff
     if (empty($oprofile)) {
         if (preg_match("/^(\\w+)\\:(.*)/", $uri, $match)) {
             $protocol = $match[1];
             switch ($protocol) {
                 case 'http':
                 case 'https':
                     $oprofile = Ostatus_profile::ensureProfileURL($uri);
                     break;
                 case 'acct':
                 case 'mailto':
                     $rest = $match[2];
                     $oprofile = Ostatus_profile::ensureWebfinger($rest);
                     break;
                 default:
                     throw new ServerException("Unrecognized URI protocol for profile: {$protocol} ({$uri})");
                     break;
             }
         } else {
             throw new ServerException("No URI protocol for profile: ({$uri})");
         }
     }
     return $oprofile;
 }
예제 #8
0
 public function onStartProfileGetAtomFeed($profile, &$feed)
 {
     $oprofile = Ostatus_profile::staticGet('profile_id', $profile->id);
     if (empty($oprofile)) {
         return true;
     }
     $feed = $oprofile->feeduri;
     return false;
 }
예제 #9
0
 private function getFeed($profile)
 {
     // Ok this is a bit of a hack. ;)
     if (class_exists('Ostatus_profile')) {
         $oprofile = Ostatus_profile::staticGet('profile_id', $profile->id);
         if ($oprofile) {
             return $oprofile->feeduri;
         }
     }
     var_dump('wtf');
     return false;
 }
 /**
  * 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
             throw new Exception('Not a valid webfinger address.');
         }
         $oprofile = Ostatus_profile::staticGet('uri', $uri);
         if (!empty($oprofile)) {
             return $oprofile;
         }
     }
     // Try looking it up
     $oprofile = Ostatus_profile::staticGet('uri', 'acct:' . $addr);
     if (!empty($oprofile)) {
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
         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.
         // @fixme distinguish temporary failures?
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null);
         throw new Exception('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.
         }
     }
     // 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 (isset($profileUrl)) {
             $profile->profileurl = $profileUrl;
         }
         $profile_id = $profile->insert();
         if (!$profile_id) {
             common_log_db_error($profile, 'INSERT', __FILE__);
             throw new Exception("Couldn't save profile for '{$addr}'");
         }
         $oprofile = new Ostatus_profile();
         $oprofile->uri = $uri;
         $oprofile->salmonuri = $salmonEndpoint;
         $oprofile->profile_id = $profile_id;
         $oprofile->created = common_sql_now();
         if (isset($feedUrl)) {
             $profile->feeduri = $feedUrl;
         }
         $result = $oprofile->insert();
         if (!$result) {
             common_log_db_error($oprofile, 'INSERT', __FILE__);
             throw new Exception("Couldn't save ostatus_profile for '{$addr}'");
         }
         self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
         return $oprofile;
     }
     throw new Exception("Couldn't find a valid profile for '{$addr}'");
 }
 function onStartUserGroupPermalink($group, &$url)
 {
     $oprofile = Ostatus_profile::staticGet('group_id', $group->id);
     if ($oprofile) {
         // @fixme this should probably be in the user_group table
         // @fixme this uri not guaranteed to be a profile page
         $url = $oprofile->uri;
         return false;
     }
 }
예제 #12
0
// Not all group entries will have this filled out, though, as it's new!
echo "Checking for bogus ostatus_profile entries matching local user_group.uri...\n";
$group = new User_group();
$group->joinAdd(array('uri', 'ostatus_profile:uri'));
$group->joinAdd(array('id', 'local_group:group_id'));
$group->find();
$count = $group->N;
echo "Found {$count}...\n";
while ($group->fetch()) {
    $uri = $group->uri;
    echo "group {$group->id} ({$group->nickname}) hidden by {$uri}";
    if ($dry) {
        echo " - skipping\n";
    } else {
        echo " - removing bogus ostatus_profile entry...";
        $evil = Ostatus_profile::staticGet('uri', $uri);
        $evil->delete();
        echo "  ok\n";
    }
}
echo "\n";
// And there may be user_group entries remaining where we've already killed
// the ostatus_profile. These were "harmless" until our lookup started actually
// using the uri field, at which point we can clearly see it breaks stuff.
echo "Checking for leftover bogus user_group.uri entries obscuring local_group entries...\n";
$group = new User_group();
$group->joinAdd(array('id', 'local_group:group_id'), 'LEFT');
$group->whereAdd('group_id IS NULL');
$marker = mt_rand(31337, 31337000);
$groupTemplate = common_local_url('groupbyid', array('id' => $marker));
$encGroup = $group->escape($groupTemplate, true);
예제 #13
0
 function onStartGetProfileFromURI($uri, &$profile)
 {
     // XXX: do discovery here instead (OStatus_profile::ensureProfileURI($uri))
     $oprofile = Ostatus_profile::staticGet('uri', $uri);
     if (!empty($oprofile) && !$oprofile->isGroup()) {
         $profile = $oprofile->localProfile();
         return false;
     }
     return true;
 }
예제 #14
0
 function saveMirror()
 {
     $mirror = SubMirror::getMirror($this->user, $this->profile);
     if (!$mirror) {
         $this->clientError(_m('Requested edit of missing mirror'));
     }
     if ($this->delete) {
         $mirror->delete();
         $oprofile = Ostatus_profile::staticGet('profile_id', $this->profile->id);
         if ($oprofile) {
             $oprofile->garbageCollect();
         }
     } else {
         if ($this->style != $mirror->style) {
             $orig = clone $mirror;
             $mirror->style = $this->style;
             $mirror->modified = common_sql_now();
             $mirror->update($orig);
         }
     }
 }
예제 #15
0
 function saveMirror()
 {
     $mirror = SubMirror::getMirror($this->user, $this->profile);
     if (!$mirror) {
         // TRANS: Client error thrown when a mirror request is made and no result is retrieved.
         $this->clientError(_m('Requested edit of missing mirror.'));
     }
     if ($this->delete) {
         $mirror->delete();
         $oprofile = Ostatus_profile::staticGet('profile_id', $this->profile->id);
         if ($oprofile) {
             $oprofile->garbageCollect();
         }
     } else {
         if ($this->style != $mirror->style) {
             $orig = clone $mirror;
             $mirror->style = $this->style;
             $mirror->modified = common_sql_now();
             $mirror->update($orig);
         }
     }
 }