gnu-social/actions/finishremotesubscribe.php
Evan Prodromou 56021d9572 move avatar scaling and saving to Avatar and Profile
Extracted the code for setting a new original avatar to the Profile
class, and moved some of it to Avatar, too. This makes it easier to
have the same functionality whether an avatar is set using the profile
settings (for our users), or on a remote subscription. Necessitated
changing the filenaming function to just take an ID.

darcs-hash:20080605193708-84dde-a441cc0474951ce7f1a1da9310b5145c0b7c3070.gz
2008-06-05 15:37:08 -04:00

220 lines
5.9 KiB
PHP

<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
require_once(INSTALLDIR.'/lib/omb.php');
require_once('Auth/Yadis/Yadis.php');
class FinishremotesubscribeAction extends Action {
function handle($args) {
parent::handle($args);
if (common_logged_in()) {
common_user_error(_t('You can use the local subscription!'));
return;
}
$omb = $_SESSION['oauth_authorization_request'];
if (!$omb) {
common_user_error(_t('Not expecting this response!'));
return;
}
$req = OAuthRequest::from_request();
$token = $req->get_parameter('oauth_token');
# I think this is the success metric
if ($token != $omb['token']) {
common_user_error(_t('Not authorized.'));
return;
}
$version = $req->get_parameter('omb_version');
if ($version != OMB_VERSION_01) {
common_user_error(_t('Unknown version of OMB protocol.'));
return;
}
$nickname = $req->get_parameter('omb_listener_nickname');
if (!$nickname) {
common_user_error(_t('No nickname provided by remote server.'));
return;
}
$profile_url = $req->get_parameter('omb_listener_profile');
if (!$profile_url) {
common_user_error(_t('No profile URL returned by server.'));
return;
}
if (!Validate::uri($profile_url, array('allowed_schemes' => array('http', 'https')))) {
common_user_error(_t('Invalid profile URL returned by server.'));
return;
}
$user = User::staticGet('uri', $omb['listenee']);
if (!$user) {
common_user_error(_t('User being listened to doesn\'t exist.'));
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) {
common_user_error(_t('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 ($fullname) {
$profile->fullname = $fullname;
}
if ($homepage) {
$profile->homepage = $homepage;
}
if ($bio) {
$profile->bio = $bio;
}
if ($location) {
$profile->location = $location;
}
if ($exists) {
$profile->update($orig_profile);
} else {
$profile->created = DB_DataObject_Cast::dateTime(); # current time
$id = $profile->insert();
$remote->id = $id;
}
if ($avatar_url) {
$this->add_avatar($profile, $avatar_url);
}
$remote->postnoticeurl = $omb[OMB_ENDPOINT_POSTNOTICE];
$remote->updateprofileurl = $omb[OMB_ENDPOINT_UPDATEPROFILE];
if ($exists) {
$remote->update($orig_remote);
} else {
$remote->created = DB_DataObject_Cast::dateTime(); # current time
$remote->insert;
}
$sub = new Subscription();
$sub->subscriber = $remote->id;
$sub->subscribed = $user->id;
$sub->token = $newtok;
$sub->secret = $newsecret;
$sub->created = DB_DataObject_Cast::dateTime(); # current time
if (!$sub->insert()) {
common_user_error(_t('Couldn\'t insert new subscription.'));
return;
}
# 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('subscribed', array('nickname' =>
$user->nickname)));
}
function add_avatar($profile, $url) {
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
copy($url, $temp_filename);
return $profile->setOriginal($temp_filename);
}
function access_token($omb) {
$con = omb_oauth_consumer();
$tok = new OAuthToken($omb['token'], $omb['secret']);
$url = omb_service_uri($omb[OAUTH_ENDPOINT_ACCESS]);
# XXX: Is this the right thing to do? Strip off GET params and make them
# POST params? Seems wrong to me.
$parsed = parse_url($url);
$params = array();
parse_str($parsed['query'], $params);
$req = OAuthRequest::from_consumer_and_token($con, $tok, "POST", $url, $params);
$req->set_parameter('omb_version', OMB_VERSION_01);
# XXX: test to see if endpoint accepts this signature method
$req->sign_request(omb_hmac_sha1(), $con, NULL);
# We re-use this tool's fetcher, since it's pretty good
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
$result = $fetcher->post($req->get_normalized_http_url(),
$req->to_postdata());
if ($result->status != 200) {
return NULL;
}
parse_str($result->body, $return);
return array($return['oauth_token'], $return['oauth_token_secret']);
}
}