1<?php
2#
3# DistributedACL Action Plugin
4#
5# License:    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6# Author:     Dael Maselli <Dael.Maselli@gmail.com>
7#
8
9if(!defined('DOKU_INC')) die();
10if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
11require_once(DOKU_PLUGIN.'action.php');
12
13class action_plugin_distributedACL extends DokuWiki_Action_Plugin {
14
15  function getInfo(){
16    return array(
17		 'author' => 'Dael Maselli',
18		 'email'  => 'Dael.Maselli@gmail.com',
19		 'date'   => rtrim(io_readFile(DOKU_PLUGIN.'distributedACL/VERSION.txt')),
20		 'name'   => 'DistributedACL (action plugin component)',
21		 'desc'   => 'DistributedACL action functions.',
22		 'url'    => 'http://wiki.splitbrain.org/plugin:distributedACL',
23		 );
24  }
25
26  function register(Doku_Event_Handler $controller) {
27    $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE',  $this, '_doacl');
28  }
29
30  function _doacl(&$event, $param) {
31
32    global $conf;
33
34    $ACLNAMESPACE = "acl:";
35    $MODE = 2;
36
37    #$ofh = fopen( "/tmp/debug", "w" );
38    #fputs ( $ofh, $event->data[1] . " " . $event->data[2] . " " . $event->data[3] . " " . "OK\n" );
39    #fclose ( $ofh );
40
41    if ( !$event->data[3] && preg_match( "/^$ACLNAMESPACE(.+)$/", $event->data[1], $c ) ) {
42
43      $aclfor     = $c[1] . ":";
44      $pagename = $event->data[2];
45      if ( $pagename == $conf['start'] ) {
46	$pagename = "*";
47      }
48      $aclfor .= $pagename;
49
50      $aclfile    = DOKU_INC . "conf/acl.auth.php";
51
52      $permarr      = array( "N" => 0, "R" => 1, "E" => 2, "C" => 4, "U" => 8, "D" => 16, "W" => 16 );
53
54      $newconfacl  = "";
55      $newwikipage = "";
56
57      $aclfh = fopen( $aclfile, "r+" ) or die("Error opening '$aclfile' for writing");
58      flock( $aclfh, LOCK_EX );
59
60      while ( $confaclline = fgets( $aclfh ) ) {
61
62	if ( $MODE == 1 ) {
63	  $matchexclude = '/[\s\t]+# distributedACL autogenerated for '. str_replace  ( "*", "\*", $aclfor ) .' #\s*$/';
64	} else {
65	  $matchexclude = '/^\s*'. str_replace  ( "*", "\*", $aclfor ) .'[\s\t]+/';
66	}
67
68	if ( ! preg_match( $matchexclude, $confaclline ) ) {
69
70	  $newconfacl .= $confaclline;
71
72	}
73
74      }
75
76      if ( ! preg_match( "/^#\s+acl.auth.php/", $newconfacl ) ) {
77	flock( $aclfh, LOCK_UN);
78	fclose( $aclfh );
79	return;
80      }
81
82      foreach ( explode( "\n", $event->data[0][1] ) as $line ) {
83
84	$line = preg_replace( "/\#.*$/", "", $line );
85
86	if ( preg_match( "/^\s*([^:]+)\s*:\s*(\S+)/", $line, $c ) && isset($permarr[$c[1]]) ) {
87
88	  $u = $c[2];
89	  $user = "";
90	  for ($j=0; $j < strlen($u); $j++) {
91	    if ( ! preg_match( "/[a-zA-Z0-9]/", $u[$j] ) ) {
92	      $user .= "%".dechex(ord( $u[$j] ));
93	    } else {
94	      $user .= $u[$j];
95	    }
96	  }
97
98	  $user = preg_replace( "/^%40/", "@", $user );
99
100	  $perm = $permarr[$c[1]];
101
102	  $newconfacl  .= sprintf ( "%-30s %-40s %3d %s",  $aclfor, $user, $perm, "# distributedACL autogenerated for $aclfor #\n" );
103
104	  $newwikipage .= "  $c[1]:$c[2]\n";
105
106	} else {
107	  $newwikipage .= $line . "\n";
108	}
109
110      }
111
112      $event->data[0][1] = $newwikipage;
113
114      rewind( $aclfh );
115      ftruncate( $aclfh, 0 );
116
117      fputs( $aclfh, $newconfacl );
118
119      flock( $aclfh, LOCK_UN);
120      fclose( $aclfh ) or die("Error closing '$aclfile'.");
121
122    }
123
124  }
125
126}
127