]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Disallow repeats (retweets) of private notices
authorEvan Prodromou <evan@status.net>
Tue, 29 Mar 2011 15:53:26 +0000 (11:53 -0400)
committerEvan Prodromou <evan@status.net>
Tue, 29 Mar 2011 15:53:26 +0000 (11:53 -0400)
We disallow repeating a notice (or whatever) if the scope of the
notice is too private. So, only notices that are public scope
(available to everyone in the world) or site scope (available to
everyone on the site) can be repeated.

Enforce this rule at a low level in Notice.php, and in the API,
commands, and Web UI. Repeat button doesn't appear on tightly-scoped
notices in the Web UI.

actions/apistatusesretweet.php
actions/repeat.php
classes/Notice.php
lib/command.php
lib/noticelistitem.php

index ecc4a3f03301b92651dea1d5fe522f8792214f27..2bc9092ba6f42aa02313a03fbf904d52e5136019 100644 (file)
@@ -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;
     }
 
index 869c2ddd4ee1851c073586789020768b64eb56a0..4201a4ce955af96b69340d5e1e2e56e801979e59 100644 (file)
@@ -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.'));
index 3780d52d561d81ebb93768235a50194947f2f8d6..a6e4566e4bc89ad89c86ed910aff731d332bad04 100644 (file)
@@ -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);
index 5b9964c5b1b0a2f878b0b81c39241cb0b8351019..35d070268414c57ab9ab3a776a409666f6dee4e8 100644 (file)
@@ -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;
index 46f15f551d3fb63882550ad1e72fd0895f4edbca..097a5d06c44352a7f01febf515133c7120726df1 100644 (file)
@@ -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();
+                }
             }
         }
     }