From c7df5594d07867b54a1e698dee35602ad0dabbd2 Mon Sep 17 00:00:00 2001 From: Mikael Nordfeldth Date: Mon, 12 Jan 2015 03:15:41 +0100 Subject: [PATCH] Simplified by adding an abstract AtompubAction --- actions/atompubmembershipfeed.php | 97 ++++--------------------- actions/atompubshowmembership.php | 100 +++++--------------------- actions/atompubshowsubscription.php | 74 +++++--------------- actions/atompubsubscriptionfeed.php | 105 ++++------------------------ lib/apiaction.php | 6 ++ lib/atompubaction.php | 95 +++++++++++++++++++++++++ 6 files changed, 161 insertions(+), 316 deletions(-) create mode 100644 lib/atompubaction.php diff --git a/actions/atompubmembershipfeed.php b/actions/atompubmembershipfeed.php index 2ebd45bc80..1a77e60ff5 100644 --- a/actions/atompubmembershipfeed.php +++ b/actions/atompubmembershipfeed.php @@ -28,11 +28,7 @@ * @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); -} +if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); } /** * Feed of group memberships for a user, in ActivityStreams format @@ -44,67 +40,34 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ -class AtompubmembershipfeedAction extends ApiAuthAction +class AtompubmembershipfeedAction extends AtompubAction { private $_profile = null; private $_memberships = null; - /** - * For initializing members of the class. - * - * @param array $argarray misc. arguments - * - * @return boolean true - */ - function prepare($argarray) + protected function atompubPrepare() { - parent::prepare($argarray); + $this->_profile = Profile::getKV('id', $this->trimmed('profile')); - $profileId = $this->trimmed('profile'); - - $this->_profile = Profile::getKV('id', $profileId); - - if (empty($this->_profile)) { + if (!$this->_profile instanceof Profile) { // TRANS: Client exception. throw new ClientException(_('No such profile.'), 404); } - $offset = ($this->page-1) * $this->count; - $limit = $this->count + 1; - $this->_memberships = Group_member::byMember($this->_profile->id, - $offset, - $limit); - + $this->offset, + $this->limit); return true; } - /** - * Handler method - * - * @param array $argarray is ignored since it's now passed in in prepare() - * - * @return void - */ - function handle($argarray=null) + protected function handleGet() { - parent::handle($argarray); + return $this->showFeed(); + } - switch ($_SERVER['REQUEST_METHOD']) { - case 'HEAD': - case 'GET': - $this->showFeed(); - break; - case 'POST': - $this->addMembership(); - break; - default: - // TRANS: Client exception thrown when using an unsupported HTTP method. - throw new ClientException(_('HTTP method not supported.'), 405); - return; - } - - return; + protected function handlePost() + { + return $this->addMembership(); } /** @@ -287,25 +250,6 @@ class AtompubmembershipfeedAction extends ApiAuthAction } } - /** - * Return true if read only. - * - * MAY override - * - * @param array $args other arguments - * - * @return boolean is read only action? - */ - function isReadOnly($args) - { - if ($_SERVER['REQUEST_METHOD'] == 'GET' || - $_SERVER['REQUEST_METHOD'] == 'HEAD') { - return true; - } else { - return false; - } - } - /** * Return last modified, if applicable. * @@ -331,19 +275,4 @@ class AtompubmembershipfeedAction extends ApiAuthAction { return null; } - - /** - * Does this require authentication? - * - * @return boolean true if delete, else false - */ - function requiresAuth() - { - if ($_SERVER['REQUEST_METHOD'] == 'GET' || - $_SERVER['REQUEST_METHOD'] == 'HEAD') { - return false; - } else { - return true; - } - } } diff --git a/actions/atompubshowmembership.php b/actions/atompubshowmembership.php index ad6aa6c1d0..1e9d66c56b 100644 --- a/actions/atompubshowmembership.php +++ b/actions/atompubshowmembership.php @@ -28,11 +28,7 @@ * @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); -} +if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); } /** * Show (or delete) a single membership event as an ActivityStreams entry @@ -44,47 +40,34 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ -class AtompubshowmembershipAction extends ApiAuthAction +class AtompubshowmembershipAction extends AtompubAction { - private $_profile = null; + private $_private = null; private $_group = null; private $_membership = null; - /** - * For initializing members of the class. - * - * @param array $argarray misc. arguments - * - * @return boolean true - */ - function prepare($argarray) + protected function atompubPrepare() { - parent::prepare($argarray); + $this->_profile = Profile::getKV('id', $this->trimmed('profile')); - $profileId = $this->trimmed('profile'); - - $this->_profile = Profile::getKV('id', $profileId); - - if (empty($this->_profile)) { + if (!$this->_profile instanceof Profile) { // TRANS: Client exception. throw new ClientException(_('No such profile.'), 404); } - $groupId = $this->trimmed('group'); + $this->_group = User_group::getKV('id', $this->trimmed('group')); - $this->_group = User_group::getKV('id', $groupId); - - if (empty($this->_group)) { + if (!$this->_group instanceof User_group) { // TRANS: Client exception thrown when referencing a non-existing group. throw new ClientException(_('No such group.'), 404); } $kv = array('group_id' => $groupId, - 'profile_id' => $profileId); + 'profile_id' => $this->_profile->id); $this->_membership = Group_member::pkeyGet($kv); - if (empty($this->_membership)) { + if (!$this->_profile->isMembmer($this->_group)) { // TRANS: Client exception thrown when trying to show membership of a non-subscribed group throw new ClientException(_('Not a member.'), 404); } @@ -92,29 +75,12 @@ class AtompubshowmembershipAction extends ApiAuthAction 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': - case 'HEAD': - $this->showMembership(); - break; - case 'DELETE': - $this->deleteMembership(); - break; - default: - // TRANS: Client exception thrown when using an unsupported HTTP method. - throw new ClientException(_('HTTP method not supported.'), 405); - break; - } - return; + protected function handleGet() { + return $this->showMembership(); + } + + protected function handleDelete() { + return $this->deleteMembership(); } /** @@ -154,25 +120,6 @@ class AtompubshowmembershipAction extends ApiAuthAction return; } - /** - * Return true if read only. - * - * MAY override - * - * @param array $args other arguments - * - * @return boolean is read only action? - */ - function isReadOnly($args) - { - if ($_SERVER['REQUEST_METHOD'] == 'GET' || - $_SERVER['REQUEST_METHOD'] == 'HEAD') { - return true; - } else { - return false; - } - } - /** * Return last modified, if applicable. * @@ -209,19 +156,4 @@ class AtompubshowmembershipAction extends ApiAuthAction $adminflag, $ctime)) . '"'; } - - /** - * Does this require authentication? - * - * @return boolean true if delete, else false - */ - function requiresAuth() - { - if ($_SERVER['REQUEST_METHOD'] == 'GET' || - $_SERVER['REQUEST_METHOD'] == 'HEAD') { - return false; - } else { - return true; - } - } } diff --git a/actions/atompubshowsubscription.php b/actions/atompubshowsubscription.php index 04681f3445..0d8c361519 100644 --- a/actions/atompubshowsubscription.php +++ b/actions/atompubshowsubscription.php @@ -28,11 +28,7 @@ * @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); -} +if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); } /** * Show a single subscription @@ -44,27 +40,19 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ -class AtompubshowsubscriptionAction extends ApiAuthAction +class AtompubshowsubscriptionAction extends AtompubAction { 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) + protected function atompubPrepare() { - parent::prepare($argarray); $subscriberId = $this->trimmed('subscriber'); $this->_subscriber = Profile::getKV('id', $subscriberId); - if (empty($this->_subscriber)) { + if (!$this->_subscriber instanceof Profile) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), @@ -75,18 +63,14 @@ class AtompubshowsubscriptionAction extends ApiAuthAction $this->_subscribed = Profile::getKV('id', $subscribedId); - if (empty($this->_subscribed)) { + if (!$this->_subscribed instanceof Profile) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), $subscribedId), 404); } - $this->_subscription = - Subscription::pkeyGet(array('subscriber' => $subscriberId, - 'subscribed' => $subscribedId)); - - if (empty($this->_subscription)) { + if (!$this->_subscriber->isSubscribed($this->_subscribed)) { // TRANS: Client exception thrown when trying to display a subscription for a non-subscribed profile ID. // TRANS: %1$d is the non-existing subscriber ID number, $2$d is the ID of the profile that was not subscribed to. $msg = sprintf(_('Profile %1$d not subscribed to profile %2$d.'), @@ -97,30 +81,14 @@ class AtompubshowsubscriptionAction extends ApiAuthAction return true; } - /** - * Handler method - * - * @param array $argarray is ignored since it's now passed in in prepare() - * - * @return void - */ - function handle($argarray=null) + protected function handleGet() { - parent::handle($argarray); - switch ($_SERVER['REQUEST_METHOD']) { - case 'HEAD': - case 'GET': - $this->showSubscription(); - break; - case 'DELETE': - $this->deleteSubscription(); - break; - default: - // TRANS: Client error shown when using a non-supported HTTP method. - $this->clientError(_('HTTP method not supported.'), 405); - } + $this->showSubscription(); + } - return; + protected function handleDelete() + { + $this->deleteSubscription(); } /** @@ -137,8 +105,6 @@ class AtompubshowsubscriptionAction extends ApiAuthAction $this->startXML(); $this->raw($activity->asString(true, true, true)); $this->endXML(); - - return; } /** @@ -148,17 +114,13 @@ class AtompubshowsubscriptionAction extends ApiAuthAction */ function deleteSubscription() { - if (empty($this->auth_user) || - $this->auth_user->id != $this->_subscriber->id) { + if (!$this->scoped instanceof Profile || + $this->scoped->id != $this->_subscriber->id) { // TRANS: Client exception thrown when trying to delete a subscription of another user. - throw new ClientException(_("Cannot delete someone else's ". - "subscription."), 403); + throw new ClientException(_("Cannot delete someone else's subscription."), 403); } - Subscription::cancel($this->_subscriber, - $this->_subscribed); - - return; + Subscription::cancel($this->_subscriber, $this->_subscribed); } /** @@ -172,9 +134,9 @@ class AtompubshowsubscriptionAction extends ApiAuthAction { if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { return false; - } else { - return true; } + + return true; } /** diff --git a/actions/atompubsubscriptionfeed.php b/actions/atompubsubscriptionfeed.php index 15e49c9f7c..413277a5d3 100644 --- a/actions/atompubsubscriptionfeed.php +++ b/actions/atompubsubscriptionfeed.php @@ -28,11 +28,7 @@ * @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); -} +if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); } /** * Subscription feed class for AtomPub @@ -46,68 +42,39 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ -class AtompubsubscriptionfeedAction extends ApiAuthAction +class AtompubsubscriptionfeedAction extends AtompubAction { private $_profile = null; private $_subscriptions = null; - /** - * For initializing members of the class. - * - * @param array $argarray misc. arguments - * - * @return boolean true - */ - function prepare($argarray) + protected function atompubPrepare() { - parent::prepare($argarray); - $subscriber = $this->trimmed('subscriber'); $this->_profile = Profile::getKV('id', $subscriber); - if (empty($this->_profile)) { + if (!$this->_profile instanceof Profile) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), $subscriber), 404); } - // page and count from ApiAction - - $offset = ($this->page-1) * $this->count; - - $this->_subscriptions = Subscription::bySubscriber($subscriber, - $offset, - $this->count + 1); + $this->_subscriptions = Subscription::bySubscriber($this->_profile->id, + $this->offset, + $this->limit); return true; } - /** - * Handler method - * - * @param array $argarray is ignored since it's now passed in in prepare() - * - * @return void - */ - function handle($argarray=null) + protected function handleGet() { - parent::handle($argarray); - switch ($_SERVER['REQUEST_METHOD']) { - case 'HEAD': - case 'GET': - $this->showFeed(); - break; - case 'POST': - $this->addSubscription(); - break; - default: - // TRANS: Client exception thrown when using an unsupported HTTP method. - $this->clientError(_('HTTP method not supported.'), 405); - } + $this->showFeed(); + } - return; + protected function handlePost() + { + $this->addSubscription(); } /** @@ -291,50 +258,4 @@ class AtompubsubscriptionfeedAction extends ApiAuthAction $this->endXML(); } } - - /** - * Return true if read only. - * - * @param array $args other arguments - * - * @return boolean is read only action? - */ - function isReadOnly($args) - { - return $_SERVER['REQUEST_METHOD'] != 'POST'; - } - - /** - * Return last modified, if applicable. - * - * @return string last modified http header - */ - function lastModified() - { - return null; - } - - /** - * Return etag, if applicable. - * - * @return string etag http header - */ - function etag() - { - return null; - } - - /** - * Does this require authentication? - * - * @return boolean true if delete, else false - */ - function requiresAuth() - { - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - return true; - } else { - return false; - } - } } diff --git a/lib/apiaction.php b/lib/apiaction.php index a562f5d976..d85029f433 100755 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -123,6 +123,8 @@ class ApiAction extends Action var $auth_user = null; var $page = null; var $count = null; + var $offset = null; + var $limit = null; var $max_id = null; var $since_id = null; var $source = null; @@ -152,6 +154,10 @@ class ApiAction extends Action $this->max_id = (int)$this->arg('max_id', 0); $this->since_id = (int)$this->arg('since_id', 0); + // These two are not used everywhere, mainly just AtompubAction extensions + $this->offset = ($this->page-1) * $this->count; + $this->limit = $this->count + 1; + if ($this->arg('since')) { header('X-StatusNet-Warning: since parameter is disabled; use since_id'); } diff --git a/lib/atompubaction.php b/lib/atompubaction.php new file mode 100644 index 0000000000..3349f40922 --- /dev/null +++ b/lib/atompubaction.php @@ -0,0 +1,95 @@ +. + */ + +if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); } + +abstract class AtompubAction extends ApiAuthAction +{ + protected $_profile = null; + protected $target = null; + + protected function prepare(array $args=array()) + { + parent::prepare($args); + + return $this->atompubPrepare(); + } + + protected function atompubPrepare() { + return true; + } + + protected function handle() + { + parent::handle(); + + switch ($_SERVER['REQUEST_METHOD']) { + case 'HEAD': + $this->handleHead(); + break; + case 'GET': + $this->handleGet(); + break; + case 'POST': + $this->handlePost(); + break; + case 'DELETE': + $this->handleDelete(); + break; + default: + // TRANS: Client exception thrown when using an unsupported HTTP method. + throw new ClientException(_('HTTP method not supported.'), 405); + } + + return true; + } + + protected function handleHead() + { + $this->handleGet(); + } + + protected function handleGet() + { + throw new ClientException(_('HTTP method not supported.'), 405); + } + + protected function handlePost() + { + throw new ClientException(_('HTTP method not supported.'), 405); + } + + protected function handleDelete() + { + throw new ClientException(_('HTTP method not supported.'), 405); + } + + function isReadOnly($args) + { + // GET/HEAD is readonly, POST and DELETE (etc?) are readwrite. + return in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')); + } + + function requiresAuth() + { + // GET/HEAD don't require auth, POST and DELETE (etc?) require it. + return !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')); + } +}