X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=5c18f03500f1de2625ad9b57ad67a484d1faf3b3;hb=refs%2Fheads%2Frewrites-nightly%2Ftype-hints-asserts;hp=86eee49321a22ec89ec56e9edb3f29359a767b6a;hpb=f4ec1c998d29cb4f9335e15e65cd43ff035583d2;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 86eee49321..5c18f03500 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -313,6 +313,16 @@ class Notice extends Managed_DataObject return $notice; } + public static function getById($id) + { + $notice = new Notice(); + $notice->id = $id; + if (!$notice->find(true)) { + throw new NoResultException($notice); + } + return $notice; + } + /** * Extract #hashtags from this notice's content and save them to the database. */ @@ -542,8 +552,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); } @@ -1114,7 +1123,7 @@ class Notice extends Managed_DataObject * * @return void */ - function saveKnownUrls($urls) + function saveKnownUrls(array $urls) { if (common_config('attachments', 'process_links')) { // @fixme validation? @@ -1684,12 +1693,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; } @@ -1766,11 +1775,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; } @@ -2495,6 +2504,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); @@ -2506,7 +2550,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; } @@ -2648,7 +2694,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); @@ -2671,7 +2717,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; @@ -2740,7 +2786,7 @@ class Notice extends Managed_DataObject return !$this->isHiddenSpam($profile); } - function isHiddenSpam($profile) { + function isHiddenSpam(Profile $profile=null) { // Hide posts by silenced users from everyone but moderators. @@ -2805,7 +2851,7 @@ class Notice extends Managed_DataObject return $scope; } - static function fillProfiles($notices) + static function fillProfiles(array $notices) { $map = self::getProfiles($notices); foreach ($notices as $entry=>$notice) { @@ -2822,7 +2868,7 @@ class Notice extends Managed_DataObject return array_values($map); } - static function getProfiles(&$notices) + static function getProfiles(array &$notices) { $ids = array(); foreach ($notices as $notice) { @@ -2832,7 +2878,7 @@ class Notice extends Managed_DataObject return Profile::pivotGet('id', $ids); } - static function fillGroups(&$notices) + static function fillGroups(array &$notices) { $ids = self::_idsOf($notices); $gis = Group_inbox::listGet('notice_id', $ids); @@ -2867,7 +2913,7 @@ class Notice extends Managed_DataObject return array_keys($ids); } - static function fillAttachments(&$notices) + static function fillAttachments(array &$notices) { $ids = self::_idsOf($notices); $f2pMap = File_to_post::listGet('post_id', $ids); @@ -2891,7 +2937,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); @@ -2913,22 +2959,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); + } }