X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=02b8ce3549f3b79ca4fb6715e6c762a997f87f0e;hb=26195d90e2a2544344a456e96cc69b9f07396207;hp=15f4f75be0e819793729ef980db92784ceadc63d;hpb=261ccfac8699534ff584a2f93d5dcd384529d855;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 15f4f75be0..02b8ce3549 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -542,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); } @@ -1118,7 +1117,7 @@ class Notice extends Managed_DataObject * * @return void */ - function saveKnownUrls($urls) + function saveKnownUrls(array $urls) { if (common_config('attachments', 'process_links')) { // @fixme validation? @@ -1692,12 +1691,12 @@ class Notice extends Managed_DataObject $ids[] = $reply->profile_id; } - $this->_replies[$this->id] = $ids; + $this->_setReplies($ids); return $ids; } - function _setReplies($replies) + function _setReplies(array $replies) { $this->_replies[$this->id] = $replies; } @@ -1775,13 +1774,11 @@ class Notice extends Managed_DataObject } $groups = User_group::multiGet('id', $ids); - - $this->_groups[$this->id] = $groups->fetchAll(); - + $this->_setGroups($groups->fetchAll()); return $this->_groups[$this->id]; } - - function _setGroups($groups) + + function _setGroups(array $groups) { $this->_groups[$this->id] = $groups; } @@ -2506,6 +2503,41 @@ class Notice extends Managed_DataObject */ public function getTags() { + // Check default scope (non-private notices) + $inScope = (!$this->isPrivateScope()); + + // Get current user + $user = common_current_user(); + + // Is the general scope check okay and the user in logged in? + /* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ',user[]=' . gettype($user)); + if (($inScope === TRUE) && ($user instanceof User)) { + // Get profile from it + $profile = $user->getProfile(); + /* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ',profile[]=' . gettype($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); @@ -2517,7 +2549,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; } @@ -2659,7 +2693,7 @@ class Notice extends Managed_DataObject * * @return boolean whether the profile is in the notice's scope */ - function inScope($profile) + function inScope(Profile $profile=null) { if (is_null($profile)) { $keypart = sprintf('notice:in-scope-for:%d:null', $this->id); @@ -2682,7 +2716,7 @@ class Notice extends Managed_DataObject return ($result == 1) ? true : false; } - protected function _inScope($profile) + protected function _inScope(Profile $profile=null) { if (!is_null($this->scope)) { $scope = $this->scope; @@ -2722,7 +2756,7 @@ class Notice extends Managed_DataObject $reply = Reply::pkeyGet(array('notice_id' => $this->id, 'profile_id' => $profile->id)); - + if (!$reply instanceof Reply) { return false; } @@ -2771,8 +2805,8 @@ class Notice extends Managed_DataObject } } - function isHiddenSpam($profile) { - + function isHiddenSpam(Profile $profile=null) { + // Hide posts by silenced users from everyone but moderators. if (common_config('notice', 'hidespam')) { @@ -2836,7 +2870,7 @@ class Notice extends Managed_DataObject return $scope; } - static function fillProfiles($notices) + static function fillProfiles(array $notices) { $map = self::getProfiles($notices); @@ -2853,8 +2887,8 @@ class Notice extends Managed_DataObject return array_values($map); } - - static function getProfiles(&$notices) + + static function getProfiles(array &$notices) { $ids = array(); foreach ($notices as $notice) { @@ -2865,8 +2899,8 @@ class Notice extends Managed_DataObject return Profile::pivotGet('id', $ids); } - - static function fillGroups(&$notices) + + static function fillGroups(array &$notices) { $ids = self::_idsOf($notices); @@ -2906,7 +2940,7 @@ class Notice extends Managed_DataObject return array_keys($ids); } - static function fillAttachments(&$notices) + static function fillAttachments(array &$notices) { $ids = self::_idsOf($notices); @@ -2935,7 +2969,7 @@ class Notice extends Managed_DataObject } } - static function fillReplies(&$notices) + static function fillReplies(array &$notices) { $ids = self::_idsOf($notices); $replyMap = Reply::listGet('notice_id', $ids); @@ -2957,22 +2991,33 @@ class Notice extends Managed_DataObject return $this->_repeats[$this->id]; } $repeatMap = Notice::listGet('repeat_of', array($this->id)); - $this->_repeats[$this->id] = $repeatMap[$this->id]; + $this->_setRepeats($repeatMap[$this->id]); return $this->_repeats[$this->id]; } - function _setRepeats($repeats) + function _setRepeats(array $repeats) { $this->_repeats[$this->id] = $repeats; } - static function fillRepeats(&$notices) + static function fillRepeats(array &$notices) { $ids = self::_idsOf($notices); $repeatMap = Notice::listGet('repeat_of', $ids); foreach ($notices as $notice) { - $repeats = $repeatMap[$notice->id]; + $repeats = $repeatMap[$notice->id]; $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); + } }