[ Index ] |
|
Code source de DokuWiki 2006-11-06 |
1 <?php 2 /** 3 * ACL administration functions 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Frank Schubert <frank@schokilade.de> 7 */ 8 // must be run within Dokuwiki 9 if(!defined('DOKU_INC')) die(); 10 11 if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 12 require_once (DOKU_PLUGIN.'admin.php'); 13 14 /** 15 * All DokuWiki plugins to extend the admin function 16 * need to inherit from this class 17 */ 18 class admin_plugin_acl extends DokuWiki_Admin_Plugin { 19 20 21 function admin_plugin_acl(){ 22 $this->setupLocale(); 23 } 24 25 26 27 /** 28 * return some info 29 */ 30 function getInfo(){ 31 return array( 32 'author' => 'Frank Schubert', 33 'email' => 'frank@schokilade.de', 34 'date' => '2005-08-08', 35 'name' => 'ACL', 36 'desc' => 'Manage Page Access Control Lists', 37 'url' => 'http://wiki.splitbrain.org/wiki:acl', 38 ); 39 } 40 41 /** 42 * return prompt for admin menu 43 */ 44 function getMenuText($language) { 45 return $this->lang['admin_acl']; 46 } 47 48 /** 49 * return sort order for position in admin menu 50 */ 51 function getMenuSort() { 52 return 1; 53 } 54 55 /** 56 * handle user request 57 */ 58 function handle() { 59 global $AUTH_ACL; 60 61 $cmd = $_REQUEST['acl_cmd']; 62 $scope = $_REQUEST['acl_scope']; 63 $type = $_REQUEST['acl_type']; 64 $user = $_REQUEST['acl_user']; 65 $perm = $_REQUEST['acl_perm']; 66 67 if(is_array($perm)){ 68 //use the maximum 69 sort($perm); 70 $perm = array_pop($perm); 71 }else{ 72 $perm = 0; 73 } 74 75 //sanitize 76 $user = auth_nameencode($user); 77 if($type == '@') $user = '@'.$user; 78 if($user == '@all') $user = '@ALL'; //special group! (now case insensitive) 79 $perm = (int) $perm; 80 if($perm > AUTH_DELETE) $perm = AUTH_DELETE; 81 //FIXME sanitize scope!!! 82 83 //nothing to do? 84 if(empty($cmd) || empty($scope) || empty($user)) return; 85 86 87 if($cmd == 'save'){ 88 $this->admin_acl_del($scope, $user); 89 $this->admin_acl_add($scope, $user, $perm); 90 }elseif($cmd == 'delete'){ 91 $this->admin_acl_del($scope, $user); 92 } 93 94 // reload ACL config 95 $AUTH_ACL = file(DOKU_CONF.'acl.auth.php'); 96 } 97 98 /** 99 * ACL Output function 100 * 101 * print a table with all significant permissions for the 102 * current id 103 * 104 * @author Frank Schubert <frank@schokilade.de> 105 * @author Andreas Gohr <andi@splitbrain.org> 106 */ 107 function html() { 108 global $ID; 109 110 print $this->locale_xhtml('intro'); 111 112 ptln('<div id="acl__manager">'); 113 ptln('<table class="inline">'); 114 115 //new 116 $this->admin_acl_html_new(); 117 118 //current config 119 $acls = $this->get_acl_config($ID); 120 foreach ($acls as $id => $acl){ 121 $this->admin_acl_html_current($id,$acl); 122 } 123 124 ptln('</table>'); 125 ptln('</div>'); 126 } 127 128 129 /** 130 * Get matching ACL lines for a page 131 * 132 * $ID is pagename, reads matching lines from $AUTH_ACL, 133 * also reads acls from namespace 134 * returns multi-array with key=pagename and value=array(user, acl) 135 * 136 * @todo Fix comment to make sense 137 * @todo should this moved to auth.php? 138 * @todo can this be combined with auth_aclcheck to avoid duplicate code? 139 * @author Frank Schubert <frank@schokilade.de> 140 */ 141 function get_acl_config($id){ 142 global $AUTH_ACL; 143 144 $acl_config=array(); 145 146 // match exact name 147 $matches = preg_grep('/^'.$id.'\s+.*/',$AUTH_ACL); 148 if(count($matches)){ 149 foreach($matches as $match){ 150 $match = preg_replace('/#.*$/','',$match); //ignore comments 151 $acl = preg_split('/\s+/',$match); 152 //0 is pagename, 1 is user, 2 is acl 153 $acl_config[$acl[0]][] = array( 'name' => $acl[1], 'perm' => $acl[2]); 154 } 155 } 156 157 $specific_found=array(); 158 // match ns 159 while(($id=getNS($id)) !== false){ 160 $matches = preg_grep('/^'.$id.':\*\s+.*/',$AUTH_ACL); 161 if(count($matches)){ 162 foreach($matches as $match){ 163 $match = preg_replace('/#.*$/','',$match); //ignore comments 164 $acl = preg_split('/\s+/',$match); 165 //0 is pagename, 1 is user, 2 is acl 166 $acl_config[$acl[0]][] = array( 'name' => $acl[1], 'perm' => $acl[2]); 167 $specific_found[]=$acl[1]; 168 } 169 } 170 } 171 172 //include *-config 173 $matches = preg_grep('/^\*\s+.*/',$AUTH_ACL); 174 if(count($matches)){ 175 foreach($matches as $match){ 176 $match = preg_replace('/#.*$/','',$match); //ignore comments 177 $acl = preg_split('/\s+/',$match); 178 // only include * for this user if not already found in ns 179 if(!in_array($acl[1], $specific_found)){ 180 //0 is pagename, 1 is user, 2 is acl 181 $acl_config[$acl[0]][] = array( 'name' => $acl[1], 'perm' => $acl[2]); 182 } 183 } 184 } 185 186 //sort 187 //FIXME: better sort algo: first sort by key, then sort by first value 188 krsort($acl_config, SORT_STRING); 189 190 return($acl_config); 191 } 192 193 194 /** 195 * adds new acl-entry to conf/acl.auth.php 196 * 197 * @author Frank Schubert <frank@schokilade.de> 198 */ 199 function admin_acl_add($acl_scope, $acl_user, $acl_level){ 200 $acl_config = join("",file(DOKU_CONF.'acl.auth.php')); 201 202 // max level for pagenames is edit 203 if(strpos($acl_scope,'*') === false) { 204 if($acl_level > AUTH_EDIT) $acl_level = AUTH_EDIT; 205 } 206 207 $new_acl = "$acl_scope\t$acl_user\t$acl_level\n"; 208 209 $new_config = $acl_config.$new_acl; 210 211 return io_saveFile(DOKU_CONF.'acl.auth.php', $new_config); 212 } 213 214 /** 215 * remove acl-entry from conf/acl.auth.php 216 * 217 * @author Frank Schubert <frank@schokilade.de> 218 */ 219 function admin_acl_del($acl_scope, $acl_user){ 220 $acl_config = file(DOKU_CONF.'acl.auth.php'); 221 222 $acl_pattern = '^'.preg_quote($acl_scope,'/').'\s+'.$acl_user.'\s+[0-8].*$'; 223 224 // save all non!-matching #FIXME invert is available from 4.2.0 only! 225 $new_config = preg_grep("/$acl_pattern/", $acl_config, PREG_GREP_INVERT); 226 227 return io_saveFile(DOKU_CONF.'acl.auth.php', join('',$new_config)); 228 } 229 230 // --- HTML OUTPUT FUNCTIONS BELOW --- // 231 232 /** 233 * print tablerows with the current permissions for one id 234 * 235 * @author Frank Schubert <frank@schokilade.de> 236 * @author Andreas Gohr <andi@splitbrain.org> 237 */ 238 function admin_acl_html_dropdown($id){ 239 $cur = $id; 240 $ret = ''; 241 $opt = array(); 242 243 //prepare all options 244 245 // current page 246 $opt[] = array('key'=> $id, 'val'=> $id.' ('.$this->lang['page'].')'); 247 248 // additional namespaces 249 while(($id=getNS($id)) !== false){ 250 $opt[] = array('key'=> $id.':*', 'val'=> $id.':* ('.$this->lang['namespace'].')'); 251 } 252 253 // the top namespace 254 $opt[] = array('key'=> '*', 'val'=> '* ('.$this->lang['namespace'].')'); 255 256 // set sel on second entry (current namespace) 257 $opt[1]['sel'] = ' selected="selected"'; 258 259 // flip options 260 $opt = array_reverse($opt); 261 262 // create HTML 263 $att = array( 'name' => 'acl_scope', 264 'class' => 'edit', 265 'title' => $this->lang['page'].'/'.$this->lang['namespace']); 266 $ret .= '<select '.html_attbuild($att).'>'; 267 foreach($opt as $o){ 268 $ret .= '<option value="'.$o['key'].'"'.$o['sel'].'>'.$o['val'].'</option>'; 269 } 270 $ret .= '</select>'; 271 272 return $ret; 273 } 274 275 /** 276 * print tablerows with the current permissions for one id 277 * 278 * @author Frank Schubert <frank@schokilade.de> 279 * @author Andreas Gohr <andi@splitbrain.org> 280 */ 281 function admin_acl_html_new(){ 282 global $ID; 283 global $lang; 284 285 // table headers 286 ptln('<tr>',2); 287 ptln(' <th class="leftalign" colspan="3">'.$this->lang['acl_new'].'</th>',2); 288 ptln('</tr>',2); 289 290 ptln('<tr>',2); 291 292 ptln('<td class="centeralign" colspan="3">',4); 293 294 ptln(' <form method="post" action="'.wl($ID).'"><div class="no">',4); 295 ptln(' <input type="hidden" name="do" value="admin" />',4); 296 ptln(' <input type="hidden" name="page" value="acl" />',4); 297 ptln(' <input type="hidden" name="acl_cmd" value="save" />',4); 298 299 //scope select 300 ptln($this->lang['acl_perms'],4); 301 ptln($this->admin_acl_html_dropdown($ID),4); 302 303 $att = array( 'name' => 'acl_type', 304 'class' => 'edit', 305 'title' => $this->lang['acl_user'].'/'.$this->lang['acl_group']); 306 ptln(' <select '.html_attbuild($att).'>',4); 307 ptln(' <option value="@">'.$this->lang['acl_group'].'</option>',4); 308 ptln(' <option value="">'.$this->lang['acl_user'].'</option>',4); 309 ptln(' </select>',4); 310 311 $att = array( 'name' => 'acl_user', 312 'type' => 'text', 313 'class' => 'edit', 314 'title' => $this->lang['acl_user'].'/'.$this->lang['acl_group']); 315 ptln(' <input '.html_attbuild($att).' />',4); 316 ptln(' <br />'); 317 318 ptln( $this->admin_acl_html_checkboxes(0,false),8); 319 320 ptln(' <input type="submit" class="button" value="'.$lang['btn_save'].'" />',4); 321 ptln(' </div></form>'); 322 ptln('</td>',4); 323 ptln('</tr>',2); 324 } 325 326 /** 327 * print tablerows with the current permissions for one id 328 * 329 * @author Frank Schubert <frank@schokilade.de> 330 * @author Andreas Gohr <andi@splitbrain.org> 331 */ 332 function admin_acl_html_current($id,$permissions){ 333 global $lang; 334 global $ID; 335 336 //is it a page? 337 if(substr($id,-1) == '*'){ 338 $ispage = false; 339 }else{ 340 $ispage = true; 341 } 342 343 // table headers 344 ptln(' <tr>'); 345 ptln(' <th class="leftalign" colspan="3">'); 346 ptln($this->lang['acl_perms'],6); 347 if($ispage){ 348 ptln($this->lang['page'],6); 349 }else{ 350 ptln($this->lang['namespace'],6); 351 } 352 ptln('<em>'.$id.'</em>',6); 353 ptln(' </th>'); 354 ptln(' </tr>'); 355 356 sort($permissions); 357 358 foreach ($permissions as $conf){ 359 //userfriendly group/user display 360 $conf['name'] = rawurldecode($conf['name']); 361 if(substr($conf['name'],0,1)=="@"){ 362 $group = $this->lang['acl_group']; 363 $name = substr($conf['name'],1); 364 $type = '@'; 365 }else{ 366 $group = $this->lang['acl_user']; 367 $name = $conf['name']; 368 $type = ''; 369 } 370 371 ptln('<tr>',2); 372 ptln('<td class="leftalign">'.htmlspecialchars($group.' '.$name).'</td>',4); 373 374 // update form 375 ptln('<td class="centeralign">',4); 376 ptln(' <form method="post" action="'.wl($ID).'"><div class="no">',4); 377 ptln(' <input type="hidden" name="do" value="admin" />',4); 378 ptln(' <input type="hidden" name="page" value="acl" />',4); 379 ptln(' <input type="hidden" name="acl_cmd" value="save" />',4); 380 ptln(' <input type="hidden" name="acl_scope" value="'.formtext($id).'" />',4); 381 ptln(' <input type="hidden" name="acl_type" value="'.$type.'" />',4); 382 ptln(' <input type="hidden" name="acl_user" value="'.formtext($name).'" />',4); 383 ptln( $this->admin_acl_html_checkboxes($conf['perm'],$ispage),8); 384 ptln(' <input type="submit" class="button" value="'.$lang['btn_update'].'" />',4); 385 ptln(' </div></form>'); 386 ptln('</td>',4); 387 388 389 // deletion form 390 391 $ask = $lang['del_confirm'].'\\n'; 392 $ask .= $id.' '.$conf['name'].' '.$conf['perm']; 393 ptln('<td class="centeralign">',4); 394 ptln(' <form method="post" action="'.wl($ID).'" onsubmit="return confirm(\''.str_replace('\\\\n','\\n',addslashes($ask)).'\')"><div class="no">',4); 395 ptln(' <input type="hidden" name="do" value="admin" />',4); 396 ptln(' <input type="hidden" name="page" value="acl" />',4); 397 ptln(' <input type="hidden" name="acl_cmd" value="delete" />',4); 398 ptln(' <input type="hidden" name="acl_scope" value="'.formtext($id).'" />',4); 399 ptln(' <input type="hidden" name="acl_type" value="'.$type.'" />',4); 400 ptln(' <input type="hidden" name="acl_user" value="'.formtext($name).'" />',4); 401 ptln(' <input type="submit" class="button" value="'.$lang['btn_delete'].'" />',4); 402 ptln(' </div></form>',4); 403 ptln('</td>',4); 404 405 ptln('</tr>',2); 406 } 407 408 } 409 410 411 /** 412 * print the permission checkboxes 413 * 414 * @author Frank Schubert <frank@schokilade.de> 415 * @author Andreas Gohr <andi@splitbrain.org> 416 */ 417 function admin_acl_html_checkboxes($setperm,$ispage){ 418 global $lang; 419 420 static $label = 0; //number labels 421 $ret = ''; 422 423 foreach(array(AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD,AUTH_DELETE) as $perm){ 424 $label += 1; 425 426 //general checkbox attributes 427 $atts = array( 'type' => 'checkbox', 428 'id' => 'pbox'.$label, 429 'name' => 'acl_perm[]', 430 'value' => $perm ); 431 //dynamic attributes 432 if($setperm >= $perm) $atts['checked'] = 'checked'; 433 # if($perm > AUTH_READ) $atts['onchange'] = #FIXME JS to autoadd lower perms 434 if($ispage && $perm > AUTH_EDIT) $atts['disabled'] = 'disabled'; 435 436 //build code 437 $ret .= '<label for="pbox'.$label.'" title="'.$this->lang['acl_perm'.$perm].'">'; 438 $ret .= '<input '.html_attbuild($atts).' />'; 439 $ret .= $this->lang['acl_perm'.$perm]; 440 $ret .= "</label>\n"; 441 } 442 return $ret; 443 } 444 445 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Tue Apr 3 20:47:31 2007 | par Balluche grâce à PHPXref 0.7 |