X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=263cc4e32394ecbcd2880ac2f8cc91e3067a9779;hb=refs%2Fheads%2Ffixes%2Fprivate_scope_on_tags;hp=3825e07a0f51745cd770f23c6c6e77491acc7e85;hpb=fd3d46d07da49eeeaedce406e30344a8bf0b7e6a;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 3825e07a0f..263cc4e323 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -416,7 +416,7 @@ class Notice extends Managed_DataObject * @return Notice * @throws ClientException */ - static function saveNew($profile_id, $content, $source, array $options=null) { + static function saveNew($profile_id, $content, $source, array $options=array()) { $defaults = array('uri' => null, 'url' => null, 'conversation' => null, // URI of conversation @@ -427,13 +427,16 @@ class Notice extends Managed_DataObject 'object_type' => null, 'verb' => null); - if (!empty($options) && is_array($options)) { + /* + * Above type-hint is already array, so simply count it, this saves + * "some" CPU cycles. + */ + if (count($options) > 0) { $options = array_merge($defaults, $options); - extract($options); - } else { - extract($defaults); } + extract($options); + if (!isset($is_local)) { $is_local = Notice::LOCAL_PUBLIC; } @@ -539,8 +542,7 @@ class Notice extends Managed_DataObject throw new ClientException(_('You cannot repeat your own notice.')); } - if ($repeat->scope != Notice::SITE_SCOPE && - $repeat->scope != Notice::PUBLIC_SCOPE) { + if ($repeat->isPrivateScope()) { // TRANS: Client error displayed when trying to repeat a non-public notice. throw new ClientException(_('Cannot repeat a private notice.'), 403); } @@ -2501,6 +2503,37 @@ class Notice extends Managed_DataObject */ public function getTags() { + // Check default scope (non-private notices) + $inScope = (!$this->isPrivateScope()); + + // Get current profile + $profile = Profile::current(); + + // Is the general scope check okay and the user in logged in? + //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ',profile[]=' . gettype($profile)); + if (($inScope === TRUE) && ($profile instanceof Profile)) { + /* + * Check scope, else a privacy leaks happens this way: + * + * 1) Bob and Alice follow each other and write private notices + * (this->scope=2) to each other. + * 2) Bob uses tags in his private notice to alice (which she can + * read from him). + * 3) Alice adds that notice (with tags) to her favorites + * ("faving") it. + * 4) The tags from Bob's private notice becomes visible in Alice's + * profile. + * + * This has the simple background that the scope is not being + * re-checked. This has to be done here at this point because given + * above scenario is a privacy leak as the tags may be *really* + * private (nobody else shall see them) such as initmate words or + * very political words. + */ + $inScope = $this->inScope($profile); + //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ' - After inScope() has been called.'); + } + $tags = array(); $keypart = sprintf('notice:tags:%d', $this->id); @@ -2512,7 +2545,9 @@ class Notice extends Managed_DataObject } else { $tag = new Notice_tag(); $tag->notice_id = $this->id; - if ($tag->find()) { + + // Check scope for privacy-leak protection (see some lines above why) + if (($inScope === TRUE) && ($tag->find())) { while ($tag->fetch()) { $tags[] = $tag->tag; } @@ -2717,7 +2752,7 @@ class Notice extends Managed_DataObject $reply = Reply::pkeyGet(array('notice_id' => $this->id, 'profile_id' => $profile->id)); - + if (!$reply instanceof Reply) { return false; } @@ -2970,4 +3005,15 @@ class Notice extends Managed_DataObject $notice->_setRepeats($repeats); } } + + /** + * Checks whether this notice is in "private scope" (non-public notice) + * + * @return $isPrivate Whether this notice is private + */ + public function isPrivateScope () + { + return ($this->scope != Notice::SITE_SCOPE && + $this->scope != Notice::PUBLIC_SCOPE); + } }