protected function prepare(array $args = array()) { 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::getKV('id', $id); if (!$this->peopletag instanceof Profile_list) { // TRANS: Client error displayed when referring to a non-existing list. $this->clientError(_m('No such list.')); } $this->target = $this->peopletag; $remote_list = Ostatus_profile::getKV('peopletag_id', $id); if ($remote_list instanceof Ostatus_profile) { // 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; }
protected function prepare(array $args = array()) { parent::prepare($args); $id = $this->trimmed('id'); if (!$id) { // TRANS: Client error. $this->clientError(_m('No ID.')); } $this->group = User_group::getKV('id', $id); if (!$this->group instanceof User_group) { // TRANS: Client error. $this->clientError(_m('No such group.')); } $this->target = $this->group; $remote_group = Ostatus_profile::getKV('group_id', $id); if ($remote_group instanceof Ostatus_profile) { // TRANS: Client error. $this->clientError(_m('Cannot accept remote posts for a remote group.')); } return true; }
function fixProfile($uri) { $oprofile = Ostatus_profile::getKV('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; }
static function ensureProfileURI($uri) { $oprofile = null; // First, try to query it $oprofile = Ostatus_profile::getKV('uri', $uri); if ($oprofile instanceof Ostatus_profile) { return $oprofile; } // If unfound, do discovery stuff if (preg_match("/^(\\w+)\\:(.*)/", $uri, $match)) { $protocol = $match[1]; switch ($protocol) { case 'http': case 'https': $oprofile = self::ensureProfileURL($uri); break; case 'acct': case 'mailto': $rest = $match[2]; $oprofile = self::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)); } } else { // TRANS: Server exception. %s is a URI. throw new ServerException(sprintf(_m('No URI protocol for profile: %s.'), $uri)); } return $oprofile; }
/** * Checks for deleted remote notices and deleted the locally * A local qvitter-delete-notice is outputted in the onNoticeDeleteRelated event above * * @return boolean hook flag */ public function onEndHandleFeedEntry($activity) { if ($activity->verb == 'qvitter-delete-notice' && class_exists('StatusNet') && !array_key_exists('ActivityModeration', StatusNet::getActivePlugins())) { $deleter_profile_uri = $activity->actor->id; $deleted_notice_uri = $activity->objects[0]->objects[0]->content; $deleted_notice_uri = substr($deleted_notice_uri, strpos($deleted_notice_uri, '{{') + 2); $deleted_notice_uri = substr($deleted_notice_uri, 0, strpos($deleted_notice_uri, '}}')); $deleter_ostatus_profile = Ostatus_profile::getKV('uri', $deleter_profile_uri); if (!$deleter_ostatus_profile instanceof Ostatus_profile) { return true; } $deleter_profile = Profile::getKV('id', $deleter_ostatus_profile->profile_id); $deleted_notice = Notice::getKV('uri', $deleted_notice_uri); if (!$deleter_profile instanceof Profile || !$deleted_notice instanceof Notice) { return true; } if ($deleter_profile->id != $deleted_notice->profile_id) { return true; } $deleted_notice->delete(); } return true; }
/** * Checks for deleted remote notices and deleted the locally * A local qvitter-delete-notice is outputted in the onNoticeDeleteRelated event above * * @return boolean hook flag */ public function onEndHandleFeedEntry($activity) { if ($activity->verb == 'qvitter-delete-notice') { $deleter_profile_uri = $activity->actor->id; $deleted_notice_uri = $activity->objects[0]->objects[0]->content; $deleted_notice_uri = substr($deleted_notice_uri, strpos($deleted_notice_uri, '{{') + 2); $deleted_notice_uri = substr($deleted_notice_uri, 0, strpos($deleted_notice_uri, '}}')); $deleter_ostatus_profile = Ostatus_profile::getKV('uri', $deleter_profile_uri); if (!$deleter_ostatus_profile instanceof Ostatus_profile) { return true; } $deleter_profile = Profile::getKV('id', $deleter_ostatus_profile->profile_id); $deleted_notice = Notice::getKV('uri', $deleted_notice_uri); if (!$deleter_profile instanceof Profile || !$deleted_notice instanceof Notice) { return true; } if ($deleter_profile->id != $deleted_notice->profile_id) { return true; } $deleted_notice->delete(); } return true; }
print "Failed to update sub record...\n"; exit(1); } } else { print "\n"; print "Feed record ok, not changing.\n\n"; } echo "\n"; echo "Pinging hub {$sub->huburi} with new subscription for {$sub->uri}\n"; try { $sub->subscribe(); echo "ok\n"; } catch (Exception $e) { echo 'Could not confirm. ' . get_class($e) . ': ' . $e->getMessage() . "\n"; } $o2 = Ostatus_profile::getKV('uri', $uri); print "\n"; print "New profile state:\n"; showProfile($o2); print "\n"; print "New feed state:\n"; $sub2 = FeedSub::ensureFeed($feedurl); showSub($sub2); function showProfile($oprofile) { print " Feed URL: {$oprofile->feeduri}\n"; print " Salmon URL: {$oprofile->salmonuri}\n"; print " Avatar URL: {$oprofile->avatar}\n"; print " Profile ID: {$oprofile->profile_id}\n"; print " Group ID: {$oprofile->group_id}\n"; print " Record created: {$oprofile->created}\n";
function handle($notice) { assert($notice instanceof Notice); $this->notice = $notice; $this->user = User::getKV('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; } if ($notice->isLocal()) { // Notices generated on remote sites will have already // been pushed to user's subscribers by their origin sites. $this->pushUser(); } foreach ($notice->getAttentionProfiles() as $target) { common_debug("OSTATUS [{$this->notice->getID()}]: Attention target profile {$target->getNickname()} ({$target->getID()})"); if ($target->isGroup()) { common_debug("OSTATUS [{$this->notice->getID()}]: {$target->getID()} is a group"); $oprofile = Ostatus_profile::getKV('group_id', $target->getGroup()->getID()); if (!$oprofile instanceof Ostatus_profile) { // we don't save profiles like this yet, but in the future $oprofile = Ostatus_profile::getKV('profile_id', $target->getID()); } if ($oprofile instanceof Ostatus_profile) { // remote group if ($notice->isLocal()) { common_debug("OSTATUS [{$this->notice->getID()}]: notice is local and remote group with profile ID {$target->getID()} gets a ping"); $this->pingReply($oprofile); } } else { common_debug("OSTATUS [{$this->notice->getID()}]: local group with profile id {$target->getID()} gets pushed out"); // local group $this->pushGroup($target->getGroup()); } } elseif ($notice->isLocal()) { // Notices generated on other sites will have already // pinged their reply-targets, so only do these things // if the target is not a group and the notice is locally generated $oprofile = Ostatus_profile::getKV('profile_id', $target->getID()); if ($oprofile instanceof Ostatus_profile) { common_debug("OSTATUS [{$this->notice->getID()}]: Notice is local and {$target->getID()} is remote profile, getting pingReply"); $this->pingReply($oprofile); } } } if ($notice->isLocal()) { try { $parent = $this->notice->getParent(); foreach ($parent->getAttentionProfiles() as $related) { if ($related->isGroup()) { // don't ping groups in parent notices since we might not be a member of them, // though it could be useful if we study this and use it correctly continue; } common_debug("OSTATUS [{$this->notice->getID()}]: parent notice {$parent->getID()} has related profile id=={$related->getID()}"); // FIXME: don't ping twice in case someone is in both notice attention spans! $oprofile = Ostatus_profile::getKV('profile_id', $related->getID()); if ($oprofile instanceof Ostatus_profile) { $this->pingReply($oprofile); } } } catch (NoParentNoticeException $e) { // nothing to do then } foreach ($notice->getProfileTags() as $ptag) { $oprofile = Ostatus_profile::getKV('peopletag_id', $ptag->id); if (!$oprofile) { $this->pushPeopletag($ptag); } } } return true; }
public function delete($useWhere = false) { try { $oprofile = Ostatus_profile::getKV('feeduri', $this->getUri()); if ($oprofile instanceof Ostatus_profile) { // Check if there's a profile. If not, handle the NoProfileException below $profile = $oprofile->localProfile(); } } catch (NoProfileException $e) { // If the Ostatus_profile has no local Profile bound to it, let's clean it out at the same time $oprofile->delete(); } catch (NoUriException $e) { // FeedSub->getUri() can throw a NoUriException, let's just go ahead and delete it } return parent::delete($useWhere); }
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(); }
public function onStartProfileGetAtomFeed($profile, &$feed) { $oprofile = Ostatus_profile::getKV('profile_id', $profile->id); if (!$oprofile instanceof Ostatus_profile) { return true; } $feed = $oprofile->feeduri; return false; }
function handle($notice) { assert($notice instanceof Notice); $this->notice = $notice; $this->user = User::getKV('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; } if ($notice->isLocal()) { // Notices generated on remote sites will have already // been pushed to user's subscribers by their origin sites. $this->pushUser(); } foreach ($notice->getGroups() as $group) { $oprofile = Ostatus_profile::getKV('group_id', $group->id); if ($oprofile) { // remote group if ($notice->isLocal()) { $this->pingReply($oprofile); } } else { // local group $this->pushGroup($group->id); } } if ($notice->isLocal()) { // Notices generated on other sites will have already // pinged their reply-targets. foreach ($notice->getReplies() as $profile_id) { $oprofile = Ostatus_profile::getKV('profile_id', $profile_id); if ($oprofile) { $this->pingReply($oprofile); } } if (!empty($this->notice->reply_to)) { $replyTo = Notice::getKV('id', $this->notice->reply_to); if (!empty($replyTo)) { foreach ($replyTo->getReplies() as $profile_id) { $oprofile = Ostatus_profile::getKV('profile_id', $profile_id); if ($oprofile) { $this->pingReply($oprofile); } } } } foreach ($notice->getProfileTags() as $ptag) { $oprofile = Ostatus_profile::getKV('peopletag_id', $ptag->id); if (!$oprofile) { $this->pushPeopletag($ptag); } } } return true; }
private function getFeed($profile) { // Ok this is a bit of a hack. ;) if (class_exists('Ostatus_profile')) { $oprofile = Ostatus_profile::getKV('profile_id', $profile->id); if ($oprofile) { return $oprofile->feeduri; } } var_dump('wtf'); return false; }
protected 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('The mirror request failed, because no result was retrieved.')); } if ($this->delete) { $mirror->delete(); $oprofile = Ostatus_profile::getKV('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); } } }