/** * Returns the ID of a protected object that is given by its name. * The ID depends on the type. * * @param string $peName Object name * @param int $peType Object type (IACL::PE_*) * @return int/bool Object id or <false> if it does not exist */ public static function peIDforName($peType, $peName) { $ns = NS_MAIN; $force = true; switch ($peType) { case IACL::PE_PAGE: // Page ACLs allow any namespace except NS_SPECIAL $force = false; break; case IACL::PE_NAMESPACE: // $peName is a namespace => get its ID global $wgContLang; $peName = str_replace(' ', '_', trim($peName, " _\t\n\r")); $idx = $wgContLang->getNsIndex($peName); if ($idx == false) { return strtolower($peName) == 'main' ? 0 : false; } return $idx; case IACL::PE_CATEGORY: $ns = NS_CATEGORY; break; case IACL::PE_USER: $user = User::newFromName($peName); return $user->getId(); case IACL::PE_SPECIAL: $ns = NS_SPECIAL; break; // Groups and rights are in ACL namespace // Groups and rights are in ACL namespace case IACL::PE_GROUP: global $haclgContLang; $peName = $haclgContLang->getPetPrefix(IACL::PE_GROUP) . '/' . $peName; case IACL::PE_RIGHT: $ns = HACL_NS_ACL; break; } // Return the page id // TODO add caching here $id = haclfArticleID($peName, $ns, $force); if ($id < 0) { if ($peType != IACL::PE_SPECIAL) { throw new Exception(__METHOD__ . ': BUG: Special page title passed, but PE type = ' . $peType . ' (not PE_SPECIAL)'); } return -$id; } return $id ? $id : NULL; }
/** * Returns array(final log message, access granted?, continue hook processing?) */ public static function userCan_Switches($title, $user, $action) { global $haclgContLang, $haclgSuperGroups; if (!$title) { return array('Title is <null>', 1); } if ($title->getInterwiki() !== '') { // Do not check interwiki links return array('Interwiki title', 1); } $groups = $user->getGroups(); if ($groups && array_intersect($groups, $haclgSuperGroups)) { return array('User is a superuser and can do anything.', 1); } if ($title->getPrefixedText() == $haclgContLang->getPermissionDeniedPage()) { // no access to the page "Permission denied" emitted by TitlePatch is allowed return array('Special handling of "Permission denied" page', 0); } // Check action $actionID = IACL::getActionID($action); if (!$actionID) { // Unknown action => nothing can be said about this return array('Unknown action', 1); } // Check rights for managing ACLs if ($title->getNamespace() == HACL_NS_ACL) { return array('Checked ACL modification rights', self::checkACLManager($title, $user, $actionID)); } // If there is a whitelist, then allow user to read the page if ($actionID == IACL::ACTION_READ && self::isWhitelisted($title)) { return array('Page is in MediaWiki whitelist', 1); } // haclfArticleID also returns IDs for special pages $articleID = haclfArticleID($title); $userID = $user->getId(); if ($articleID && $actionID == IACL::ACTION_CREATE) { // create=edit for existing articles $actionID = IACL::ACTION_EDIT; } elseif (!$articleID) { if ($actionID == IACL::ACTION_EDIT) { // edit=create for non-existing articles self::log('Article does not exist yet. Checking right to create.'); $actionID = IACL::ACTION_CREATE; } elseif ($actionID == IACL::ACTION_DELETE || $actionID == IACL::ACTION_MOVE) { return array('Moving/deleting non-existing article is pointless', 1); } $r = IACLDefinition::userCan($userID, IACL::PE_NAMESPACE, $title->getNamespace(), $actionID); if ($r <= 0 && $actionID == IACL::ACTION_READ) { // Read right is needed to show edit form $r = IACLDefinition::userCan($userID, IACL::PE_NAMESPACE, $title->getNamespace(), IACL::ACTION_CREATE); } return array('Checked namespace access right', $r); } if ($articleID && $title->isRedirect()) { // Redirects are treated like symlinks in Unix: their permissions are always equal to target // (at least if target exists...) $dbr = wfGetDB(DB_SLAVE); $id = $articleID; $seen = array(); do { $seen[$id] = true; $row = $dbr->selectRow(array('page', 'redirect'), 'page.*', array('rd_from' => $id, 'page_namespace=rd_namespace', 'page_title=rd_title'), __METHOD__); $id = $row ? $row->page_id : NULL; } while ($row && $row->page_is_redirect && !$seen[$row->page_id]); if ($row) { $title = Title::newFromRow($row); $articleID = $row->page_id; self::log("Page is a live redirect to " . $title->getFullText() . ", checking permissions for target"); } } return self::hasSD($title, $articleID, $userID, $actionID); }