Difference between revisions of "Extension:SimpleSecurity2.1.php"

From Organic Design wiki
Line 42: Line 42:
 
if (preg_match_all('/\\[{2}\\s*security\\s*:\\s*([^\\]]+?)\\s*\\|\\s*([^\\]]*)\\s*\\]{2}/i',$text->fetchContent(0,false,false),$match,PREG_SET_ORDER)) {
 
if (preg_match_all('/\\[{2}\\s*security\\s*:\\s*([^\\]]+?)\\s*\\|\\s*([^\\]]*)\\s*\\]{2}/i',$text->fetchContent(0,false,false),$match,PREG_SET_ORDER)) {
 
$seclinks = array_merge($match,$seclinks);
 
$seclinks = array_merge($match,$seclinks);
addSecurityInfo($match,$secinfo,"this rule is inherited from <a href='/$cat'>$cat</a>");
+
addSecurityInfo($match,$secinfo,"this rule is inherited from [[:$cat]]");
 
}
 
}
 
}
 
}
Line 96: Line 96:
 
}
 
}
  
# Remove the security links before wiki-parsing
+
# Remove the security links and append security info before wiki-parsing
$wgHooks['ParserBeforeStrip'][] = 'removeSecurityLinks';
+
$wgHooks['ParserBeforeStrip'][] = 'securityBeforeParsing';
function removeSecurityLinks(&$parser,&$text,&$strip_state) {
+
function securityBeforeParsing(&$parser,&$text,&$strip_state) {
global $deny;
+
global $deny,$secinfo,$action,$wgHooks;
 
if ($deny) {
 
if ($deny) {
 
$text = new Article(Title::newFromText('Action not permitted'));
 
$text = new Article(Title::newFromText('Action not permitted'));
Line 106: Line 106:
 
}
 
}
 
else $text = preg_replace("/\\[{2}\\s*:?security\\s*:[^\\]]+?\\]{2}[\r\n]?/i",'',$text);
 
else $text = preg_replace("/\\[{2}\\s*:?security\\s*:[^\\]]+?\\]{2}[\r\n]?/i",'',$text);
 +
if ($secinfo && 0 == $GLOBALS['rsi-done']++ && $action == 'view') $text .= "\n{{Security info|1=\n$secinfo\n}}";
 
return true;
 
return true;
 
}
 
}
  
# Security information functions
+
# Add security information item
if ($secinfo) $wgHooks['ParserAfterTidy'][] = 'renderSecurityInfo';
 
function renderSecurityInfo(&$parser,&$text) {
 
global $secinfo,$action,$wgHooks;
 
if ($GLOBALS['rsi-done']++) return;
 
if ($action == 'view') $text .= "\n<br><table width=100% style='border:1px solid #aaa'><tr><td valign=top><h4>There are security restrictions on this article</h4><ul>$secinfo</ul><td align=right valign=middle><img src='/wiki/images/c/c1/Padlock.png'/></table>";
 
return true;
 
}
 
 
function addSecurityInfo(&$links,&$info,$comment='') {
 
function addSecurityInfo(&$links,&$info,$comment='') {
if ($comment) $comment = " &nbsp; <i>($comment)</i>";
+
if ($comment) $comment = " &nbsp; ''($comment)''";
 
foreach ($links as $link) {
 
foreach ($links as $link) {
 
$a = $link[1] == '*' ? 'Every action' : ucfirst($link[1]);
 
$a = $link[1] == '*' ? 'Every action' : ucfirst($link[1]);
 
$b = $link[2] == '*' ? 'anybody' : $link[2];
 
$b = $link[2] == '*' ? 'anybody' : $link[2];
$info .= "<li><b>$a</b> requires the user to be <b>$b</b>$comment</li>";
+
$info .= "*'''$a''' requires the user to be '''$b'''$comment\n";
 
}
 
}
 
}
 
}
 
?>
 
?>

Revision as of 01:03, 3 March 2007

<?

  1. Simple security extension
  2. - See [[MediaWiki Security]] article for installation and usage details
  3. - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
  4. - Needs apache's mod-rewrite for security on images, see code comments below
  1. Handle moves

$a = $action == 'submit' ? 'edit' : strtolower($action); if ($title=='Special:Movepage' && $action=='submit') { $a = 'move'; $t = $wgRequest->getText('wpOldTitle',$wgRequest->getVal('target')); } else $t = $title;

$groups = $wgUser->getGroups(); foreach($groups as $k => $v) $groups[$k] = strtolower($v); if ($t) {

# Handle security on files (needs apache mod-rewrite) # - mod-rewrite redirects /wiki/images/... requests to article title Download/image-path... # - Use the following rewrite condition and rule (adjust to your wiki path if necessary) # RewriteCond %{REQUEST_URI} ^/wiki/images/.+ # RewriteRule ^/wiki/images/(.+) /wiki/index.php/Download/$1 [L] if (ereg('^Download/(.+)/([^/]+)$',$t,$m)) { $path = $m[1]; $file = $image = $m[2]; if (ereg('^thumb/.+/([^/]+)$',$path,$m)) $image = $m[1]; $t = "Image:$image"; } else $file = ;

# Get security links from this article $secinfo = ; $text = new Article(Title::newFromText($t)); $text = $text->fetchContent(0,false,false); if (preg_match_all('/\\[{2}\\s*:?security\\s*:\\s*([^\\]]+?)\\s*\\|\\s*([^\\]]*)\\s*\\]{2}/i',$text,$seclinks,PREG_SET_ORDER)) addSecurityInfo($seclinks,$secinfo); else $seclinks = array();

# Get security links from article's categories preg_match_all('/\\[{2}category:(.+?)(\\|.+?)?\\]]/i',$text,$cats); foreach ($cats[1] as $i => $cat) { $cats[1][$i] = $cat = 'Category:'.ucfirst($cat); if (is_object($text = new Article(Title::newFromText($cat)))) { if (preg_match_all('/\\[{2}\\s*security\\s*:\\s*([^\\]]+?)\\s*\\|\\s*([^\\]]*)\\s*\\]{2}/i',$text->fetchContent(0,false,false),$match,PREG_SET_ORDER)) { $seclinks = array_merge($match,$seclinks); addSecurityInfo($match,$secinfo,"this rule is inherited from $cat"); } } }

# Resolve permission for this action from the extracted security links $security = ; foreach ($seclinks as $link) { if ($link[2]==) $link[2] = 'sysop'; $actions = preg_split("/\\s*,\\s*/",strtolower($link[1])); if (in_array($a,$actions)) $security = $link[2]; if (in_array('*',$actions) && ($security == )) $security = $link[2]; }

# Validate extracted security against this user/groups $deny = false; if ($security && !in_array('sysop',$groups) && !in_array('director',$groups)) { $security = preg_split("/\\s*,\\s*/",$security); if (!in_array('*',$security)) { $groups[] = ucwords($wgUser->mName); if (count(array_intersect($groups,$security))==0) { $action = 'view'; $deny = true; } } } if ($file) { # Log the download event if any security on file if ($secinfo) { $user = $wgUser->mName; if ($deny) $entry = "User:$user was denied access to \"$file\""; else $entry = "User:$user accessed \"$file\""; $ts = $GLOBALS['wgLang']->timeanddate(wfTimestampNow(),true); $la = new Article(Title::newFromText('Download log')); $log = "{{Log item". "|ts=$ts". "|entry=$entry". "|ip=".$_SERVER['REMOTE_ADDR']. "|ua=".$_SERVER['HTTP_USER_AGENT']. "|cookie=".$_SERVER['HTTP_COOKIE']. "|qs=".$_SERVER['QUERY_STRING']. "}}\n"; $la->quickEdit($log.$la->fetchContent(0,false,false)); } # Return the file to the client if security validates if ($deny) $title = $t; else { header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"$file\""); @readfile("$wgUploadDirectory/$path/$file"); die; } } }

  1. Remove the security links and append security info before wiki-parsing

$wgHooks['ParserBeforeStrip'][] = 'securityBeforeParsing'; function securityBeforeParsing(&$parser,&$text,&$strip_state) { global $deny,$secinfo,$action,$wgHooks; if ($deny) { $text = new Article(Title::newFromText('Action not permitted')); $text = $text->fetchContent(0,false,false); $deny = false; } else $text = preg_replace("/\\[{2}\\s*:?security\\s*:[^\\]]+?\\]{2}[\r\n]?/i",,$text); if ($secinfo && 0 == $GLOBALS['rsi-done']++ && $action == 'view') $text .= "\n

Padlock.svg

There are security restrictions on this article (for information about this extension, click here)

\n$secinfo\n

";

return true; }

  1. Add security information item

function addSecurityInfo(&$links,&$info,$comment=) { if ($comment) $comment = "   ($comment)"; foreach ($links as $link) { $a = $link[1] == '*' ? 'Every action' : ucfirst($link[1]); $b = $link[2] == '*' ? 'anybody' : $link[2]; $info .= "*$a requires the user to be $b$comment\n"; } } ?>