- <?php
- /**
- * Diese Klasse dient dazu die Repositories zu verwalten
- * wird später mehr Funktionalität gewünscht, kann diese in dieser
- * Klasse hinzugefügt werden. Damit nur authorisierte Benutzer
- * Repositories wieder löschen können, werden alle reps und deren
- * Ersteller in einer eigenen INI Datei verwaltet. Dabei werden alle Benutzer
- * die zu einem Repository hinzugefügt werden können in einer separaten htpasswd
- * Datei verwaltet. Die Zugriffsrechte für die Repositorys werden doppelt gespeichert
- * einmal in der Datei <code>$_config_file_name</code> und in der Konfigurationsdatei
- * die von Subversion direkt benutzt wird. So ist es möglich in der Konfigurationsdatei
- * die im lokalem Programm benutzt wird weitere Informationen hinzuzufügen.
- *
- * @copyright 2005 Hasso-Plattner-Institut für Softwaresystemtechnik
- * @author Martin Grund
- * @link http://www.grundprinzip.de
- * @version 1.0
- */
- class SVNAdmin {
-
- var $_repository_list = array();
- var $_config_file_name = "rep_list.ini";
- var $_svn_config_file = "c:/xampp5/svn/usr_config.cfg";
- var $_svn_password_file = "c:/xampp5/svn/usr_list";
- var $_svn_parent_path = "c:/xampp5/svn";
-
- var $current_user = null;
- var $pass = null;
- var $error_list = array();
- var $user_list = array();
-
- var $use_fs_locks = true;
- var $lock_handle;
-
-
- /**
- * Konstruktor der Klasse. Hier wird der aktuelle Benutzer
- * initialisiert und geladen. Weiterhin wird die Konfiguration
- * geladen, damit diese Benutzt werden kann
- *
- * @param String $username Der aktuelle Benutzername
- * @param String $pass Das Passwort
- * @access public
- */
- function SVNAdmin($username, $pass) {
-
- $this->current_user = $username;
- $this->pass = $pass;
-
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Konfiguration
- if (!$this->_loadRepositoryFile())
- {
- $this->error_list[] = "Konnte Objekt nicht korrekt erzeugen";
- foreach ($this->error_list as $error) {
- echo $error;
- }
- die();
- }
-
- $this->_releaseExclusiveLock();
-
- } else {
- die("Dateisystemfehler");
- }
-
- //Ab hier fertig für Aufträge
- }
-
-
- /**
- * Diese Methode erstellt ein neues Repository im Kontext
- * des aktuellen Benutzers. Dazu wird mittels
- * <code>svn create</code> ein neues Repository angelegt und dann der Benutzer
- * hinzugefügt.
- *
- * @param String $rep_name Der Name des Repositories
- * @return Boolean
- * @access public
- */
- function createRepository($rep_name)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- //Zurücksetzen der Fehlermeldungen
- $this->error_list = array();
-
- //Als erstes überprüfen, ob Rep schon ex.
- if (!$this->_checkIfRepositoryExists($rep_name))
- {
-
- //Wechseln in SVN Parent Path
- //merken des eigenen pfades
- $old_path = getcwd();
- chdir($this->_svn_parent_path);
-
- //Ausführen von svnadmin create
- $line = system("svnadmin create $rep_name", $return);
- //und wieder verzeichnis wechseln
- chdir($old_path);
-
-
- //Nun Rep zu Datei hinzu und die Konfig schreiben
- $rep = $this->_repository_list[$rep_name];
- $rep['owner'] = $this->current_user;
- $this->_repository_list[$rep_name] = $rep;
- //Speichern der Konfig
- $this->_writeRepositoryFile();
-
- //Den aktuellen Benutzer mit vollen Rechten hinzu
- //plus das owner feld
- $this->_releaseExclusiveLock();
-
- $this->addUserToRepository($this->current_user, $rep_name, "rw");
- return true;
-
-
- } else
- {
- $this->_releaseExclusiveLock();
- return false;
- }
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
-
- }
-
- /**
- * Diese Methode löscht ein Repository aus dem Stammverzeichnis
- * dise geschieht durch aufrufen von <code>rm -Rf</code>
- *
- * @param String $rep_name Der Name des Repositorys
- * @return Boolean
- * @access public
- */
- function deleteRepository($rep_name)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- if ($this->_checkIfUserIsRepOwner($rep_name))
- {
- unset($this->_repository_list[$rep_name]);
- $this->_writeRepositoryFile();
-
- //Wechseln in SVN Parent Path
- //merken des eigenen pfades
- $old_path = getcwd();
- chdir($this->_svn_parent_path);
-
- //Ausführen von svnadmin create
- $line = system("rm -Rf $rep_name", $return);
- //und wieder verzeichnis wechseln
- chdir($old_path);
- $this->_releaseExclusiveLock();
- return true;
-
- }
-
- $this->_releaseExclusiveLock();
- return false;
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
- /**
- * Diese Methode fügt einen Bentzer zu dem Repository hinzu
- *
- * @param String $user der neue Benutzer
- * @param String $rep_name Der Name des Repositorys
- * @param String $rights Die Rechte des Benutzers
- * @return Boolean
- * @access public
- */
- function addUserToRepository($user, $rep_name, $rights)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- if ($this->_checkIfRepositoryExists($rep_name) &&
- $this->_checkIfUserIsRepOwner($rep_name) &&
- !$this->_checkIfUserExistsInRep($rep_name, $user) &&
- $this->_checkIfUserExists($user))
- {
-
- $rep = $this->_repository_list[$rep_name];
- $rep[$user] = $rights;
- $this->_repository_list[$rep_name] = $rep;
- $this->_writeRepositoryFile();
-
- $this->_releaseExclusiveLock();
- return true;
-
- }
-
- $this->_releaseExclusiveLock();
- return false;
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
- /**
- * Diese Methode entfernt einen Benutzer aus dem Repository.
- *
- * @param String $user Der zu entfernende Benutzer
- * @param String $rep_name Der Name des Repositorys
- * @return Boolean
- * @access public
- */
- function removeUserFromRepository($user, $rep_name)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- if ($this->_checkIfRepositoryExists($rep_name) &&
- $this->_checkIfUserIsRepOwner($rep_name) &&
- $this->_checkIfUserExistsInRep($rep_name, $user))
- {
- unset($this->_repository_list[$rep_name][$user]);
-
- $this->_writeRepositoryFile();
- $this->_releaseExclusiveLock();
-
- return true;
- }
-
- $this->_releaseExclusiveLock();
- return false;
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
- /**
- * Diese Funktion löscht einen Benutzer aus der globalen
- * Benutzerliste
- *
- * @param String $user Der Benutzer
- */
- function deleteUser($user)
- {
- }
-
- /**
- * Diese Methode verändert die Zugriffsrechte eines Benutzers
- * in einem Repository.
- *
- * @param String $user Der zu verändernde Benutzer
- * @param String $rep_name Der Name des Repositorys
- * @param String $rights Die neuen Benutzerrechte
- * @return boolean
- * @access public
- */
- function changeUserRights($user, $rep_name, $rights)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- if ($this->_checkIfRepositoryExists($rep_name) &&
- $this->_checkIfUserIsRepOwner($rep_name) &&
- $this->_checkIfUserExistsInRep($rep_name, $user))
- {
- $this->_repository_list[$rep_name][$user] = $rights;
- $this->_writeRepositoryFile();
-
- $this->_releaseExclusiveLock();
- return true;
- }
-
- $this->_releaseExclusiveLock();
- return false;
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
- /**
- * Diese Funktion liefert die Benutzer eines ausgewählten
- * Repositorys zurück
- *
- * @param String $rep_name Der Name des Repositorys
- * @return Array
- * @access public
- */
- function getRepositoryUsers($rep_name)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- if ($this->_checkIfRepositoryExists($rep_name) && $this->_checkIfUserIsRepOwner($rep_name))
- {
- $this->_releaseExclusiveLock();
- return $this->_getUserByRepository($rep_name);
- }
-
- $this->_releaseExclusiveLock();
- return false;
-
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
-
- /**
- * Liest alle Repositories des aktuellen Benutzers aus
- * und liefert diese in einem Array zurück.
- *
- * @package String $user Der Benutzer
- * @return Array
- * @access public
- */
- function getUserRepositories($user)
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- $out = array();
- foreach ($this->_repository_list as $key => $rep) {
-
- if ($rep['owner'] == $user)
- {
- $out[$key] = $rep;
- }
- }
-
- $this->_releaseExclusiveLock();
- return $out;
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
-
- /**
- * Liefert die Liste aller global registrierten Benutzer zurück.
- *
- * @return Array
- * @access public
- */
- function getAllRegisteredUsers()
- {
- if ($this->_aquireExclusiveLock())
- {
- //Laden der Repository Konfiguration
- $this->_loadRepositoryFile();
-
- $this->_releaseExclusiveLock();
- return array_keys($this->user_list);
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
- function getRegisteredUserByName($username)
- {
-
- }
-
- /**
- * Diese Methode erzeugt ein HTAccess Password mittels
- * der Funktion htpasswd. Diese wird benutzt, da unter Windows Probleme mit
- * dem manuellen Crypt auftreten können.
- */
- function addGlobalUser($username, $password)
- {
- if ($this->_aquireExclusiveLock())
- {
- if (is_string($username) && $password )
- {
- if (!$this->_checkIfUserExists($username))
- {
-
- //Laden von htpasswd
- $line = exec("htpasswd -bn $username $password", $out);
- $linearr = explode(":", $out[0]);
-
- $this->_loadRepositoryFile();
-
- $res = $this->user_list[$username] = $linearr[1];
- $res2 = $this->_writeRepositoryFile();
- $res3 = $this->_writePasswordFile();
-
- $this->_releaseExclusiveLock();
- return $res && $res2 && $res3;
-
- } else {
-
- $this->_releaseExclusiveLock();
- $this->error_list[] = "Der gewählte Benutzer existiert schon";
- return false;
- }
-
- } else {
-
- $this->_releaseExclusiveLock();
- $this->error_list[] = "Benutzername oder Passwort nicht vollständig eingegeben.";
- return false;
- }
- }
-
- $this->error_list[] = "Dateisystemfehler";
- return false;
- }
-
- ///////////////////////////////////////////////////////////////
- // Hilfsfunktionen
- ///////////////////////////////////////////////////////////////
-
- /**
- * Liefert alle Benutzer des Repositorys zurück. Spezielle Felder
- * in der INI Datei werden dabei ignoriert
- *
- * @param String $rep_name Der Name des Repositorys
- * @return Array
- * @access privcate
- */
- function _getUserByRepository($rep_name)
- {
- $rep = $this->_repository_list[$rep_name];
- unset($rep['owner']);
-
- return $rep;
- }
-
- /**
- * Diese Methode läd die Repository Konfiguration aus der
- * angegebenen Datei. Die liste wird dabei global in die Klasse
- * geschrien
- * @access private
- */
- function _loadRepositoryFile()
- {
- //Erstellen der INI Klasse und öffnen der Datei
- $this->_repository_list = IniController::parse_ini_file($this->_config_file_name);
-
- //Laden der Benutzer und Passwörter
- $this->_parsePasswordFile();
-
- if (empty($this->_repository_list))
- $this->_repository_list = array();
-
- if (!is_array($this->_repository_list))
- {
- $this->error_list[] = "Fehler beim laden der INI Datei";
- return false;
- }
-
-
- return true;
- }
-
-
- /**
- * Diese Methode schreibt die nötigen Änderungen wieder in die entsprechenden INI
- * Dateien. Dabei wird nicht nur die lokale Konfiguration geschrieben sondern auch
- * die Konfiguration für Subversion selbst.
- *
- * @return boolean
- * @access private
- */
- function _writeRepositoryFile()
- {
-
- $res = IniController::save_ini_file($this->_config_file_name, $this->_repository_list);
- $res_svn = IniController::save_ini_file($this->_svn_config_file, $this->_repository_list, true, true);
-
- if ($res && $res_svn)
- {
- return true;
- }
-
- $this->error_list[] = $ini_class->writeError;
- $this->_loadRepositoryFile();
- $this->_parsePasswordFile();
- return false;
-
- }
-
-
- /**
- * Diese Methode überprüft, ob das angegebene Repository existiert. Dazu
- * wird die lokale Liste der Repositorys überprüft.
- *
- * @param String $rep_name Der Name des Repositorys
- * @return boolean
- * @access private
- */
- function _checkIfRepositoryExists($rep_name)
- {
- //Das Repository muss als Schlüssel in der
- //globalen Kofig stehen
-
- if (array_key_exists($rep_name, $this->_repository_list))
- {
- return true;
- }
-
- $this->error_list[] ='Das gewählte Repository existiert nicht';
- return false;
- }
-
-
- /**
- * Diese Methode überprüft, ob der aktuelle Benutzer der Besitzter
- * des Repositorys ist
- *
- * @param String $rep_name Der Name des Repositorys
- * @return boolean
- * @access private
- */
- function _checkIfUserIsRepOwner($rep_name)
- {
- $rep = $this->_repository_list[$rep_name];
- if ($rep['owner'] == $this->current_user)
- return true;
- else {
- $this->error_list[] = "Der angemeldete Benutzer ist nicht Besitzer des Repositorys";
- return false;
- }
- }
-
- /**
- * Diese Methode überprüft, ob ein Benutzer in dem Repository existiert
- *
- * @param String $rep_name Der Name des Repositorys
- * @param String $user Der Benutzer
- * @return boolean
- * @access private
- */
- function _checkIfUserExistsInRep($rep_name, $user)
- {
- $rep = $this->_repository_list[$rep_name];
- if (array_key_exists($user, $rep))
- return true;
- else
- return false;
- }
-
- /**
- * Die Methode überprüft, ob ein Benutzer überhaupt existiert
- *
- * @param String $user Der Benutzer
- * @return boolean
- * @access private
- */
- function _checkIfUserExists($user)
- {
- $users = array_keys($this->user_list);
-
- if (in_array($user, $users))
- return true;
- else {
- $this->error_list[] = "Der gewünschte Benutzer exisitiert nicht.";
- return false;
- }
-
- }
-
- /**
- * Diese Methode parst ene <code>htpasswd</code> Datei
- * um daraus die Benuternamen und die gehashten Passwörter
- * zu extrahieren
- *
- * @access private
- * @return boolean
- *
- */
- function _parsePasswordFile()
- {
- $cts = file_get_contents($this->_svn_password_file);
- if ($cts)
- {
- $user_list_raw = explode("\n", $cts);
- foreach ($user_list_raw as $val) {
-
- $tmp = explode(":", $val);
- if ($tmp[0] != "")
- $this->user_list[$tmp[0]] = $tmp[1];
- }
-
- return true;
- }
-
- return false;
- }
-
-
- /**
- * Diese Methode schreibt ene <code>htpasswd</code> Datei
- *
- * @access private
- * @return boolean
- *
- */
- function _writePasswordFile()
- {
- $cts = "";
- foreach ($this->user_list as $key => $val) {
-
- $cts.=$key.":".$val."\n";
- }
-
- $fid = fopen($this->_svn_password_file, "w+");
- if ($fid)
- {
- fwrite($fid, $cts);
- fclose($fid);
- return true;
- }
-
- $this->error_list[] = "Konnte Passwort Datei nicht schreiben.";
- return false;
- }
-
- /**
- * Diese Funktion legt eine globale Schreibsperre auf die Konfigurationsdateien.
- * Diese Funktion funktioniert solange, wie nur auf die public Methoden zugegriffen
- * wird. Dies ist der Tribut an die Performance.
- *
- * @access private
- * @return boolean
- */
- function _aquireExclusiveLock()
- {
- if ($this->use_fs_locks)
- {
- $fid = fopen("file.lck", "w+");
- if ($fid)
- {
- $res = flock($fid, LOCK_EX);
- if ($res)
- {
- $this->lock_handle = $fid;
- return true;
- } else
- return false;
- }
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Diese Funktion hebt die Schreibsperre auf die Konfigurationsdateien
- * wieder auf.
- *
- * @access private
- * @return boolean
- */
- function _releaseExclusiveLock()
- {
- if ($this->use_fs_locks)
- {
-
- $res = flock($this->lock_handle, LOCK_UN);
- fclose($this->lock_handle);
- unlink("file.lck");
-
- if ($res)
- {
- $this->lock_handle = null;
- return true;
- }
- else
- return false;
- }
-
- return true;
- }
- }
-
-
- ?>