diff options
-rw-r--r-- | actions/atompubshowsubscription.php | 224 | ||||
-rw-r--r-- | classes/Subscription.php | 9 | ||||
-rw-r--r-- | lib/router.php | 21 |
3 files changed, 247 insertions, 7 deletions
diff --git a/actions/atompubshowsubscription.php b/actions/atompubshowsubscription.php new file mode 100644 index 000000000..a30b21096 --- /dev/null +++ b/actions/atompubshowsubscription.php @@ -0,0 +1,224 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2010, StatusNet, Inc. + * + * Single subscription + * + * PHP version 5 + * + * 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/>. + * + * @category AtomPub + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +require_once INSTALLDIR . '/lib/apiauth.php'; + +/** + * Show a single subscription + * + * @category AtomPub + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class AtompubshowsubscriptionAction extends ApiAuthAction +{ + private $_subscriber = null; + private $_subscribed = null; + private $_subscription = null; + + /** + * For initializing members of the class. + * + * @param array $argarray misc. arguments + * + * @return boolean true + */ + + function prepare($argarray) + { + parent::prepare($argarray); + $subscriberId = $this->trimmed('subscriber'); + + $this->_subscriber = Profile::staticGet('id', $subscriberId); + + if (empty($this->_subscriber)) { + throw new ClientException(sprintf(_('No such profile id: %d'), + $subscriberId), 404); + } + + $subscribedId = $this->trimmed('subscribed'); + + $this->_subscribed = Profile::staticGet('id', $subscribedId); + + if (empty($this->_subscribed)) { + throw new ClientException(sprintf(_('No such profile id: %d'), + $subscribedId), 404); + } + + $this->_subscription = + Subscription::pkeyGet(array('subscriber' => $subscriberId, + 'subscribed' => $subscribedId)); + + if (empty($this->_subscription)) { + $msg = sprintf(_('Profile %d not subscribed to profile %d'), + $subscriberId, $subscribedId); + throw new ClientException($msg, 404); + } + + return true; + } + + /** + * Handler method + * + * @param array $argarray is ignored since it's now passed in in prepare() + * + * @return void + */ + + function handle($argarray=null) + { + switch ($_SERVER['REQUEST_METHOD']) { + case 'GET': + $this->showSubscription(); + break; + case 'DELETE': + $this->deleteSubscription(); + break; + default: + $this->clientError(_('HTTP method not supported.'), 405); + return; + } + + return; + } + + /** + * Show the subscription in ActivityStreams Atom format. + * + * @return void + */ + + function showSubscription() + { + $activity = $this->_subscription->asActivity(); + + header('Content-Type: application/atom+xml; charset=utf-8'); + + $this->startXML(); + $this->raw($activity->asString(true, true, true)); + $this->endXML(); + + return; + } + + /** + * Delete the subscription + * + * @return void + */ + + function deleteSubscription() + { + if (empty($this->auth_user) || + $this->auth_user->id != $this->_subscriber->id) { + throw new ClientException(_("Can't delete someone else's". + " subscription"), 403); + } + + Subscription::cancel($this->_subscriber, + $this->_subscribed); + + return; + } + + /** + * Is this action read only? + * + * @param array $args other arguments + * + * @return boolean true + */ + + function isReadOnly($args) + { + if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { + return false; + } else { + return true; + } + } + + /** + * Return last modified, if applicable. + * + * MAY override + * + * @return string last modified http header + */ + + function lastModified() + { + return max(strtotime($this->_subscriber->modified), + strtotime($this->_subscribed->modified), + strtotime($this->_subscription->modified)); + } + + /** + * Etag for this object + * + * @return string etag http header + */ + + function etag() + { + $mtime = strtotime($this->_subscription->modified); + + return 'W/"' . implode(':', array('AtomPubShowSubscription', + $this->_subscriber->id, + $this->_subscribed->id, + $mtime)) . '"'; + } + + /** + * Does this require authentication? + * + * @return boolean true if delete, else false + */ + + function requiresAuth() + { + if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { + return true; + } else { + return false; + } + } +} diff --git a/classes/Subscription.php b/classes/Subscription.php index e9ad2a5a2..d41349412 100644 --- a/classes/Subscription.php +++ b/classes/Subscription.php @@ -245,6 +245,8 @@ class Subscription extends Memcached_DataObject $act->verb = ActivityVerb::FOLLOW; + // XXX: rationalize this with the URL + $act->id = TagURI::mint('follow:%d:%d:%s', $subscriber->id, $subscribed->id, @@ -262,6 +264,13 @@ class Subscription extends Memcached_DataObject $act->actor = ActivityObject::fromProfile($subscriber); $act->objects[] = ActivityObject::fromProfile($subscribed); + $url = common_local_url('AtomPubShowSubscription', + array('subscriber' => $subscriber->id, + 'subscribed' => $subscribed->id)); + + $act->selfLink = $url; + $act->editLink = $url; + return $act; } } diff --git a/lib/router.php b/lib/router.php index ca895c8bb..4e718f132 100644 --- a/lib/router.php +++ b/lib/router.php @@ -761,13 +761,6 @@ class Router $m->connect('api/oauth/authorize', array('action' => 'ApiOauthAuthorize')); - $m->connect('api/statusnet/app/service/:id.xml', - array('action' => 'ApiAtomService', - 'id' => Nickname::DISPLAY_FMT)); - - $m->connect('api/statusnet/app/service.xml', - array('action' => 'ApiAtomService')); - // Admin $m->connect('admin/site', array('action' => 'siteadminpanel')); @@ -909,6 +902,20 @@ class Router array('nickname' => Nickname::DISPLAY_FMT)); } + // AtomPub API + + $m->connect('api/statusnet/app/service/:id.xml', + array('action' => 'ApiAtomService', + 'id' => Nickname::DISPLAY_FMT)); + + $m->connect('api/statusnet/app/service.xml', + array('action' => 'ApiAtomService')); + + $m->connect('api/statusnet/app/subscriptions/:subscriber/:subscribed.atom', + array('action' => 'AtomPubShowSubscription'), + array('subscriber' => '[0-9]+', + 'subscribed' => '[0-9]+')); + // user stuff Event::handle('RouterInitialized', array($m)); |