1<?php
2/**
3 * Setting up the Shibboleth authentication admin plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Yoann Lecuyer <yoann.lecuyer AT cru.fr>
7 * @author     Dominique Launay <dominique.launay AT cru.fr>
8 * @author     Olivier Salaün <olivier.salaun AT cru.fr>
9 */
10
11if(!defined('DOKU')) define('DOKU',realpath(dirname(__FILE__).'/../../../').'/');
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU.'lib/plugins/');
13require_once(DOKU_PLUGIN.'admin.php');
14if(!defined('DOKU_CONFIGLANG')) define('DOKU_CONFIGLANG', realpath(dirname(__FILE__).'/../config/lang/'));
15if(!defined('DOKU_SHIBBOLETHLANG')) define('DOKU_SHIBBOLETHLANG', realpath(dirname(__FILE__) .'/lang/'));
16
17
18
19
20/**
21 * All DokuWiki plugins to extend the admin function
22 * need to inherit from this class
23 */
24class admin_plugin_shibbolethauth extends DokuWiki_Admin_Plugin {
25
26  //global $conf;
27  /**
28   * Return some info about the plugin
29   *
30   **/
31  function getInfo(){
32
33      return array(
34		   'author' => 'Yoann Lecuyer',
35		   'email'  => 'yoann.lecuyer@cru.fr',
36		   'date'   => '2006/07/03',
37		   'name'   => 'shibbolethauth',
38		   'desc'   => 'Plugin to grant authentication with Shibboleth',
39		   );
40  }
41
42
43  /**
44   * handle user request
45   */
46  function handle() {
47    if ($_REQUEST['action_'] == 'install') {
48      $this->install();
49    }
50    elseif ($_REQUEST['action_'] == 'uninstall') {
51      $this->uninstall();
52    }
53  }
54
55
56  /**
57   * Output appropriate html
58   *
59   */
60  function html() {
61    global $ID;
62    global $conf;
63    // Display the text about this plugin from "shibbolethauth/lang/$lang/intro.txt"
64    print $this->locale_xhtml('intro');
65    ptln('<div id="shibboleth__manager">');
66
67    // If not installed, it displays the install menu
68    // if installed, it displays the uninstall menu
69    ptln('<form action_="'.wl($ID).'" method="post">');
70    if($this->is_installed()) {
71      if($this->is_used()) {
72	ptln('<p> ' .$this->getLang('is_used'). '</p>');
73      }
74      else {
75	ptln('<p> '.$this->getLang('uninstall') .' </p>');
76	ptln('<p> <input type="hidden" name="action_" value="uninstall" />');
77	ptln('    <input type="submit" name="submit" class="button" value="'.$this->getLang('btn_uninstall').'" /> </p>');
78      }
79    }
80    else {
81      ptln('<p> '.$this->getLang('install') .' </p>');
82      ptln('<p> <input type="hidden" name="action_" value="install" />');
83      ptln('    <input type="submit" name="submit" class="button" value="'.$this->getLang('btn_install').'" /> </p>');
84    }
85    ptln('  <p> <input type="hidden" name="do"     value="admin" />');
86    ptln('      <input type="hidden" name="page"   value="shibbolethauth" /> </p>');
87    ptln('</form>');
88    ptln('</div>');
89  }
90
91  /**********************
92   * Check if the plugin
93   * is installed
94   *
95   **********************/
96  function is_installed() {
97    //Check if the file shibboleth.class.php is in the authenticafion methods directory
98    if (!file_exists(DOKU . '/inc/auth/shibboleth.class.php')) {
99      return false;
100    }
101
102
103    return true;
104  }
105
106
107  /**********************
108   * Check if the plugin
109   * is currently used
110   *
111   **********************/
112  function is_used() {
113    //Check if the authentication mode is Shibboleth
114    if (!$local_handle = fopen(DOKU . '/conf/local.php', 'r')) {
115      return true;
116    }
117    while (!feof($local_handle)) {
118      $line = fgets($local_handle, 1000);
119      if(preg_match('!\$conf\[\'authtype\'\] *= *.*!', $line)) {
120	$value = $line;
121      }
122      if(preg_match('!\$conf\[\'authtype\'\] *= *[\'"]shibboleth[\'"]!', $value)) return true;
123    }
124    fclose($local_handle);
125    return false;
126  }
127
128
129  /**********************
130   * Install the plugin
131   *
132   **********************/
133  function install() {
134    // Check if the plugin files are already there, and delete it if it's the case
135    if (file_exists(DOKU . '/inc/auth/shibboleth.class.php')) {
136      if(!unlink(DOKU . '/inc/auth/shibboleth.class.php')) return false;
137    }
138    // Copy the new ones
139    if (!copy(DOKU .'/lib/plugins/shibbolethauth/files/shibboleth.class.php', DOKU .'/inc/auth/shibboleth.class.php')) return false;
140
141
142    // Install localization for the config plugin
143    return($this->install_langconf());
144
145    return(true);
146  }
147
148
149  /***********************
150   * Uninstall the plugin
151   *
152   ***********************/
153  function uninstall() {
154     // Check if the plugin files are already there, and delete it if it's the case
155    if (file_exists(DOKU . '/inc/auth/shibboleth.class.php')) {
156      if(!unlink(DOKU . '/inc/auth/shibboleth.class.php')) return false;
157    }
158
159    // Uninstall localization for the config plugin
160    return($this->uninstall_langconf());
161  }
162
163
164  /**************************
165   * Install the language
166   * phrases related to this
167   * plugin in the config
168   * plugin
169   *
170   **************************/
171  function install_langconf() {
172    // Read what are the languages available with the config plugin
173    if( !$configlang_h = opendir(DOKU_CONFIGLANG) ) return false;
174    while ($lang = readdir($configlang_h)) {
175      if ($lang != "." && $lang != ".." && is_dir(DOKU_CONFIGLANG.'/'. $lang)) {
176	// Then look for every languages in the shibbolethauth plugin
177	if(is_dir(DOKU_SHIBBOLETHLANG.'/'. $lang)) {
178	  if(!$shibboleth_file = fopen(DOKU_SHIBBOLETHLANG .'/' .$lang .'/config_lang.php','r')) return false;
179	  $i=0;
180	  // And copy the $lang lines from each... assuming that noone would place a ; at the beginning of a new line :-)
181	  while (!feof($shibboleth_file)) {
182	    $lines[$i] = fgets($shibboleth_file, 1000);
183	    if(!preg_match('!\$lang\[\'\w{1,}\'\] *= *.*!', $lines[$i])) unset($lines[$i--]);
184	    $i++;
185	  }
186	  fclose($shibboleth_file);
187	  // To the associated language file of the config plugin
188	  if(!$config_file= fopen(DOKU_CONFIGLANG .'/'.$lang .'/lang.php','a')) return false;
189	  if(!fwrite($config_file,'/* Parameters for authenticating from Shibboleth */'."\n")) return false;
190	  foreach ($lines as $line) {
191	    if(!empty($line) && !fwrite($config_file,$line ."\n")) return false;
192	  }
193	  fclose($config_file);
194	}
195      }
196    }
197    closedir($configlang_h);
198    return(true);
199  }
200
201
202  /**************************
203   * Uninstall the language
204   * phrases from the config
205   * plugin
206   *
207   **************************/
208  function uninstall_langconf() {
209    if( !$configlang_h = opendir(DOKU_CONFIGLANG) ) return false;
210    // Delete every line containing the word "shibboleth"
211    while (false !== ($lang = readdir($configlang_h)) ) {
212      if ($lang != "." && $lang != ".." && is_dir(DOKU_CONFIGLANG.'/'. $lang)) {
213	if(!$shibboleth_file = fopen(DOKU_CONFIGLANG .'/' .$lang .'/lang.php','r')) return false;
214	$i = 0;
215	while (!feof($shibboleth_file)) {
216	  $lines[$i] = fgets($shibboleth_file, 1000);
217	  if(preg_match('!shibboleth!i', $lines[$i])) unset($lines[$i--]);
218	  $i++;
219	}
220	fclose($shibboleth_file);
221
222	// Delete lang.php after having backed it up, then copy $lines to a new lang.php. Restore backup if failure.
223	if(!copy(DOKU_CONFIGLANG .'/' .$lang .'/lang.php', DOKU_CONFIGLANG .'/' .$lang .'/lang.php.bak')) return false;
224	if(!unlink(DOKU_CONFIGLANG .'/' .$lang .'/lang.php')) return false;
225	if (!$shibboleth_file = fopen(DOKU_CONFIGLANG .'/' .$lang .'/lang.php', 'w')) {
226	  copy(DOKU . '/conf/local.php.bak', DOKU . '/conf/local.php');
227	  return false;
228	}
229	foreach ($lines as $line) {
230	  if (!empty($line) && fwrite($shibboleth_file, $line) == FALSE) {
231	    copy(DOKU . '/conf/local.php.bak', DOKU . '/conf/local.php');
232	    return false;
233	  }
234	}
235	fclose($shibboleth_file);
236      }
237    }
238  }
239
240
241}
242