Root/
<?php /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* # ***** BEGIN LICENSE BLOCK ***** # This file is part of InDefero, an open source project management application. # Copyright (C) 2008 Céondo Ltd and contributors. # # InDefero is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # InDefero is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # ***** END LICENSE BLOCK ***** */ /** * This classes is a plugin which allows to synchronise access rights * between indefero and a DAV powered Subversion repository. */ class IDF_Plugin_SyncSvn { /** * Entry point of the plugin. */ static public function entry( $signal , & $params ) { // First check for the 3 mandatory config variables. if (!Pluf::f( 'idf_plugin_syncsvn_authz_file' , false) or !Pluf::f( 'idf_plugin_syncsvn_passwd_file' , false) or !Pluf::f( 'idf_plugin_syncsvn_svn_path' . false)) { return ; } include_once 'File/Passwd/Authdigest.php' ; // $ pear install File_Passwd $plug = new IDF_Plugin_SyncSvn(); switch ( $signal ) { case 'IDF_Project::created' : $plug ->processSvnCreate( $params [ 'project' ]); break ; case 'IDF_Project::membershipsUpdated' : $plug ->processSyncAuthz( $params [ 'project' ]); break ; case 'Pluf_User::passwordUpdated' : $plug ->processSyncPasswd( $params [ 'user' ]); break ; } } /** * Run svnadmin command to create the corresponding Subversion * repository. * * @param IDF_Project * @return bool Success */ function processSvnCreate( $project ) { if ( $project ->getConf()->getVal( 'scm' ) != 'svn' ) { return false; } $shortname = $project ->shortname; if (false===( $svn_path =Pluf::f( 'idf_plugin_syncsvn_svn_path' ,false))) { throw new Pluf_Exception_SettingError( "'idf_plugin_syncsvn_svn_path' must be defined in your configuration file." ); } if ( file_exists ( $svn_path . '/' . $shortname )) { throw new Exception(sprintf(__( 'The repository %s already exists.' ), $svn_path . '/' . $shortname )); } $return = 0; $output = array (); $cmd = sprintf(Pluf::f( 'svnadmin_path' , 'svnadmin' ). ' create %s' , escapeshellarg ( $svn_path . '/' . $shortname )); $cmd = Pluf::f( 'idf_exec_cmd_prefix' , '' ). $cmd ; $ll = exec ( $cmd , $output , $return ); return ( $return == 0); } /** * Synchronise an user's password. * * @param Pluf_User */ function processSyncPasswd( $user ) { $passwd_file = Pluf::f( 'idf_plugin_syncsvn_passwd_file' ); if (! file_exists ( $passwd_file ) or ! is_writable ( $passwd_file )) { return false; } $ht = new File_Passwd_Authbasic( $passwd_file ); $ht ->load(); $ht ->setMode(FILE_PASSWD_SHA); if ( $ht ->userExists( $user ->login)) { $ht ->changePasswd( $user ->login, $this ->getSvnPass( $user )); } else { $ht ->addUser( $user ->login, $this ->getSvnPass( $user )); } $ht ->save(); return true; } /** * Synchronize the authz file and the passwd file for the project. * * @param IDF_Project */ function processSyncAuthz( $project ) { $this ->SyncAccess(); $this ->generateProjectPasswd( $project ); } /** * Get the repository password for the user */ function getSvnPass( $user ){ return substr (sha1( $user ->password.Pluf::f( 'secret_key' )), 0, 8); } /** * For a particular project: update all passwd information */ function generateProjectPasswd( $project ) { $passwd_file = Pluf::f( 'idf_plugin_syncsvn_passwd_file' ); if (! file_exists ( $passwd_file ) or ! is_writable ( $passwd_file )) { return false; } $ht = new File_Passwd_Authbasic( $passwd_file ); $ht ->setMode(FILE_PASSWD_SHA); $ht ->load(); $mem = $project ->getMembershipData(); $members = array_merge (( array ) $mem [ 'members' ], ( array ) $mem [ 'owners' ], ( array ) $mem [ 'authorized' ]); foreach ( $members as $user ) { if ( $ht ->userExists( $user ->login)) { $ht ->changePasswd( $user ->login, $this ->getSvnPass( $user )); } else { $ht ->addUser( $user ->login, $this ->getSvnPass( $user )); } } $ht ->save(); } /** * Generate the dav_svn.authz file * * We rebuild the complete file each time. This is just to be sure * not to bork the rights when trying to just edit part of the * file. */ function SyncAccess() { $authz_file = Pluf::f( 'idf_plugin_syncsvn_authz_file' ); $access_owners = Pluf::f( 'idf_plugin_syncsvn_access_owners' , 'rw' ); $access_members = Pluf::f( 'idf_plugin_syncsvn_access_members' , 'rw' ); $access_extra = Pluf::f( 'idf_plugin_syncsvn_access_extra' , 'r' ); $access_public = Pluf::f( 'idf_plugin_syncsvn_access_public' , 'r' ); $access_public_priv = Pluf::f( 'idf_plugin_syncsvn_access_private' , '' ); if (! file_exists ( $authz_file ) or ! is_writable ( $authz_file )) { return false; } $fcontent = '' ; foreach (Pluf::factory( 'IDF_Project' )->getList() as $project ) { $conf = new IDF_Conf(); $conf ->setProject( $project ); if ( $conf ->getVal( 'scm' ) != 'svn' or strlen ( $conf ->getVal( 'svn_remote_url' )) > 0) { continue ; } $mem = $project ->getMembershipData(); // [shortname:/] $fcontent .= '[' . $project ->shortname. ':/]' . "\n" ; foreach ( $mem [ 'owners' ] as $v ) { $fcontent .= $v ->login. ' = ' . $access_owners . "\n" ; } foreach ( $mem [ 'members' ] as $v ) { $fcontent .= $v ->login. ' = ' . $access_members . "\n" ; } // access for all users if ( $project -> private == true) { foreach ( $mem [ 'authorized' ] as $v ) { $fcontent .= $v ->login. ' = ' . $access_extra . "\n" ; } $fcontent .= '* = ' . $access_public_priv . "\n" ; } else { $fcontent .= '* = ' . $access_public . "\n" ; } $fcontent .= "\n" ; } file_put_contents ( $authz_file , $fcontent , LOCK_EX); return true; } } |