Exemplo n.º 1
0
 /**
  * Sign and post the given Atom entry as a Salmon message.
  *
  * Side effects: may generate a keypair on-demand for the given user,
  * which can be very slow on some systems (like those without php5-gmp).
  *
  * @param string $endpoint_uri
  * @param string $xml string representation of payload
  * @param Profile $user profile whose keys we sign with (must be a local user)
  * @return boolean success
  */
 public static function post($endpoint_uri, $xml, Profile $actor, Profile $target = null)
 {
     if (empty($endpoint_uri)) {
         common_debug('No endpoint URI for Salmon post to ' . $actor->getUri());
         return false;
     }
     try {
         $magic_env = MagicEnvelope::signAsUser($xml, $actor->getUser());
     } catch (Exception $e) {
         common_log(LOG_ERR, "Salmon unable to sign: " . $e->getMessage());
         return false;
     }
     // $target is so far only used in Diaspora, so it can be null
     if (Event::handle('SalmonSlap', array($endpoint_uri, $magic_env, $target))) {
         return false;
         //throw new ServerException('Could not distribute salmon slap as no plugin completed the event.');
     }
     return true;
 }
Exemplo n.º 2
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;
 }
Exemplo n.º 3
0
 function onEndUnsubscribe(Profile $profile, Profile $other)
 {
     // Only do this if config is enabled
     if (!$this->StopFollowUser) {
         return true;
     }
     if (!$profile->isLocal()) {
         return true;
     }
     // TRANS: Text for "stopped following" item in activity plugin.
     // TRANS: %1$s is a profile URL, %2$s is a profile name,
     // TRANS: %3$s is a profile URL, %4$s is a profile name.
     $rendered = sprintf(_m('<a href="%1$s">%2$s</a> stopped following <a href="%3$s">%4$s</a>.'), $profile->getUrl(), $profile->getBestName(), $other->getUrl(), $other->getBestName());
     // TRANS: Text for "stopped following" item in activity plugin.
     // TRANS: %1$s is a profile name, %2$s is a profile URL,
     // TRANS: %3$s is a profile name, %4$s is a profile URL.
     $content = sprintf(_m('%1$s (%2$s) stopped following %3$s (%4$s).'), $profile->getBestName(), $profile->getUrl(), $other->getBestName(), $other->getUrl());
     $uri = TagURI::mint('stop-following:%d:%d:%s', $profile->id, $other->id, common_date_iso8601(common_sql_now()));
     $notice = Notice::saveNew($profile->id, $content, ActivityPlugin::SOURCE, array('rendered' => $rendered, 'urls' => array(), 'replies' => array($other->getUri()), 'uri' => $uri, 'verb' => ActivityVerb::UNFOLLOW, 'object_type' => ActivityObject::PERSON));
     return true;
 }
Exemplo n.º 4
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;
 }
 static function fromProfile(Profile $profile)
 {
     $object = new ActivityObject();
     if (Event::handle('StartActivityObjectFromProfile', array($profile, &$object))) {
         $object->type = ActivityObject::PERSON;
         $object->id = $profile->getUri();
         $object->title = $profile->getBestName();
         $object->link = $profile->profileurl;
         $orig = $profile->getOriginalAvatar();
         if (!empty($orig)) {
             $object->avatarLinks[] = AvatarLink::fromAvatar($orig);
         }
         $sizes = array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE);
         foreach ($sizes as $size) {
             $alink = null;
             $avatar = $profile->getAvatar($size);
             if (!empty($avatar)) {
                 $alink = AvatarLink::fromAvatar($avatar);
             } else {
                 $alink = new AvatarLink();
                 $alink->type = 'image/png';
                 $alink->height = $size;
                 $alink->width = $size;
                 $alink->url = Avatar::defaultImage($size);
                 if ($size == AVATAR_PROFILE_SIZE) {
                     // Hack for Twitter import: we don't have a 96x96 image,
                     // but we do have a 73x73 image. For now, fake it with that.
                     $avatar = $profile->getAvatar(73);
                     if ($avatar) {
                         $alink = AvatarLink::fromAvatar($avatar);
                         $alink->height = $size;
                         $alink->width = $size;
                     }
                 }
             }
             $object->avatarLinks[] = $alink;
         }
         if (isset($profile->lat) && isset($profile->lon)) {
             $object->geopoint = (double) $profile->lat . ' ' . (double) $profile->lon;
         }
         $object->poco = PoCo::fromProfile($profile);
         Event::handle('EndActivityObjectFromProfile', array($profile, &$object));
     }
     return $object;
 }
 static function fromProfile(Profile $profile)
 {
     $object = new ActivityObject();
     $object->type = ActivityObject::PERSON;
     $object->id = $profile->getUri();
     $object->title = $profile->getBestName();
     $object->link = $profile->profileurl;
     $orig = $profile->getOriginalAvatar();
     if (!empty($orig)) {
         $object->avatarLinks[] = AvatarLink::fromAvatar($orig);
     }
     $sizes = array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE);
     foreach ($sizes as $size) {
         $alink = null;
         $avatar = $profile->getAvatar($size);
         if (!empty($avatar)) {
             $alink = AvatarLink::fromAvatar($avatar);
         } else {
             $alink = new AvatarLink();
             $alink->type = 'image/png';
             $alink->height = $size;
             $alink->width = $size;
             $alink->url = Avatar::defaultImage($size);
         }
         $object->avatarLinks[] = $alink;
     }
     if (isset($profile->lat) && isset($profile->lon)) {
         $object->geopoint = (double) $profile->lat . ' ' . (double) $profile->lon;
     }
     $object->poco = PoCo::fromProfile($profile);
     return $object;
 }
Exemplo n.º 7
0
 static function checkAuthorship(Activity $activity, Profile $profile)
 {
     if (Event::handle('CheckActivityAuthorship', array($activity, &$profile))) {
         // if (empty($activity->actor)), then we generated this Activity ourselves and can trust $profile
         $actor_uri = $profile->getUri();
         if (!in_array($actor_uri, array($activity->actor->id, $activity->actor->link))) {
             // A mismatch between our locally stored URI and the supplied author?
             // Probably not more than a blog feed or something (with multiple authors or so)
             // but log it for future inspection.
             common_log(LOG_WARNING, "Got an actor '{$activity->actor->title}' ({$activity->actor->id}) on single-user feed for " . $actor_uri);
         } elseif (empty($activity->actor->id)) {
             // Plain <author> without ActivityStreams actor info.
             // We'll just ignore this info for now and save the update under the feed's identity.
         }
     }
     if (!$profile instanceof Profile) {
         throw new ServerException('Could not get an author Profile for activity');
     }
     return $profile;
 }