--- includes/actions/HistoryAction.php 2014-10-16 19:21:51.485431647 +0200 +++ includes_new/actions/HistoryAction.php 2014-10-16 19:21:25.489302729 +0200 @@ -614,7 +614,15 @@ } # Text following the character difference is added just before running hooks - $s2 = Linker::revComment( $rev, false, true ); + /*op-patch|TS|2009-11-05|HaloACL|Protected properties|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/Protected_properties + global $haclgProtectProperties; + $s2 = ''; + if (!$haclgProtectProperties) { + // The comment for an article might reveal values of protected properties + $s2 = Linker::revComment( $rev, false, true ); + } + /*op-patch|TS|2009-11-05|end*/ if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) { $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>'; --- includes/CategoryViewer.php 2014-10-16 19:21:51.433431367 +0200 +++ includes_new/CategoryViewer.php 2014-10-16 19:21:25.453302543 +0200 @@ -187,6 +187,12 @@ */ function addSubcategory( Title $title, $sortkey, $pageLength ) { wfDeprecated( __METHOD__, '1.17' ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$title->userCanReadEx()) { + return; + } + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|end*/ $this->addSubcategoryObject( Category::newFromTitle( $title ), $sortkey, $pageLength ); } @@ -255,6 +261,12 @@ function addPage( $title, $sortkey, $pageLength, $isRedirect = false ) { global $wgContLang; + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$title->userCanReadEx()) { + return; + } + /*op-patch|TS|2009-06-19|end*/ $link = Linker::link( $title ); if ( $isRedirect ) { // This seems kind of pointless given 'mw-redirect' class, --- includes/diff/DairikiDiff.php 2014-10-16 19:21:49.785423203 +0200 +++ includes_new/diff/DairikiDiff.php 2014-10-16 19:21:24.353297091 +0200 @@ -758,6 +758,7 @@ return $lines; } + /** * Check a Diff for validity. * @@ -1385,6 +1386,7 @@ function _lines( $lines, $prefix = ' ', $color = 'white' ) { } + // Remove property values before output if properties are protected /** * HTML-escape parameter before calling this @@ -1392,7 +1394,16 @@ * @return string */ function addedLine( $line ) { - return $this->wrapLine( '+', 'diff-addedline', $line ); + global $haclgProtectProperties; + if (!$haclgProtectProperties || !defined('SMW_VERSION') || !strpos($line, "::") ) { + // Properties are not protected or no properties in line - everything can be processed + return $this->wrapLine( '+++', 'diff-addedline', $line ); + } else { // properties in text + $regexpattern = '/::[^\]]*/'; + $regexreplace = '::Property value removed by HaloACL'; + $line2 = preg_replace($regexpattern, $regexreplace, $line); + return $this->wrapLine( '+', 'diff-addedline', $line2 ); + } } /** @@ -1401,7 +1412,16 @@ * @return string */ function deletedLine( $line ) { - return $this->wrapLine( '−', 'diff-deletedline', $line ); + global $haclgProtectProperties; + if (!$haclgProtectProperties || !defined('SMW_VERSION') || !strpos($line, "::") ) { + // Properties are not protected or no properties in line - everything can be processed + return $this->wrapLine( '-', 'diff-addedline', $line ); + } else { // properties in text + $regexpattern = '/::[^\]]*/'; + $regexreplace = '::Property value removed by HaloACL'; + $line2 = preg_replace($regexpattern, $regexreplace, $line); + return $this->wrapLine( '-', 'diff-addedline', $line2 ); + } } /** @@ -1410,7 +1430,16 @@ * @return string */ function contextLine( $line ) { - return $this->wrapLine( ' ', 'diff-context', $line ); + global $haclgProtectProperties; + if (!$haclgProtectProperties || !defined('SMW_VERSION') || !strpos($line, "::") ) { + // Properties are not protected or no properties in line - everything can be processed + return $this->wrapLine( ' ', 'diff-addedline', $line ); + } else { // properties in text + $regexpattern = '/::[^\]]*/'; + $regexreplace = '::Property value removed by HaloACL'; + $line2 = preg_replace($regexpattern, $regexreplace, $line); + return $this->wrapLine( ' ', 'diff-addedline', $line2 ); + } } /** --- includes/Linker.php 2014-10-16 19:21:50.557427038 +0200 +++ includes_new/Linker.php 2014-10-16 19:21:24.641298519 +0200 @@ -1588,7 +1588,14 @@ } else { $formatted = self::formatComment( $comment, $title, $local ); $formatted = wfMessage( 'parentheses' )->rawParams( $formatted )->escaped(); - return " <span class=\"comment\">$formatted</span>"; + global $haclgProtectProperties; + if (!$haclgProtectProperties || !defined('SMW_VERSION')) { + // Properties are not protected. + return " <span class=\"comment\">$formatted</span>"; + } elseif ( !strpos($formatted, "::") ) { // no properties in text + return " <span class=\"comment\">$formatted</span>"; + } + return ""; // text had properties -> deleted } } --- includes/QueryPage.php 2014-10-16 19:21:51.741432907 +0200 +++ includes_new/QueryPage.php 2014-10-16 19:21:25.709303812 +0200 @@ -588,6 +588,21 @@ # $res might contain the whole 1,000 rows, so we read up to # $num [should update this to use a Pager] for ( $i = 0; $i < $num && $row = $res->fetchObject(); $i++ ) { + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com/dmwiki/index.php/SafeTitle + $title = null; + if (isset($row->namespace) && isset($row->title)) { + $title = Title::makeTitleSafe( $row->namespace, $row->title ); + } else if (isset($row->id)) { + $title = Title::newFromID($row->id); + } else if (isset($row->type) && $row->type === 'Templates' + && isset($row->title)) { + $title = Title::makeTitleSafe(NS_TEMPLATE, $row->title); + } + if ($title && !$title->userCanReadEx()) { + continue; + } + /*op-patch|TS|2009-06-19|end*/ $line = $this->formatResult( $skin, $row ); if ( $line ) { $attr = ( isset( $row->usepatrol ) && $row->usepatrol && $row->patrolled == 0 ) --- includes/specials/SpecialAllpages.php 2014-10-16 19:21:52.505436684 +0200 +++ includes_new/specials/SpecialAllpages.php 2014-10-16 19:21:26.953309964 +0200 @@ -393,6 +393,12 @@ $out = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-chunk' ) ); while ( ( $n < $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) { $t = Title::newFromRow( $s ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if ($t && !$t->userCanReadEx()) { + continue; + } + /*op-patch|TS|2009-06-19|end*/ if ( $t ) { $link = ( $s->page_is_redirect ? '<div class="allpagesredirect">' : '' ) . Linker::link( $t ) . --- includes/specials/SpecialCategories.php 2014-10-16 19:21:52.401436154 +0200 +++ includes_new/specials/SpecialCategories.php 2014-10-16 19:21:26.837309403 +0200 @@ -121,6 +121,13 @@ function formatRow( $result ) { $title = Title::makeTitle( NS_CATEGORY, $result->cat_title ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + $title_nftv = Title::newFromTitleValue($title); + if (!$title_nftv->userCanReadEx()) { + return ""; + } + /*op-patch|TS|2009-06-19|end*/ $titleText = Linker::link( $title, htmlspecialchars( $title->getText() ) ); $count = $this->msg( 'nmembers' )->numParams( $result->cat_pages )->escaped(); --- includes/specials/SpecialContributions.php 2014-10-16 19:21:52.653437430 +0200 +++ includes_new/specials/SpecialContributions.php 2014-10-16 19:21:27.109310733 +0200 @@ -904,6 +904,9 @@ $classes = array(); $page = Title::newFromRow( $row ); + if (!$page->userCanReadEx()) { + return ""; + } $link = Linker::link( $page, htmlspecialchars( $page->getPrefixedText() ), --- includes/specials/SpecialDeletedContributions.php 2014-10-16 19:21:52.505436684 +0200 +++ includes_new/specials/SpecialDeletedContributions.php 2014-10-16 19:21:26.941309923 +0200 @@ -154,6 +154,9 @@ wfProfileIn( __METHOD__ ); $page = Title::makeTitle( $row->ar_namespace, $row->ar_title ); + if (!$page->userCanReadEx()) { + return ""; + } $rev = new Revision( array( 'title' => $page, --- includes/specials/SpecialExport.php 2014-10-16 19:21:52.617437252 +0200 +++ includes_new/specials/SpecialExport.php 2014-10-16 19:21:27.065310555 +0200 @@ -422,8 +422,15 @@ $ns = $wgContLang->getNsText( $row->page_namespace ); $n = $ns . ':' . $n; } - - $pages[] = $n; +/*op-patch|TS|2009-07-09|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + $t = Title::newFromText($n); + global $wgUser; + $allowed = wfRunHooks( 'userCan', array( &$t, &$wgUser, "read", &$result)); + if ($allowed) { + $pages[] = $n; + } +/*op-patch|TS|2009-07-09|end*/ } return $pages; --- includes/specials/SpecialListfiles.php 2014-10-16 19:21:52.357435954 +0200 +++ includes_new/specials/SpecialListfiles.php 2014-10-16 19:21:26.825309335 +0200 @@ -386,6 +386,31 @@ UserCache::singleton()->doQuery( $userIds, array( 'userpage' ), __METHOD__ ); } + function formatRow( $row ) { + + /*op-patch*/ + $fieldNames = $this->getFieldNames(); + $value = isset( $row->img_name ) ? $row->img_name : null; + $filePage = Title::makeTitleSafe( NS_FILE, $value ); + if (!$filePage->userCanReadEx()) { + return ""; + } + /*op-patch*/ + $this->mCurrentRow = $row; # In case formatValue etc need to know + $s = Xml::openElement( 'tr', $this->getRowAttrs( $row ) ); + $fieldNames = $this->getFieldNames(); + foreach ( $fieldNames as $field => $name ) { + $value = isset( $row->$field ) ? $row->$field : null; + $formatted = strval( $this->formatValue( $field, $value ) ); + if ( $formatted == '' ) { + $formatted = ' '; + } + $s .= Xml::tags( 'td', $this->getCellAttrs( $field, $value ), $formatted ); + } + $s .= "</tr>\n"; + return $s; + } + function formatValue( $field, $value ) { switch ( $field ) { case 'thumb': --- includes/specials/SpecialListredirects.php 2014-10-16 19:21:52.341435867 +0200 +++ includes_new/specials/SpecialListredirects.php 2014-10-16 19:21:26.785309154 +0200 @@ -123,6 +123,12 @@ # Find out where the redirect leads $target = $this->getRedirectTarget( $result ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$target->userCanReadEx()) { + return; + } + /*op-patch|TS|2009-06-19|end*/ if ( $target ) { # Make a link to the destination page $lang = $this->getLanguage(); --- includes/specials/SpecialNewimages.php 2014-10-16 19:21:52.405436174 +0200 +++ includes_new/specials/SpecialNewimages.php 2014-10-16 19:21:26.837309403 +0200 @@ -140,6 +140,9 @@ $user = User::newFromId( $row->img_user ); $title = Title::makeTitle( NS_FILE, $name ); + if (!$title->userCanReadEx()) { + return ""; + } $ul = Linker::link( $user->getUserpage(), $user->getName() ); $time = $this->getLanguage()->userTimeAndDate( $row->img_timestamp, $this->getUser() ); --- includes/specials/SpecialNewpages.php 2014-10-16 19:21:52.561436970 +0200 +++ includes_new/specials/SpecialNewpages.php 2014-10-16 19:21:27.029310361 +0200 @@ -305,6 +305,12 @@ */ public function formatRow( $result ) { $title = Title::newFromRow( $result ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$title->userCanReadEx()) { + return ""; + } + /*op-patch|TS|2009-06-19|end*/ # Revision deletion works on revisions, so we should cast one $row = array( --- includes/specials/SpecialPrefixindex.php 2014-10-16 19:21:52.625437280 +0200 +++ includes_new/specials/SpecialPrefixindex.php 2014-10-16 19:21:27.065310555 +0200 @@ -208,6 +208,12 @@ $prefixLength = strlen( $prefix ); while ( ( $n < $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) { $t = Title::makeTitle( $s->page_namespace, $s->page_title ); +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if ($t && !$t->userCanReadEx()) { + continue; + } +/*op-patch|TS|2009-06-19|end*/ if ( $t ) { $displayed = $t->getText(); // Try not to generate unclickable links --- includes/specials/SpecialProtectedpages.php 2014-10-16 19:21:52.561436970 +0200 +++ includes_new/specials/SpecialProtectedpages.php 2014-10-16 19:21:27.029310361 +0200 @@ -101,6 +101,12 @@ } $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$title->userCanReadEx()) { + return ""; + } + /*op-patch|TS|2009-06-19|end*/ if ( !$title ) { wfProfileOut( __METHOD__ ); --- includes/specials/SpecialProtectedtitles.php 2014-10-16 19:21:52.161434983 +0200 +++ includes_new/specials/SpecialProtectedtitles.php 2014-10-16 19:21:26.585308136 +0200 @@ -99,6 +99,13 @@ ) . "\n"; } + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$title->userCanReadEx()) { + return ""; + } + /*op-patch|TS|2009-06-19|end*/ + $link = Linker::link( $title ); $description_items = array(); // Messages: restriction-level-sysop, restriction-level-autoconfirmed --- includes/specials/SpecialRandompage.php 2014-10-16 19:21:52.517436746 +0200 +++ includes_new/specials/SpecialRandompage.php 2014-10-16 19:21:26.985310129 +0200 @@ -61,6 +61,12 @@ } $title = $this->getRandomTitle(); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$title->userCanReadEx()) { + $title = NULL; + } + /*op-patch|TS|2009-06-19|end*/ if ( is_null( $title ) ) { $this->setHeaders(); --- includes/specials/SpecialRecentchanges.php 2014-10-16 19:21:52.209435212 +0200 +++ includes_new/specials/SpecialRecentchanges.php 2014-10-16 19:21:26.613308280 +0200 @@ -464,6 +464,13 @@ $rclistOutput = $list->beginRecentChangesList(); foreach ( $rows as $obj ) { + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + $rc = RecentChange::newFromRow( $obj ); + if (!$rc->getTitle()->userCanReadEx()) { + continue; + } + /*op-patch|TS|2009-06-19|end*/ if ( $limit == 0 ) { break; } --- includes/specials/SpecialSearch.php 2014-10-16 19:21:52.265435499 +0200 +++ includes_new/specials/SpecialSearch.php 2014-10-16 19:21:26.685308659 +0200 @@ -540,7 +540,28 @@ $out .= "<ul class='mw-search-results'>\n"; $result = $matches->next(); while ( $result ) { - $out .= $this->showHit( $result, $terms ); +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (($result->getTitle() != NULL) && ($result->getTitle()->userCanReadEx())) { + global $haclgProtectProperties; + if (!$haclgProtectProperties || !defined('SMW_VERSION')) { + // Properties are not protected. + $out .= $this->showHit( $result, $terms ); + } else { + $res0 = $this->showHit( $result, $terms ); + $res1 = str_replace("'", "", $res0); + if ( !strpos($res1, "::<span class=searchmatch>") ) { + $regexpattern = '/::[^\]]*/'; + $regexreplace = '::Property value protected by HaloACL'; + $res2 = preg_replace($regexpattern, $regexreplace, $res1); + $out .= $res2; + } else { + $out .= '<p>Search result deleted by HaloACL</p>'; + } + + } + } +/*op-patch|TS|2009-06-19|end*/ $result = $matches->next(); } $out .= "</ul>\n"; --- includes/specials/SpecialUndelete.php 2014-10-16 19:21:52.317435758 +0200 +++ includes_new/specials/SpecialUndelete.php 2014-10-16 19:21:26.745308951 +0200 @@ -1339,6 +1339,12 @@ $user = $this->getUser(); if ( $this->mCanView ) { $titleObj = $this->getTitle(); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if ($titleObj && !$titleObj->userCanReadEx()) { + return ""; + } + /*op-patch|TS|2009-06-19|end*/ # Last link if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) { $pageLink = htmlspecialchars( $this->getLanguage()->userTimeAndDate( $ts, $user ) ); @@ -1388,6 +1394,12 @@ private function formatFileRow( $row ) { $file = ArchivedFile::newFromRow( $row ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if ($file->getTitle() && !$file->getTitle()->userCanReadEx()) { + return ""; + } + /*op-patch|TS|2009-06-19|end*/ $ts = wfTimestamp( TS_MW, $row->fa_timestamp ); $user = $this->getUser(); --- includes/specials/SpecialWatchlist.php 2014-10-16 19:21:52.281435580 +0200 +++ includes_new/specials/SpecialWatchlist.php 2014-10-16 19:21:26.685308659 +0200 @@ -430,6 +430,12 @@ foreach ( $res as $obj ) { # Make RC entry $rc = RecentChange::newFromRow( $obj ); + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$rc->getTitle()->userCanReadEx()) { + continue; + } + /*op-patch|TS|2009-06-19|end*/ $rc->counter = $counter++; if ( $wgShowUpdatedMarker ) { --- includes/specials/SpecialWhatlinkshere.php 2014-10-16 19:21:52.513436732 +0200 +++ includes_new/specials/SpecialWhatlinkshere.php 2014-10-16 19:21:26.965310063 +0200 @@ -261,6 +261,12 @@ $out->addHTML( $this->listStart( $level ) ); foreach ( $rows as $row ) { $nt = Title::makeTitle( $row->page_namespace, $row->page_title ); +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + if (!$nt->userCanReadEx()) { + continue; + } +/*op-patch|TS|2009-06-19|end*/ if ( $row->rd_from && $level < 2 ) { $out->addHTML( $this->listItem( $row, $nt, true ) ); diff -u -r -N includes/Title.php includes_new/Title.php --- includes/Title.php 2014-10-16 19:21:49.997424257 +0200 +++ includes_new/Title.php 2014-10-16 19:21:24.461297618 +0200 @@ -104,9 +104,15 @@ public static function newFromDBkey( $key ) { $t = new Title(); $t->mDbkeyform = $key; - if ( $t->secureAndSplit() ) { - return $t; - } else { + if( $t->secureAndSplit() ) { + /*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ + // See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + return $t->checkAccessControl(); + } + /*op-patch|TS|2009-06-19|end*/ + //Replaced by patch return $t; + + else { return null; } } @@ -159,7 +165,11 @@ $cachedcount++; Title::$titleCache[$text] =& $t; } - return $t; +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + return $t->checkAccessControl(); +/*op-patch|TS|2009-06-19|end*/ +// Preplaced by patch return $t; } else { $ret = null; return $ret; @@ -193,7 +203,11 @@ $t->mDbkeyform = str_replace( ' ', '_', $url ); if ( $t->secureAndSplit() ) { - return $t; +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + return $t->checkAccessControl(); +/*op-patch|TS|2009-06-19|end*/ +// Preplaced by patch return $t; } else { return null; } @@ -338,7 +352,12 @@ $t->mUrlform = wfUrlencode( $t->mDbkeyform ); $t->mTextform = str_replace( '_', ' ', $title ); $t->mContentModel = false; # initialized lazily in getContentModel() - return $t; +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + $t = $t->checkAccessControl(); + return $t; +/*op-patch|TS|2009-06-19|end*/ +// Preplaced by patch return $t; } /** @@ -360,7 +379,11 @@ $t = new Title(); $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki ); if ( $t->secureAndSplit() ) { - return $t; +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + return $t->checkAccessControl(); +/*op-patch|TS|2009-06-19|end*/ +// Preplaced by patch return $t; } else { return null; } @@ -1015,6 +1038,24 @@ return $result; } + /*op-patch|TS|2012-02-24|HaloACL|HaloACLMemcache|start*/ + // See http://dmwiki.ontoprise.com/index.php/HaloACLMemcache + public function userCanRead() { + if (!defined('HACL_HALOACL_VERSION')) { + //HaloACL is disabled + return $this->userCanReadOrig(); + } + + global $wgUser; + $hmc = HACLMemcache::getInstance(); + $allowed = $hmc->retrievePermission($wgUser, $this, 'read'); + if ($allowed === -1) { + $allowed = $this->userCanReadOrig(); + $hmc->storePermission($wgUser, $this, 'read', $allowed); + } + return $allowed; + } + /** * Is this the mainpage? * @note Title::newFromText seems to be sufficiently optimized by the title @@ -1348,6 +1389,25 @@ return implode( '/', $parts ); } +/*op-patch|TS|2012-02-24|HaloACL|HaloACLMemcache|start*/ +// See http://dmwiki.ontoprise.com/index.php/HaloACLMemcache + +public function userCan($action, $doExpensiveQueries = true) { + if (!defined('HACL_HALOACL_VERSION')) { + //HaloACL is disabled + return $this->userCanOrig($action, $doExpensiveQueries); + } + + global $wgUser; + $hmc = HACLMemcache::getInstance(); + $allowed = $hmc->retrievePermission($wgUser, $this, $action); + if ($allowed === -1) { + $allowed = $this->userCanOrig($action, $doExpensiveQueries); + $hmc->storePermission($wgUser, $this, $action, $allowed); + } + return $allowed; +} + /** * Get the base page name title, i.e. the part before the subpage name * @@ -1760,7 +1820,7 @@ * @return Bool * @todo fold these checks into userCan() */ - public function userCanRead() { + public function userCanReadOrig() { wfDeprecated( __METHOD__, '1.19' ); return $this->userCan( 'read' ); } @@ -1794,7 +1854,7 @@ * unnecessary queries. * @return Bool */ - public function userCan( $action, $user = null, $doExpensiveQueries = true ) { + public function userCanOrig( $action, $user = null, $doExpensiveQueries = true ) { if ( !$user instanceof User ) { global $wgUser; $user = $wgUser; @@ -2237,7 +2297,7 @@ # If it's a special page, ditch the subpage bit and check again $name = $this->getDBkey(); list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name ); - if ( $name ) { + if ( !is_null($name) ) { $pure = SpecialPage::getTitleFor( $name )->getPrefixedText(); if ( in_array( $pure, $wgWhitelistRead, true ) ) { $whitelisted = true; @@ -2257,6 +2317,9 @@ } } + wfRunHooks( 'userCan', array( &$this, &$user, $action, &$whitelisted ) ); + + if ( !$whitelisted ) { # If the title is not whitelisted, give extensions a chance to do so... wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) ); @@ -4450,6 +4513,99 @@ return $this->getArticleID() != 0; } +/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/ +// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle + + /** + * This function is called from the patches for HaloACL for secure listings + * (e.g. Spcecial:AllPages). It checks, whether the current user is allowed + * to read the article for this title object. For normal pages this is + * evaluate in the method <userCanRead>. + * However, the special pages that generate listings, often create title + * objects before the can check their accessibility. The fallback mechanism + * of HaloACL creates the title "Permission denied" for the article that + * must not be accessed. The listings would then show a link to "Permission + * denied". So this function returns "false" for the title "Permission denied" + * as well. + * + * @return + * true, if this title can be read + * false, if the title is protected or "Permission denied". + */ + public function userCanReadEx() { + if (!defined('HACL_HALOACL_VERSION')) { + //HaloACL is disabled + return true; + } + global $haclgContLang; + return $this->mTextform !== $haclgContLang->getPermissionDeniedPage() + && $this->userCanRead(); + } + + /** + * This function checks, if this title is accessible for the action of the + * current request. If the action is unknown it is assumed to be "read". + * If the title is not accessible, the new title "Permission denied" is + * returned. This is a fallback to protect titles if all other security + * patches fail. + * + * While a page is rendered, the same title is often checked several times. + * To speed things up, the results of an accessibility check are internally + * cached. + * + * This function can be disabled in HACL_Initialize.php or LocalSettings.php + * by setting the variable $haclgEnableTitleCheck = false. + * + * @return + * $this, if access is granted on this title or + * the title for "Permission denied" if not. + */ + private function checkAccessControl() { + if (!defined('HACL_HALOACL_VERSION')) { + //HaloACL is disabled + return $this; + } + global $haclgEnableTitleCheck; + if (isset($haclgEnableTitleCheck) && $haclgEnableTitleCheck === false) { + return $this; + } + + static $permissionCache = array(); + + global $wgRequest; + $action = $wgRequest->getVal( 'action', 'read'); + $currentTitle = $wgRequest->getVal('title'); + $currentTitle = str_replace( '_', ' ', $currentTitle); + if ($this->getFullText() != $currentTitle) { + $action = 'read'; + } + $index = $this->getFullText().'-'.$action; // A bug was fixed here thanks to Dave MacDonald + $allowed = @$permissionCache[$index]; + if (!isset($allowed)) { + switch ($action) { + case 'create': + case 'edit': + case 'move': + case 'annotate': + $allowed = $this->userCan($action); + break; + default: + $allowed = $this->userCanRead(); + } + $permissionCache[$index] = $allowed; + } + if ($allowed === false) { + global $haclgContLang; + $etc = $haclgEnableTitleCheck; + $haclgEnableTitleCheck = false; + $t = Title::newFromURL($haclgContLang->getPermissionDeniedPage()); + $haclgEnableTitleCheck = $etc; + return $t; + } + return $this; + } +/*op-patch|TS|2009-06-19|end*/ + /** * Should links to this title be shown as potentially viewable (i.e. as * "bluelinks"), even if there's no record by this title in the page