Exemplo n.º 1
0
 function getDefs()
 {
     return IACLDefinition::select(array('pe' => $this->pe_ids));
 }
Exemplo n.º 2
0
 /**
  * This method returns HTML code for the IntraACL toolbar,
  * for the $title editing mode.
  *
  * Looks like the following:
  * Page protection: <selectbox>. [Additional ACL ↓] [Used content ↓] [Edit ACL] ... [Manage Quick ACL]
  *
  * Options for selectbox:
  * - [no custom rights] - use only category/namespace rights
  * - [ACL:Page/XXX] - use custom ACL
  * - [Right 1] - use ACL template 1
  * - [Right 2] - use ACL template 2
  * - ...
  * ACL templates are detected using HACLSecurityDescriptor::isSinglePredefinedRightInclusion()
  * So if ACL:Page/XXX is really the inclusion of a single right template, it will be detected.
  */
 static function get($title, $nonreadable)
 {
     global $wgUser, $wgRequest, $haclgContLang, $wgContLang, $haclgHaloScriptPath, $wgScriptPath, $wgOut, $haclgOpenWikiAccess;
     self::addToolbarLinks($wgOut);
     $ns = $wgContLang->getNsText(HACL_NS_ACL);
     $canModify = true;
     $options = array(array('value' => 'unprotected', 'name' => wfMsg('hacl_toolbar_unprotected'), 'title' => wfMsg('hacl_toolbar_unprotected')));
     if (!is_object($title)) {
         $title = Title::newFromText($title);
     }
     if ($title->getNamespace() == HACL_NS_ACL) {
         return '';
     }
     // $found = "is current page SD in the list?"
     $found = false;
     // The list of ACLs which have effect on $title, but are not ACL:Page/$title by themselves
     // I.e. category and namespace ACLs
     $globalACL = array();
     $pageSDId = NULL;
     if ($title->exists()) {
         // Check SD modification rights
         $pageSDTitle = Title::newFromText(IACLDefinition::nameOfSD(IACL::PE_PAGE, $title));
         $pageSD = IACLDefinition::getSDForPE(IACL::PE_PAGE, $title->getArticleId());
         if ($pageSD) {
             $realPageSDId = $pageSDId = array($pageSD['pe_type'], $pageSD['pe_id']);
             $canModify = $pageSDTitle->userCan('edit');
             // Check if page SD is a single predefined right inclusion
             if ($pageSD['single_child']) {
                 $pageSDId = $pageSD['single_child'];
                 // But don't change $realPageSDId
             } else {
                 $found = true;
                 $options[] = array('current' => true, 'value' => implode('-', $pageSDId), 'name' => $pageSDTitle->getFullText(), 'title' => $pageSDTitle->getFullText());
             }
         } else {
             // Get protected categories this article belongs to (for hint)
             $categories = IACLStorage::get('Util')->getParentCategoryIDs($title->getArticleId());
             foreach ($categories as &$cat) {
                 $cat = array(IACL::PE_CATEGORY, $cat);
             }
             unset($cat);
             // prevent reference bugs
             $defs = IACLDefinition::select(array('pe' => $categories));
             foreach ($defs as $def) {
                 $globalACL[] = $def['def_title'];
             }
         }
     }
     // Add Quick ACLs
     $quickacl = IACLQuickacl::newForUserId($wgUser->getId());
     $default = $quickacl->default_pe_id;
     $hasQuickACL = false;
     foreach ($quickacl->getPEIds() as $def) {
         $hasQuickACL = true;
         $sdTitle = IACLDefinition::getSDTitle($def);
         if (!$sdTitle) {
             continue;
         }
         $option = array('value' => implode('-', $def), 'current' => $def == $pageSDId, 'name' => $sdTitle->getPrefixedText(), 'title' => $sdTitle->getPrefixedText());
         $found = $found || $option['current'];
         if ($default == $def) {
             if (!$title->exists()) {
                 // Select default option for new articles
                 $option['current'] = true;
             }
             // Always insert default SD as the second option
             array_splice($options, 1, 0, array($option));
         } else {
             $options[] = $option;
         }
     }
     // If page SD is not yet in the list, insert it as the second option
     if ($pageSDId && !$found) {
         $sdTitle = IACLDefinition::getSDTitle($pageSDId);
         array_splice($options, 1, 0, array(array('name' => $sdTitle->getPrefixedText(), 'value' => implode('-', $pageSDId), 'current' => true, 'title' => $sdTitle->getPrefixedText())));
     }
     // Alter selection using request data (hacl_protected_with)
     if ($canModify && ($st = $wgRequest->getVal('hacl_protected_with'))) {
         foreach ($options as &$o) {
             $o['current'] = $o['value'] == $st;
         }
         unset($o);
         // prevent reference bugs
     }
     $selectedIndex = false;
     foreach ($options as $i => $o) {
         if (!empty($o['current'])) {
             $selectedIndex = $i;
         }
     }
     // Check if page namespace has an ACL (for hint)
     if (!$pageSDId && !$globalACL) {
         $sdTitle = IACLDefinition::getSDTitle(array(IACL::PE_NAMESPACE, $title->getNamespace()));
         if ($sdTitle->exists()) {
             $globalACL[] = $sdTitle;
         }
     }
     if ($globalACL) {
         foreach ($globalACL as &$t) {
             if ($haclgOpenWikiAccess || $t->userCan('read')) {
                 $t = Xml::element('a', array('href' => $t->getLocalUrl(), 'target' => '_blank'), $t->getText());
             }
         }
         unset($t);
         // prevent reference bugs
         $globalACL = implode(', ', $globalACL);
     }
     // Check if the article does include any content
     $anyLinks = $embeddedToolbar = false;
     if ($title->exists()) {
         if (!$pageSDId) {
             $pageSDId = '';
         }
         $c = false;
         foreach ($wgRequest->getValues() as $k => $v) {
             if (substr($k, 0, 7) == 'sd_emb_' && $v !== "") {
                 $c = true;
                 break;
             }
         }
         if ($c) {
             // If there were any changes in the embedded content
             // toolbar, display it initially
             $embeddedToolbar = self::getEmbeddedHtml($title->getArticleId(), $realPageSDId[0], $realPageSDId[1]);
         } else {
             // Else only check for imagelinks/templatelinks existence
             $dbr = wfGetDB(DB_SLAVE);
             $res = $dbr->query($dbr->selectSQLText('imagelinks', '1', array('il_from' => $title->getArticleId()), __METHOD__, array('GROUP BY' => 'il_from')) . ' UNION ' . $dbr->selectSQLText('templatelinks', '1', array('tl_from' => $title->getArticleId()), __METHOD__, array('GROUP BY' => 'tl_from')), __METHOD__);
             $res = $res->fetchObject();
             if ($res) {
                 $anyLinks = true;
             }
         }
     }
     // Link to Quick ACL manage page
     $quick_acl_link = Title::newFromText('Special:IntraACL')->getLocalUrl(array('action' => 'quickaccess'));
     // Run template
     ob_start();
     require dirname(__FILE__) . '/../templates/HACL_Toolbar.tpl.php';
     $html = ob_get_contents();
     ob_end_clean();
     return $html;
 }
 /**
  * Displays full graph of IntraACL rights using Graphviz, in SVG format.
  * Does not reflect the right override method - just displays which rights apply
  * to different protected elements.
  *
  * SD -> (namespace = page cluster)
  * SD -> page
  * SD -> category -> each subcategory -> subcluster of a namespace
  * Included SD -> SD
  */
 public function html_rightgraph(&$q)
 {
     global $wgOut, $wgContLang;
     $patch = haclfDisableTitlePatch();
     // FIXME Special pages?
     // Select ALL SDs
     $titles = array();
     $defs = IACLDefinition::select(array('pe_type != ' . IACL::PE_GROUP));
     $cats = array();
     foreach ($defs as $def) {
         $titles[$def['key']] = $def['def_title'];
         if ($def['pe_type'] == IACL::PE_CATEGORY) {
             $cats[] = $def['pe_title'];
         }
         if ($def['pe_type'] == IACL::PE_CATEGORY || $def['pe_type'] == IACL::PE_PAGE) {
             $titles[$def['pe_id']] = $def['pe_title'];
         }
     }
     $cattitles = IACLStorage::get('Util')->getAllChildrenCategories($cats);
     $catkeys = array();
     // Fetch article IDs massively using LinkBatch
     $batch = new LinkBatch();
     foreach ($cattitles as $t) {
         $batch->addObj($t);
     }
     $batch->execute();
     foreach ($cattitles as $t) {
         $titles[$t->getArticleId()] = $t;
         $catkeys[$t->getDBkey()] = $t->getArticleId();
     }
     $catlinks = IACLStorage::get('Util')->getCategoryLinks(array_keys($catkeys));
     // Draw security descriptors
     $nodes = array();
     $edges = array();
     $ns_first = array();
     $cluster = array();
     foreach ($defs as $def) {
         if ($def['pe_type'] != IACL::PE_PAGE) {
             $nodes['sd' . $def['key']] = $def;
             if ($def['pe_type'] == IACL::PE_CATEGORY) {
                 $edges['sd' . $def['key']]['cat' . $def['pe_id']] = true;
                 $nodes['cat' . $def['pe_id']] = true;
                 $cluster['sd' . $def['key']] = "clusterns" . NS_CATEGORY;
             }
         } else {
             $nodes['pg' . $def['pe_id']] = true;
             $edges['sd' . $def['key']]['pg' . $def['pe_id']] = true;
             if (!isset($ns_first[$titles[$def['pe_id']]->getNamespace()])) {
                 $ns_first[$titles[$def['pe_id']]->getNamespace()] = 'pg' . $def['pe_id'];
             }
         }
     }
     // Group pages in category clusters within namespaces
     $cat_cluster = array();
     $cat_cluster[NS_CATEGORY][''] = array();
     foreach ($catlinks as $catkey => $cattitles) {
         $cattitle = $titles[$catkeys[$catkey]];
         $catid = $cattitle->getArticleId();
         foreach ($cattitles as $t) {
             $tns = $t->getNamespace();
             $tid = $t->getArticleId();
             if ($tns == NS_CATEGORY) {
                 $edges["cat{$catid}"]["cat{$tid}"] = true;
                 if (!isset($nodes["cat{$tid}"])) {
                     $nodes["cat{$tid}"] = true;
                 }
             } elseif (isset($nodes["pg{$tid}"])) {
                 if (!isset($cluster["pg{$tid}"])) {
                     $cluster["pg{$tid}"] = 'clustercat' . $tns . '_' . $catid;
                     if (!isset($cat_cluster[$tns][$catid])) {
                         $cat_cluster[$tns][$catid] = array();
                         $edges["cat{$catid}"]["pg{$tid}"] = 'lhead=clustercat' . $tns . '_' . $catid;
                     }
                 } else {
                     $edges["cat{$catid}"]["pg{$tid}"] = true;
                 }
             }
         }
     }
     // Set namespace clusters for non-grouped nodes
     foreach ($nodes as $n => &$attr) {
         if (substr($n, 0, 2) == 'pg' && !isset($cluster[$n])) {
             $cluster[$n] = 'clusterns' . $titles[substr($n, 2)]->getNamespace();
         } elseif (substr($n, 0, 3) == 'cat') {
             $cluster[$n] = 'clusterns' . NS_CATEGORY;
             if (!isset($ns_first[NS_CATEGORY])) {
                 $ns_first[NS_CATEGORY] = $n;
             }
         }
     }
     unset($attr);
     // prevent reference bugs
     // Group SDs in the same clusters as their PEs and draw namespace SD edges
     $sdbyid = array();
     foreach ($defs as $def) {
         if ($def['pe_type'] == IACL::PE_PAGE) {
             $cluster['sd' . $def['key']] = $cluster['pg' . $def['pe_id']];
             $sdbyid[$def['key']] = $def;
         } elseif ($def['pe_type'] == IACL::PE_NAMESPACE) {
             $cluster['sd' . $def['key']] = '';
             if (isset($ns_first[$def['pe_id']])) {
                 $k = $ns_first[$def['pe_id']];
             } else {
                 $k = 'etc' . $def['pe_id'];
                 $nodes[$k] = array('label' => '...', 'shape' => 'circle', 'href' => Title::newFromText('Special:Allpages')->getFullUrl(array('namespace' => $def['pe_id'])), 'tooltip' => "Click to see all pages in namespace " . $wgContLang->getNsText($def['pe_id']));
                 $cluster[$k] = "clusterns" . $def['pe_id'];
                 $ns_first[$def['pe_id']] = $k;
             }
             $edges['sd' . $def['key']][$k] = "lhead=clusterns" . $def['pe_id'];
         } elseif ($def['pe_type'] == IACL::PE_RIGHT) {
             $cluster['sd' . $def['key']] = '';
         }
     }
     // Draw right hierarchy
     $hier = array();
     foreach ($defs as $def) {
         foreach ($def['rules'] as $rules) {
             foreach ($rules as $rule) {
                 if ($rule['child_type'] != IACL::PE_USER && $rule['child_type'] != IACL::PE_GROUP && $rule['child_type'] != IACL::PE_ALL_USERS && $rule['child_type'] != IACL::PE_REG_USERS && $rule['actions'] & IACL::ACTION_INCLUDE_SD) {
                     $parent = $rule['pe_type'] . '-' . $rule['pe_id'];
                     // get_key
                     $child = $rule['child_type'] . '-' . $rule['child_id'];
                     // get_key
                     if (isset($sdbyid[$child]) && $sdbyid[$child]['pe_type'] == IACL::PE_PAGE) {
                         $nodes['sd' . $child] = $sdbyid[$child];
                     }
                     if (isset($sdbyid[$parent]) && $sdbyid[$parent]['pe_type'] == IACL::PE_PAGE) {
                         $nodes['sd' . $parent] = $sdbyid[$parent];
                     }
                     if (isset($nodes['sd' . $child]) && isset($nodes['sd' . $parent])) {
                         $edges['sd' . $child]['sd' . $parent] = true;
                     }
                 }
             }
         }
     }
     foreach ($cluster as $k => $cl) {
         if (isset($nodes[$k])) {
             if (preg_match('/clustercat(\\d+)_(\\d+)/', $cl, $m)) {
                 $cat_cluster[$m[1]][$m[2]][] = $k;
             } elseif (preg_match('/clusterns(\\d+)/', $cl, $m)) {
                 $cat_cluster[$m[1]][''][] = $k;
             } elseif ($cl === '') {
                 $cat_cluster[''][''][] = $k;
             }
         }
     }
     // Set node attributes
     $shapes = array('sd' => 'note', 'pg' => 'ellipse', 'cat' => 'folder');
     $colors = array('sd' . IACL::PE_PAGE => '#ffd0d0', 'sd' . IACL::PE_CATEGORY => '#ffff80', 'sd' . IACL::PE_RIGHT => '#90ff90', 'sd' . IACL::PE_NAMESPACE => '#c0c0ff', 'cat' => '#ffe0c0');
     foreach ($nodes as $n => $r) {
         if (is_array($r)) {
             continue;
         }
         preg_match('/([a-z]+)(\\d+(?:-\\d+)?)/', $n, $m);
         $type = $m[1];
         $id = $m[2];
         $nodes[$n] = array('shape' => $shapes[$type], 'label' => $titles[$id]->getPrefixedText(), 'href' => $titles[$id]->getFullUrl());
         if ($type != 'pg') {
             $type2 = $type;
             if ($type2 == 'sd') {
                 $type2 .= $r['pe_type'];
             }
             if (isset($colors[$type2])) {
                 $nodes[$n]['fillcolor'] = $colors[$type2];
             }
             $nodes[$n]['style'] = 'filled';
         }
     }
     if ($nodes) {
         // Draw clusters
         $graph = '';
         $ns_first[''] = '';
         foreach ($ns_first as $ns => $first) {
             if ($ns !== '') {
                 $graph .= "subgraph clusterns{$ns} {\n";
                 $graph .= "graph [label=\"Namespace " . ($ns ? $wgContLang->getNsText($ns) : 'Main') . "\", href=\"" . Title::newFromText('Special:Allpages')->getFullUrl(array('namespace' => $ns)) . "\"];\n";
             }
             if (isset($cat_cluster[$ns])) {
                 foreach ($cat_cluster[$ns] as $cat => $ks) {
                     if ($cat !== '') {
                         $graph .= "subgraph clustercat{$ns}_{$cat} {\n";
                         $graph .= 'graph [label="' . $titles[$cat]->getPrefixedText() . '", href="' . $titles[$cat]->getFullUrl() . '"];' . "\n";
                     }
                     foreach ($ks as $nodename) {
                         $graph .= "\"{$nodename}\" [" . self::attrstring($nodes[$nodename]) . "];\n";
                     }
                     if ($cat !== '') {
                         $graph .= "}\n";
                     }
                 }
             }
             if ($ns !== '') {
                 $graph .= "}\n";
             }
         }
         // Draw edges
         foreach ($edges as $from => $to) {
             if (isset($nodes[$from])) {
                 foreach ($to as $id => $attr) {
                     if ($attr !== true) {
                         $attr .= ', ';
                     } else {
                         $attr = '';
                     }
                     $attr .= self::attrstring(array('href' => $nodes[$from]['href'], 'tooltip' => $nodes[$from]['label']));
                     $graph .= "\"{$from}\" -> \"{$id}\" [{$attr}];\n";
                 }
             }
         }
         // Render the graph
         $graph = "<graphviz>\ndigraph G {\nedge [penwidth=2 color=blue];\nsplines=polyline;\n" . "overlap=false;\nranksep=2;\nrankdir=LR;\ncompound=true;\n{$graph}\n}\n</graphviz>\n";
         $wgOut->addWikiText($graph);
         $wgOut->addHTML("<pre>{$graph}</pre>");
     } else {
         $wgOut->addWikiText(wfMsg('hacl_acllist_empty'));
     }
     haclfRestoreTitlePatch($patch);
 }