diff --git a/actions/apistatusesretweet.php b/actions/apistatusesretweet.php index ecc4a3f033..2bc9092ba6 100644 --- a/actions/apistatusesretweet.php +++ b/actions/apistatusesretweet.php @@ -85,8 +85,27 @@ class ApiStatusesRetweetAction extends ApiAuthAction return false; } + // Is it OK to repeat that notice (general enough scope)? + + if ($this->original->scope != Notice::SITE_SCOPE && + $this->original->scope != Notice::PUBLIC_SCOPE) { + $this->clientError(_('You may not repeat a private notice.'), + 403, + $this->format); + return false; + } + $profile = $this->user->getProfile(); + // Can the profile actually see that notice? + + if (!$this->original->inScope($profile)) { + $this->clientError(_('No access to that notice.'), + 403, + $this->format); + return false; + } + if ($profile->hasRepeated($id)) { // TRANS: Client error displayed trying to re-repeat a notice through the API. $this->clientError(_('Already repeated that notice.'), @@ -94,6 +113,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction return false; } + return true; } diff --git a/actions/repeat.php b/actions/repeat.php index 869c2ddd4e..4201a4ce95 100644 --- a/actions/repeat.php +++ b/actions/repeat.php @@ -73,6 +73,14 @@ class RepeatAction extends Action return false; } + // Is it OK to repeat that notice (general enough scope)? + + if ($this->notice->scope != Notice::SITE_SCOPE && + $this->notice->scope != Notice::PUBLIC_SCOPE) { + $this->clientError(_('You may not repeat a private notice.'), + 403); + } + if ($this->user->id == $this->notice->profile_id) { // TRANS: Client error displayed when trying to repeat an own notice. $this->clientError(_('You cannot repeat your own notice.')); @@ -88,6 +96,13 @@ class RepeatAction extends Action $profile = $this->user->getProfile(); + // Can the profile actually see that notice? + + if (!$this->notice->inScope($profile)) { + $this->clientError(_('No access to that notice.'), 403); + } + + if ($profile->hasRepeated($id)) { // TRANS: Client error displayed when trying to repeat an already repeated notice. $this->clientError(_('You already repeated that notice.')); diff --git a/classes/Notice.php b/classes/Notice.php index 3780d52d56..a6e4566e4b 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -90,6 +90,7 @@ class Notice extends Memcached_DataObject const LOCAL_NONPUBLIC = -1; const GATEWAY = -2; + const PUBLIC_SCOPE = 0; // Useful fake constant const SITE_SCOPE = 1; const ADDRESSEE_SCOPE = 2; const GROUP_SCOPE = 4; @@ -344,6 +345,19 @@ class Notice extends Memcached_DataObject // Handle repeat case if (isset($repeat_of)) { + + // Check for a private one + + $repeat = Notice::staticGet('id', $repeat_of); + + if (!empty($repeat) && + $repeat->scope != Notice::SITE_SCOPE && + $repeat->scope != Notice::PUBLIC_SCOPE) { + throw new ClientException(_('Cannot repeat a private notice.'), 403); + } + + // XXX: Check for access...? + $notice->repeat_of = $repeat_of; } else { $notice->reply_to = self::getReplyTo($reply_to, $profile_id, $source, $final); diff --git a/lib/command.php b/lib/command.php index 5b9964c5b1..35d0702684 100644 --- a/lib/command.php +++ b/lib/command.php @@ -544,7 +544,22 @@ class RepeatCommand extends Command return; } - if ($this->user->getProfile()->hasRepeated($notice->id)) { + // Is it OK to repeat that notice (general enough scope)? + + if ($notice->scope != Notice::SITE_SCOPE && + $notice->scope != Notice::PUBLIC_SCOPE) { + $channel->error($this->user, _('You may not repeat a private notice.')); + } + + $profile = $this->user->getProfile(); + + // Can the profile actually see that notice? + + if (!$notice->inScope($profile)) { + $channel->error($this->user, _('You have no access to that notice.')); + } + + if ($profile->hasRepeated($notice->id)) { // TRANS: Error text shown when trying to repeat an notice that was already repeated by the user. $channel->error($this->user, _('Already repeated that notice.')); return; diff --git a/lib/noticelistitem.php b/lib/noticelistitem.php index 46f15f551d..097a5d06c4 100644 --- a/lib/noticelistitem.php +++ b/lib/noticelistitem.php @@ -596,17 +596,21 @@ class NoticeListItem extends Widget function showRepeatForm() { - $user = common_current_user(); - if ($user && $user->id != $this->notice->profile_id) { - $this->out->text(' '); - $profile = $user->getProfile(); - if ($profile->hasRepeated($this->notice->id)) { - $this->out->element('span', array('class' => 'repeated', - 'title' => _('Notice repeated')), - _('Repeated')); - } else { - $rf = new RepeatForm($this->out, $this->notice); - $rf->show(); + if ($this->notice->scope == Notice::PUBLIC_SCOPE || + $this->notice->scope == Notice::SITE_SCOPE) { + $user = common_current_user(); + if (!empty($user) && + $user->id != $this->notice->profile_id) { + $this->out->text(' '); + $profile = $user->getProfile(); + if ($profile->hasRepeated($this->notice->id)) { + $this->out->element('span', array('class' => 'repeated', + 'title' => _('Notice repeated')), + _('Repeated')); + } else { + $rf = new RepeatForm($this->out, $this->notice); + $rf->show(); + } } } }