function save_notice(&$req, &$consumer, &$token) { $version = $req->get_parameter('omb_version'); if ($version != OMB_VERSION_01) { $this->clientError(_('Unsupported OMB version'), 400); return false; } # First, check to see $listenee = $req->get_parameter('omb_listenee'); $remote_profile = Remote_profile::staticGet('uri', $listenee); if (!$remote_profile) { $this->clientError(_('Profile unknown'), 403); return false; } $sub = Subscription::staticGet('token', $token->key); if (!$sub) { $this->clientError(_('No such subscription'), 403); return false; } $content = $req->get_parameter('omb_notice_content'); $content_shortened = common_shorten_links($content); if (mb_strlen($content_shortened) > 140) { $this->clientError(_('Invalid notice content'), 400); return false; } $notice_uri = $req->get_parameter('omb_notice'); if (!Validate::uri($notice_uri) && !common_valid_tag($notice_uri)) { $this->clientError(_('Invalid notice uri'), 400); return false; } $notice_url = $req->get_parameter('omb_notice_url'); if ($notice_url && !common_valid_http_url($notice_url)) { $this->clientError(_('Invalid notice url'), 400); return false; } $notice = Notice::staticGet('uri', $notice_uri); if (!$notice) { $notice = Notice::saveNew($remote_profile->id, $content, 'omb', false, null, $notice_uri); if (is_string($notice)) { common_server_serror($notice, 500); return false; } common_broadcast_notice($notice, true); } return true; }
function updateOStatus($user) { if (!have_option('q', 'quiet')) { echo "{$user->nickname}..."; } $up = $user->getProfile(); $sp = $user->getSubscriptions(); $rps = array(); while ($sp->fetch()) { $remote = Remote_profile::staticGet('id', $sp->id); if (!empty($remote)) { $rps[] = clone $sp; } } if (!have_option('q', 'quiet')) { echo count($rps) . "\n"; } foreach ($rps as $rp) { try { if (!have_option('q', 'quiet')) { echo "Checking {$rp->nickname}..."; } $op = Ostatus_profile::ensureProfileURL($rp->profileurl); if (empty($op)) { echo "can't convert.\n"; continue; } else { if (!have_option('q', 'quiet')) { echo "Converting..."; } Subscription::start($up, $op->localProfile()); Subscription::cancel($up, $rp); if (!have_option('q', 'quiet')) { echo "done.\n"; } } } catch (Exception $e) { if (!have_option('q', 'quiet')) { echo "fail.\n"; } common_log(LOG_NOTICE, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname . ") to OStatus: " . $e->getMessage()); continue; } } }
function ensureProfile($user) { // check to see if there's already a profile for this user $profileurl = 'http://twitter.com/' . $user->screen_name; $profile = $this->getProfileByUrl($user->screen_name, $profileurl); if (!empty($profile)) { common_debug($this->name() . " - Profile for {$profile->nickname} found."); // Check to see if the user's Avatar has changed $this->checkAvatar($user, $profile); return $profile; } else { common_debug($this->name() . ' - Adding profile and remote profile ' . "for Twitter user: {$profileurl}."); $profile = new Profile(); $profile->query("BEGIN"); $profile->nickname = $user->screen_name; $profile->fullname = $user->name; $profile->homepage = $user->url; $profile->bio = $user->description; $profile->location = $user->location; $profile->profileurl = $profileurl; $profile->created = common_sql_now(); try { $id = $profile->insert(); } catch (Exception $e) { common_log(LOG_WARNING, $this->name() . ' Couldn\'t insert profile - ' . $e->getMessage()); } if (empty($id)) { common_log_db_error($profile, 'INSERT', __FILE__); $profile->query("ROLLBACK"); return false; } // check for remote profile $remote_pro = Remote_profile::staticGet('uri', $profileurl); if (empty($remote_pro)) { $remote_pro = new Remote_profile(); $remote_pro->id = $id; $remote_pro->uri = $profileurl; $remote_pro->created = common_sql_now(); try { $rid = $remote_pro->insert(); } catch (Exception $e) { common_log(LOG_WARNING, $this->name() . ' Couldn\'t save remote profile - ' . $e->getMessage()); } if (empty($rid)) { common_log_db_error($profile, 'INSERT', __FILE__); $profile->query("ROLLBACK"); return false; } } $profile->query("COMMIT"); $this->saveAvatars($user, $id); return $profile; } }
/** * Return OMB remote profiles as well as regular profiles * in helper * * @param type $profile * @param type $uri */ function onStartCommonProfileURI($profile, &$uri) { $remote = Remote_profile::staticGet($profile->id); if ($remote) { $uri = $remote->uri; return false; } return true; }
function handle($channel) { if (!$this->other) { // TRANS: Error text shown when no username was provided when issuing a subscribe command. $channel->error($this->user, _('Specify the name of the user to subscribe to.')); return; } $target = $this->getProfile($this->other); $remote = Remote_profile::staticGet('id', $target->id); if ($remote) { // TRANS: Command exception text shown when trying to subscribe to an OMB profile using the subscribe command. throw new CommandException(_("Can't subscribe to OMB profiles by command.")); } try { Subscription::start($this->user->getProfile(), $target); // TRANS: Text shown after having subscribed to another user successfully. // TRANS: %s is the name of the user the subscription was requested for. $channel->output($this->user, sprintf(_('Subscribed to %s.'), $this->other)); } catch (Exception $e) { $channel->error($this->user, $e->getMessage()); } }
/** * Check pre-requisites and instantiate attributes * * @param Array $args array of arguments (URL, GET, POST) * * @return boolean success flag */ function prepare($args) { parent::prepare($args); // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Client error displayed when the session token does not match or is not given. $this->clientError(_('There was a problem with your session token.' . ' Try again, please.')); return false; } // Only for logged-in users $this->user = common_current_user(); if (empty($this->user)) { // TRANS: Error message displayed when trying to perform an action that requires a logged in user. $this->clientError(_('Not logged in.')); return false; } // Profile to subscribe to $tagged_id = $this->arg('tagged'); $this->tagged = Profile::staticGet('id', $tagged_id); if (empty($this->tagged)) { // TRANS: Client error displayed trying to perform an action related to a non-existing profile. $this->clientError(_('No such profile.')); return false; } $id = $this->arg('peopletag_id'); $this->peopletag = Profile_list::staticGet('id', $id); if (empty($this->peopletag)) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.')); return false; } // OMB 0.1 doesn't have a mechanism for local-server- // originated tag. $omb01 = Remote_profile::staticGet('id', $tagged_id); if (!empty($omb01)) { // TRANS: Client error displayed when trying to add an OMB 0.1 remote profile to a list. $this->clientError(_('You cannot list an OMB 0.1 ' . 'remote profile with this action.')); return false; } return true; }
/** * Class handler. * * @param array $args query arguments * * @return nothing * */ function handle($args) { parent::handle($args); /* Restore session data. RemotesubscribeAction should have stored this entry. */ $service = unserialize($_SESSION['oauth_authorization_request']); if (!$service) { // TRANS: Client error displayed when subscribing to a remote profile and an unexpected response is received. $this->clientError(_('Not expecting this response!')); return; } common_debug('stored request: ' . print_r($service, true), __FILE__); /* Create user objects for both users. Do it early for request validation. */ $user = User::staticGet('uri', $service->getListeneeURI()); if (!$user) { // TRANS: Client error displayed when subscribing to a remote profile that does not exist. $this->clientError(_('User being listened to does not exist.')); return; } $other = User::staticGet('uri', $service->getListenerURI()); if ($other) { // TRANS: Client error displayed when subscribing to a remote profile that is a local profile. $this->clientError(_('You can use the local subscription!')); return; } $remote = Remote_profile::staticGet('uri', $service->getListenerURI()); if ($remote) { // Note remote profile may not have been saved yet. // @fixme not convinced this is correct at all! $profile = Profile::staticGet($remote->id); if ($user->hasBlocked($profile)) { // TRANS: Client error displayed when subscribing to a remote profile that is blocked form subscribing to. $this->clientError(_('That user has blocked you from subscribing.')); return; } } /* Perform the handling itself via libomb. */ try { $service->finishAuthorization(); } catch (OAuthException $e) { if ($e->getMessage() == 'The authorized token does not equal the ' . 'submitted token.') { // TRANS: Client error displayed when subscribing to a remote profile without providing an authorised token. $this->clientError(_('You are not authorized.')); return; } else { // TRANS: Client error displayed when subscribing to a remote profile and conversion of the request token to access token fails. $this->clientError(_('Could not convert request token to ' . 'access token.')); return; } } catch (OMB_RemoteServiceException $e) { // TRANS: Client error displayed when subscribing to a remote profile fails because of an unsupported version of the OMB protocol. $this->clientError(_('Remote service uses unknown version of ' . 'OMB protocol.')); return; } catch (Exception $e) { common_debug('Got exception ' . print_r($e, true), __FILE__); $this->clientError($e->getMessage()); return; } /* The service URLs are not accessible from datastore, so setting them after insertion of the profile. */ $remote = Remote_profile::staticGet('uri', $service->getListenerURI()); $orig_remote = clone $remote; $remote->postnoticeurl = $service->getServiceURI(OMB_ENDPOINT_POSTNOTICE); $remote->updateprofileurl = $service->getServiceURI(OMB_ENDPOINT_UPDATEPROFILE); if (!$remote->update($orig_remote)) { // TRANS: Server error displayed when subscribing to a remote profile fails because the remote profile could not be updated. $this->serverError(_('Error updating remote profile.')); return; } /* Clear the session data. */ unset($_SESSION['oauth_authorization_request']); /* If we show subscriptions in reverse chronological order, the new one should show up close to the top of the page. */ common_redirect(common_local_url('subscribers', array('nickname' => $user->nickname)), 303); }
function handle($args) { parent::handle($args); if (common_logged_in()) { $this->clientError(_('You can use the local subscription!')); return; } $omb = $_SESSION['oauth_authorization_request']; if (!$omb) { $this->clientError(_('Not expecting this response!')); return; } common_debug('stored request: ' . print_r($omb, true), __FILE__); common_remove_magic_from_request(); $req = OAuthRequest::from_request(); $token = $req->get_parameter('oauth_token'); # I think this is the success metric if ($token != $omb['token']) { $this->clientError(_('Not authorized.')); return; } $version = $req->get_parameter('omb_version'); if ($version != OMB_VERSION_01) { $this->clientError(_('Unknown version of OMB protocol.')); return; } $nickname = $req->get_parameter('omb_listener_nickname'); if (!$nickname) { $this->clientError(_('No nickname provided by remote server.')); return; } $profile_url = $req->get_parameter('omb_listener_profile'); if (!$profile_url) { $this->clientError(_('No profile URL returned by server.')); return; } if (!Validate::uri($profile_url, array('allowed_schemes' => array('http', 'https')))) { $this->clientError(_('Invalid profile URL returned by server.')); return; } if ($profile_url == common_local_url('showstream', array('nickname' => $nickname))) { $this->clientError(_('You can use the local subscription!')); return; } common_debug('listenee: "' . $omb['listenee'] . '"', __FILE__); $user = User::staticGet('nickname', $omb['listenee']); if (!$user) { $this->clientError(_('User being listened to doesn\'t exist.')); return; } $other = User::staticGet('uri', $omb['listener']); if ($other) { $this->clientError(_('You can use the local subscription!')); return; } $fullname = $req->get_parameter('omb_listener_fullname'); $homepage = $req->get_parameter('omb_listener_homepage'); $bio = $req->get_parameter('omb_listener_bio'); $location = $req->get_parameter('omb_listener_location'); $avatar_url = $req->get_parameter('omb_listener_avatar'); list($newtok, $newsecret) = $this->access_token($omb); if (!$newtok || !$newsecret) { $this->clientError(_('Couldn\'t convert request tokens to access tokens.')); return; } # XXX: possible attack point; subscribe and return someone else's profile URI $remote = Remote_profile::staticGet('uri', $omb['listener']); if ($remote) { $exists = true; $profile = Profile::staticGet($remote->id); $orig_remote = clone $remote; $orig_profile = clone $profile; # XXX: compare current postNotice and updateProfile URLs to the ones # stored in the DB to avoid (possibly...) above attack } else { $exists = false; $remote = new Remote_profile(); $remote->uri = $omb['listener']; $profile = new Profile(); } $profile->nickname = $nickname; $profile->profileurl = $profile_url; if (!is_null($fullname)) { $profile->fullname = $fullname; } if (!is_null($homepage)) { $profile->homepage = $homepage; } if (!is_null($bio)) { $profile->bio = $bio; } if (!is_null($location)) { $profile->location = $location; } if ($exists) { $profile->update($orig_profile); } else { $profile->created = DB_DataObject_Cast::dateTime(); # current time $id = $profile->insert(); if (!$id) { $this->serverError(_('Error inserting new profile')); return; } $remote->id = $id; } if ($avatar_url) { if (!$this->add_avatar($profile, $avatar_url)) { $this->serverError(_('Error inserting avatar')); return; } } $remote->postnoticeurl = $omb['post_notice_url']; $remote->updateprofileurl = $omb['update_profile_url']; if ($exists) { if (!$remote->update($orig_remote)) { $this->serverError(_('Error updating remote profile')); return; } } else { $remote->created = DB_DataObject_Cast::dateTime(); # current time if (!$remote->insert()) { $this->serverError(_('Error inserting remote profile')); return; } } if ($user->hasBlocked($profile)) { $this->clientError(_('That user has blocked you from subscribing.')); return; } $sub = new Subscription(); $sub->subscriber = $remote->id; $sub->subscribed = $user->id; $sub_exists = false; if ($sub->find(true)) { $sub_exists = true; $orig_sub = clone $sub; } else { $sub_exists = false; $sub->created = DB_DataObject_Cast::dateTime(); # current time } $sub->token = $newtok; $sub->secret = $newsecret; if ($sub_exists) { $result = $sub->update($orig_sub); } else { $result = $sub->insert(); } if (!$result) { common_log_db_error($sub, $sub_exists ? 'UPDATE' : 'INSERT', __FILE__); $this->clientError(_('Couldn\'t insert new subscription.')); return; } # Notify user, if necessary mail_subscribe_notify_profile($user, $profile); # Clear the data unset($_SESSION['oauth_authorization_request']); # If we show subscriptions in reverse chron order, this should # show up close to the top of the page common_redirect(common_local_url('subscribers', array('nickname' => $user->nickname))); }
function validateOmb(&$req) { foreach (array('omb_version', 'omb_listener', 'omb_listenee', 'omb_listenee_profile', 'omb_listenee_nickname', 'omb_listenee_license') as $param) { if (is_null($req->get_parameter($param))) { throw new OAuthException("Required parameter '{$param}' not found"); } } # Now, OMB stuff $version = $req->get_parameter('omb_version'); if ($version != OMB_VERSION_01) { throw new OAuthException("OpenMicroBlogging version '{$version}' not supported"); } $listener = $req->get_parameter('omb_listener'); $user = User::staticGet('uri', $listener); if (!$user) { throw new OAuthException("Listener URI '{$listener}' not found here"); } $cur = common_current_user(); if ($cur->id != $user->id) { throw new OAuthException("Can't add for another user!"); } $listenee = $req->get_parameter('omb_listenee'); if (!Validate::uri($listenee) && !common_valid_tag($listenee)) { throw new OAuthException("Listenee URI '{$listenee}' not a recognizable URI"); } if (strlen($listenee) > 255) { throw new OAuthException("Listenee URI '{$listenee}' too long"); } $other = User::staticGet('uri', $listenee); if ($other) { throw new OAuthException("Listenee URI '{$listenee}' is local user"); } $remote = Remote_profile::staticGet('uri', $listenee); if ($remote) { $sub = new Subscription(); $sub->subscriber = $user->id; $sub->subscribed = $remote->id; if ($sub->find(true)) { throw new OAuthException("Already subscribed to user!"); } } $nickname = $req->get_parameter('omb_listenee_nickname'); if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { throw new OAuthException('Nickname must have only letters and numbers and no spaces.'); } $profile = $req->get_parameter('omb_listenee_profile'); if (!common_valid_http_url($profile)) { throw new OAuthException("Invalid profile URL '{$profile}'."); } if ($profile == common_local_url('showstream', array('nickname' => $nickname))) { throw new OAuthException("Profile URL '{$profile}' is for a local user."); } $license = $req->get_parameter('omb_listenee_license'); if (!common_valid_http_url($license)) { throw new OAuthException("Invalid license URL '{$license}'."); } $site_license = common_config('license', 'url'); if (!common_compatible_license($license, $site_license)) { throw new OAuthException("Listenee stream license '{$license}' not compatible with site license '{$site_license}'."); } # optional stuff $fullname = $req->get_parameter('omb_listenee_fullname'); if ($fullname && mb_strlen($fullname) > 255) { throw new OAuthException("Full name '{$fullname}' too long."); } $homepage = $req->get_parameter('omb_listenee_homepage'); if ($homepage && (!common_valid_http_url($homepage) || mb_strlen($homepage) > 255)) { throw new OAuthException("Invalid homepage '{$homepage}'"); } $bio = $req->get_parameter('omb_listenee_bio'); if ($bio && mb_strlen($bio) > 140) { throw new OAuthException("Bio too long '{$bio}'"); } $location = $req->get_parameter('omb_listenee_location'); if ($location && mb_strlen($location) > 255) { throw new OAuthException("Location too long '{$location}'"); } $avatar = $req->get_parameter('omb_listenee_avatar'); if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { throw new OAuthException("Invalid avatar URL '{$avatar}'"); } $size = @getimagesize($avatar); if (!$size) { throw new OAuthException("Can't read avatar URL '{$avatar}'"); } if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) { throw new OAuthException("Wrong size image at '{$avatar}'"); } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { throw new OAuthException("Wrong image type for '{$avatar}'"); } } $callback = $req->get_parameter('oauth_callback'); if ($callback && !common_valid_http_url($callback)) { throw new OAuthException("Invalid callback URL '{$callback}'"); } if ($callback && $callback == common_local_url('finishremotesubscribe')) { throw new OAuthException("Callback URL '{$callback}' is for local site."); } }
function showSubscribeButton() { // Is this a logged-in user, looking at someone else's // profile? $user = common_current_user(); if (!empty($user) && $this->profile->id != $user->id) { $this->out->elementStart('li', 'entity_subscribe'); if ($user->isSubscribed($this->profile)) { $usf = new UnsubscribeForm($this->out, $this->profile); $usf->show(); } else { // We can't initiate sub for a remote OMB profile. $remote = Remote_profile::staticGet('id', $this->profile->id); if (empty($remote)) { $sf = new SubscribeForm($this->out, $this->profile); $sf->show(); } } $this->out->elementEnd('li'); } }
function common_profile_uri($profile) { if (!$profile) { return null; } $user = User::staticGet($profile->id); if ($user) { return $user->uri; } $remote = Remote_profile::staticGet($profile->id); if ($remote) { return $remote->uri; } // XXX: this is a very bad profile! return null; }
/** * Returns the best URI for a profile. Plugins may override. * * @return string $uri */ function getUri() { $uri = null; // give plugins a chance to set the URI if (Event::handle('StartGetProfileUri', array($this, &$uri))) { // check for a local user first $user = User::staticGet('id', $this->id); if (!empty($user)) { $uri = $user->uri; } else { // return OMB profile if any $remote = Remote_profile::staticGet('id', $this->id); if (!empty($remote)) { $uri = $remote->uri; } } Event::handle('EndGetProfileUri', array($this, &$uri)); } return $uri; }
/** * Check pre-requisites and instantiate attributes * * @param Array $args array of arguments (URL, GET, POST) * * @return boolean success flag */ function prepare($args) { parent::prepare($args); // Only allow POST requests if ($_SERVER['REQUEST_METHOD'] != 'POST') { // TRANS: Client error displayed trying to perform any request method other than POST. // TRANS: Do not translate POST. $this->clientError(_('This action only accepts POST requests.')); return false; } // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Client error displayed when the session token is not okay. $this->clientError(_('There was a problem with your session token.' . ' Try again, please.')); return false; } // Only for logged-in users $this->user = common_current_user(); if (empty($this->user)) { // TRANS: Error message displayed when trying to perform an action that requires a logged in user. $this->clientError(_('Not logged in.')); return false; } // Profile to subscribe to $other_id = $this->arg('subscribeto'); $this->other = Profile::staticGet('id', $other_id); if (empty($this->other)) { // TRANS: Client error displayed trying to subscribe to a non-existing profile. $this->clientError(_('No such profile.')); return false; } // OMB 0.1 doesn't have a mechanism for local-server- // originated subscription. $omb01 = Remote_profile::staticGet('id', $other_id); if (!empty($omb01)) { // TRANS: Client error displayed trying to subscribe to an OMB 0.1 remote profile. $this->clientError(_('You cannot subscribe to an OMB 0.1' . ' remote profile with this action.')); return false; } return true; }
function omb_broadcast_profile($profile) { # First, get remote users subscribed to this profile # XXX: use a join here rather than looping through results $sub = new Subscription(); $sub->subscribed = $profile->id; if ($sub->find()) { $updated = array(); while ($sub->fetch()) { $rp = Remote_profile::staticGet('id', $sub->subscriber); if ($rp) { if (!array_key_exists($rp->updateprofileurl, $updated)) { if (omb_update_profile($profile, $rp, $sub)) { $updated[$rp->updateprofileurl] = true; } } } } } }
function update_profile($req, $consumer, $token) { $version = $req->get_parameter('omb_version'); if ($version != OMB_VERSION_01) { $this->clientError(_('Unsupported OMB version'), 400); return false; } # First, check to see if listenee exists $listenee = $req->get_parameter('omb_listenee'); $remote = Remote_profile::staticGet('uri', $listenee); if (!$remote) { $this->clientError(_('Profile unknown'), 404); return false; } # Second, check to see if they should be able to post updates! # We see if there are any subscriptions to that remote user with # the given token. $sub = new Subscription(); $sub->subscribed = $remote->id; $sub->token = $token->key; if (!$sub->find(true)) { $this->clientError(_('You did not send us that profile'), 403); return false; } $profile = Profile::staticGet('id', $remote->id); if (!$profile) { # This one is our fault $this->serverError(_('Remote profile with no matching profile'), 500); return false; } $nickname = $req->get_parameter('omb_listenee_nickname'); if ($nickname && !Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { $this->clientError(_('Nickname must have only lowercase letters and numbers and no spaces.')); return false; } $license = $req->get_parameter('omb_listenee_license'); if ($license && !common_valid_http_url($license)) { $this->clientError(sprintf(_("Invalid license URL '%s'"), $license)); return false; } $profile_url = $req->get_parameter('omb_listenee_profile'); if ($profile_url && !common_valid_http_url($profile_url)) { $this->clientError(sprintf(_("Invalid profile URL '%s'."), $profile_url)); return false; } # optional stuff $fullname = $req->get_parameter('omb_listenee_fullname'); if ($fullname && mb_strlen($fullname) > 255) { $this->clientError(_("Full name is too long (max 255 chars).")); return false; } $homepage = $req->get_parameter('omb_listenee_homepage'); if ($homepage && (!common_valid_http_url($homepage) || mb_strlen($homepage) > 255)) { $this->clientError(sprintf(_("Invalid homepage '%s'"), $homepage)); return false; } $bio = $req->get_parameter('omb_listenee_bio'); if ($bio && mb_strlen($bio) > 140) { $this->clientError(_("Bio is too long (max 140 chars).")); return false; } $location = $req->get_parameter('omb_listenee_location'); if ($location && mb_strlen($location) > 255) { $this->clientError(_("Location is too long (max 255 chars).")); return false; } $avatar = $req->get_parameter('omb_listenee_avatar'); if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { $this->clientError(sprintf(_("Invalid avatar URL '%s'"), $avatar)); return false; } $size = @getimagesize($avatar); if (!$size) { $this->clientError(sprintf(_("Can't read avatar URL '%s'"), $avatar)); return false; } if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) { $this->clientError(sprintf(_("Wrong size image at '%s'"), $avatar)); return false; } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { $this->clientError(sprintf(_("Wrong image type for '%s'"), $avatar)); return false; } } $orig_profile = clone $profile; /* Use values even if they are an empty string. Parsing an empty string in updateProfile is the specified way of clearing a parameter in OMB. */ if (!is_null($nickname)) { $profile->nickname = $nickname; } if (!is_null($profile_url)) { $profile->profileurl = $profile_url; } if (!is_null($fullname)) { $profile->fullname = $fullname; } if (!is_null($homepage)) { $profile->homepage = $homepage; } if (!is_null($bio)) { $profile->bio = $bio; } if (!is_null($location)) { $profile->location = $location; } if (!$profile->update($orig_profile)) { $this->serverError(_('Could not save new profile info'), 500); return false; } else { if ($avatar) { $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar'); copy($avatar, $temp_filename); $imagefile = new ImageFile($profile->id, $temp_filename); $filename = Avatar::filename($profile->id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); if (!$profile->setOriginal($filename)) { $this->serverError(_('Could not save avatar info'), 500); return false; } } return true; } }
function handle($args) { parent::handle($args); header('Content-Type: application/rdf+xml'); $this->startXML(); $this->elementStart('rdf:RDF', array('xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'xmlns:rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', 'xmlns:geo' => 'http://www.w3.org/2003/01/geo/wgs84_pos#', 'xmlns' => 'http://xmlns.com/foaf/0.1/')); // This is the document about the user $this->showPpd('', $this->user->uri); // XXX: might not be a person $this->elementStart('Person', array('rdf:about' => $this->user->uri)); $this->element('mbox_sha1sum', null, sha1('mailto:' . $this->user->email)); if ($this->profile->fullname) { $this->element('name', null, $this->profile->fullname); } if ($this->profile->homepage) { $this->element('homepage', array('rdf:resource' => $this->profile->homepage)); } if ($this->profile->bio) { $this->element('rdfs:comment', null, $this->profile->bio); } // XXX: more structured location data if ($this->profile->location) { $this->elementStart('based_near'); $this->elementStart('geo:SpatialThing'); $this->element('name', null, $this->profile->location); $this->elementEnd('geo:SpatialThing'); $this->elementEnd('based_near'); } $this->showMicrobloggingAccount($this->profile, common_root_url()); $avatar = $this->profile->getOriginalAvatar(); if ($avatar) { $this->elementStart('img'); $this->elementStart('Image', array('rdf:about' => $avatar->url)); foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { $scaled = $this->profile->getAvatar($size); if (!$scaled->original) { // sometimes the original has one of our scaled sizes $this->elementStart('thumbnail'); $this->element('Image', array('rdf:about' => $scaled->url)); $this->elementEnd('thumbnail'); } } $this->elementEnd('Image'); $this->elementEnd('img'); } // Get people user is subscribed to $person = array(); $sub = new Subscription(); $sub->subscriber = $this->profile->id; $sub->whereAdd('subscriber != subscribed'); if ($sub->find()) { while ($sub->fetch()) { if ($sub->token) { $other = Remote_profile::staticGet('id', $sub->subscribed); } else { $other = User::staticGet('id', $sub->subscribed); } if (!$other) { common_debug('Got a bad subscription: ' . print_r($sub, true)); continue; } $this->element('knows', array('rdf:resource' => $other->uri)); $person[$other->uri] = array(LISTENEE, $other); } } // Get people who subscribe to user $sub = new Subscription(); $sub->subscribed = $this->profile->id; $sub->whereAdd('subscriber != subscribed'); if ($sub->find()) { while ($sub->fetch()) { if ($sub->token) { $other = Remote_profile::staticGet('id', $sub->subscriber); } else { $other = User::staticGet('id', $sub->subscriber); } if (!$other) { common_debug('Got a bad subscription: ' . print_r($sub, true)); continue; } if (array_key_exists($other->uri, $person)) { $person[$other->uri][0] = BOTH; } else { $person[$other->uri] = array(LISTENER, $other); } } } $this->elementEnd('Person'); foreach ($person as $uri => $p) { $foaf_url = null; if ($p[1] instanceof User) { $foaf_url = common_local_url('foaf', array('nickname' => $p[1]->nickname)); } $this->profile = Profile::staticGet($p[1]->id); $this->elementStart('Person', array('rdf:about' => $uri)); if ($p[0] == LISTENER || $p[0] == BOTH) { $this->element('knows', array('rdf:resource' => $this->user->uri)); } $this->showMicrobloggingAccount($this->profile, $p[1] instanceof User ? common_root_url() : null); if ($foaf_url) { $this->element('rdfs:seeAlso', array('rdf:resource' => $foaf_url)); } $this->elementEnd('Person'); if ($foaf_url) { $this->showPpd($foaf_url, $uri); } } $this->elementEnd('rdf:RDF'); $this->endXML(); }
/** * Check pre-requisites and instantiate attributes * * @param Array $args array of arguments (URL, GET, POST) * * @return boolean success flag */ function prepare($args) { parent::prepare($args); // Only allow POST requests if ($_SERVER['REQUEST_METHOD'] != 'POST') { $this->clientError(_('This action only accepts POST requests.')); return false; } // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->clientError(_('There was a problem with your session token.' . ' Try again, please.')); return false; } // Only for logged-in users $this->user = common_current_user(); if (empty($this->user)) { $this->clientError(_('Not logged in.')); return false; } // Profile to subscribe to $other_id = $this->arg('subscribeto'); $this->other = Profile::staticGet('id', $other_id); if (empty($this->other)) { $this->clientError(_('No such profile.')); return false; } // OMB 0.1 doesn't have a mechanism for local-server- // originated subscription. $omb01 = Remote_profile::staticGet('id', $other_id); if (!empty($omb01)) { $this->clientError(_('You cannot subscribe to an OMB 0.1' . ' remote profile with this action.')); return false; } return true; }
private function _getAnyProfile($uri) { $user = Remote_profile::staticGet('uri', $uri); if (!$user) { $user = User::staticGet('uri', $uri); } if (!$user) { throw new Exception('No such user.'); } return $user; }
function handle($channel) { if (!$this->other) { $channel->error($this->user, _('Specify the name of the user to subscribe to')); return; } $target = $this->getProfile($this->other); $remote = Remote_profile::staticGet('id', $target->id); if ($remote) { throw new CommandException(_("Can't subscribe to OMB profiles by command.")); } try { Subscription::start($this->user->getProfile(), $target); $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other)); } catch (Exception $e) { $channel->error($this->user, $e->getMessage()); } }
function ensureProfile($user) { // check to see if there's already a profile for this user $profileurl = 'http://twitter.com/' . $user->screen_name; $profile = Profile::staticGet('profileurl', $profileurl); if ($profile) { if (defined('SCRIPT_DEBUG')) { common_debug("Profile for {$profile->nickname} found."); } // Check to see if the user's Avatar has changed $this->checkAvatar($user, $profile); return $profile->id; } else { if (defined('SCRIPT_DEBUG')) { common_debug('Adding profile and remote profile ' . "for Twitter user: {$profileurl}"); } $profile = new Profile(); $profile->query("BEGIN"); $profile->nickname = $user->screen_name; $profile->fullname = $user->name; $profile->homepage = $user->url; $profile->bio = $user->description; $profile->location = $user->location; $profile->profileurl = $profileurl; $profile->created = common_sql_now(); $id = $profile->insert(); if (empty($id)) { common_log_db_error($profile, 'INSERT', __FILE__); $profile->query("ROLLBACK"); return false; } // check for remote profile $remote_pro = Remote_profile::staticGet('uri', $profileurl); if (!$remote_pro) { $remote_pro = new Remote_profile(); $remote_pro->id = $id; $remote_pro->uri = $profileurl; $remote_pro->created = common_sql_now(); $rid = $remote_pro->insert(); if (empty($rid)) { common_log_db_error($profile, 'INSERT', __FILE__); $profile->query("ROLLBACK"); return false; } } $profile->query("COMMIT"); $this->saveAvatars($user, $id); return $id; } }
function validateOmb() { $listener = $_GET['omb_listener']; $listenee = $_GET['omb_listenee']; $nickname = $_GET['omb_listenee_nickname']; $profile = $_GET['omb_listenee_profile']; $user = User::staticGet('uri', $listener); if (!$user) { throw new Exception(sprintf(_('Listener URI ‘%s’ not found here.'), $listener)); } if (strlen($listenee) > 255) { throw new Exception(sprintf(_('Listenee URI ‘%s’ is too long.'), $listenee)); } $other = User::staticGet('uri', $listenee); if ($other) { throw new Exception(sprintf(_('Listenee URI ‘%s’ is a local user.'), $listenee)); } $remote = Remote_profile::staticGet('uri', $listenee); if ($remote) { $sub = new Subscription(); $sub->subscriber = $user->id; $sub->subscribed = $remote->id; if ($sub->find(true)) { throw new Exception('You are already subscribed to this user.'); } } if ($profile == common_profile_url($nickname)) { throw new Exception(sprintf(_('Profile URL ‘%s’ is for a local user.'), $profile)); } $license = $_GET['omb_listenee_license']; $site_license = common_config('license', 'url'); if (!common_compatible_license($license, $site_license)) { throw new Exception(sprintf(_('Listenee stream license ‘%1$s’ is not ' . 'compatible with site license ‘%2$s’.'), $license, $site_license)); } $avatar = $_GET['omb_listenee_avatar']; if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { throw new Exception(sprintf(_('Avatar URL ‘%s’ is not valid.'), $avatar)); } $size = @getimagesize($avatar); if (!$size) { throw new Exception(sprintf(_('Can’t read avatar URL ‘%s’.'), $avatar)); } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { throw new Exception(sprintf(_('Wrong image type for avatar URL ' . '‘%s’.'), $avatar)); } } }
function validateOmb() { $listener = $_GET['omb_listener']; $listenee = $_GET['omb_listenee']; $nickname = $_GET['omb_listenee_nickname']; $profile = $_GET['omb_listenee_profile']; $user = User::staticGet('uri', $listener); if (!$user) { // TRANS: Exception thrown when no valid user is found for an authorisation request. // TRANS: %s is a listener URI. throw new Exception(sprintf(_('Listener URI "%s" not found here.'), $listener)); } if (strlen($listenee) > 255) { // TRANS: Exception thrown when listenee URI is too long for an authorisation request. // TRANS: %s is a listenee URI. throw new Exception(sprintf(_('Listenee URI "%s" is too long.'), $listenee)); } $other = User::staticGet('uri', $listenee); if ($other) { // TRANS: Exception thrown when listenee URI is a local user for an authorisation request. // TRANS: %s is a listenee URI. throw new Exception(sprintf(_('Listenee URI "%s" is a local user.'), $listenee)); } $remote = Remote_profile::staticGet('uri', $listenee); if ($remote) { $sub = new Subscription(); $sub->subscriber = $user->id; $sub->subscribed = $remote->id; if ($sub->find(true)) { // TRANS: Exception thrown when already subscribed. throw new Exception('You are already subscribed to this user.'); } } if ($profile == common_profile_url($nickname)) { // TRANS: Exception thrown when profile URL is a local user for an authorisation request. // TRANS: %s is a profile URL. throw new Exception(sprintf(_('Profile URL "%s" is for a local user.'), $profile)); } $license = $_GET['omb_listenee_license']; $site_license = common_config('license', 'url'); if (!common_compatible_license($license, $site_license)) { // TRANS: Exception thrown when licenses are not compatible for an authorisation request. // TRANS: %1$s is the license for the listenee, %2$s is the license for "this" StatusNet site. throw new Exception(sprintf(_('Listenee stream license "%1$s" is not ' . 'compatible with site license "%2$s".'), $license, $site_license)); } $avatar = $_GET['omb_listenee_avatar']; if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { // TRANS: Exception thrown when avatar URL is invalid for an authorisation request. // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Avatar URL "%s" is not valid.'), $avatar)); } $size = @getimagesize($avatar); if (!$size) { // TRANS: Exception thrown when avatar URL could not be read for an authorisation request. // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Cannot read avatar URL "%s".'), $avatar)); } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { // TRANS: Exception thrown when avatar URL return an invalid image type for an authorisation request. // TRANS: %s is an avatar URL. throw new Exception(sprintf(_('Wrong image type for avatar URL ' . '"%s".'), $avatar)); } } }
function omb_broadcast_profile($profile) { $user = User::staticGet('id', $profile->id); if (!$user) { return false; } $profile = $user->getProfile(); $omb_profile = profile_to_omb_profile($user->uri, $profile, true); /* Get remote users subscribed to this profile. */ $rp = new Remote_profile(); $rp->query('SELECT remote_profile.*, secret, token ' . 'FROM subscription JOIN remote_profile ' . 'ON subscription.subscriber = remote_profile.id ' . 'WHERE subscription.subscribed = ' . $profile->id . ' '); $posted = array(); while ($rp->fetch()) { if (isset($posted[$rp->updateprofileurl])) { /* We already posted to this url. */ continue; } common_debug('Posting to ' . $rp->updateprofileurl, __FILE__); /* Update profile. */ $service = new StatusNet_OMB_Service_Consumer(array(OMB_ENDPOINT_UPDATEPROFILE => $rp->updateprofileurl), $rp->uri); try { $service->setToken($rp->token, $rp->secret); $service->updateProfile($omb_profile); } catch (Exception $e) { common_log(LOG_ERR, 'Failed posting to ' . $rp->updateprofileurl); common_log(LOG_ERR, 'Error status ' . $e); continue; } $posted[$rp->updateprofileurl] = true; common_debug('Finished to ' . $rp->updateprofileurl, __FILE__); } return; }
static function fromURI($uri) { $profile = null; if (Event::handle('StartGetProfileFromURI', array($uri, &$profile))) { // Get a local user or remote (OMB 0.1) profile $user = User::staticGet('uri', $uri); if (!empty($user)) { $profile = $user->getProfile(); } else { $remote_profile = Remote_profile::staticGet('uri', $uri); if (!empty($remote_profile)) { $profile = Profile::staticGet('id', $remote_profile->profile_id); } } Event::handle('EndGetProfileFromURI', array($uri, $profile)); } return $profile; }