2008-12-03 20:04:32 +00:00
|
|
|
<?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 ***** */
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2008-12-03 22:02:59 +00:00
|
|
|
* This classes is a plugin which allows to synchronise access rights
|
|
|
|
* between indefero and a DAV powered Subversion repository.
|
2008-12-03 20:04:32 +00:00
|
|
|
*/
|
|
|
|
class IDF_Plugin_SyncSvn
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
2008-12-03 22:02:59 +00:00
|
|
|
* Entry point of the plugin.
|
2008-12-03 20:04:32 +00:00
|
|
|
*/
|
2008-12-05 10:52:14 +00:00
|
|
|
static public function entry($signal, &$params)
|
2008-12-03 22:02:59 +00:00
|
|
|
{
|
|
|
|
// 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;
|
|
|
|
}
|
2008-12-07 08:34:52 +00:00
|
|
|
include_once 'File/Passwd/Authdigest.php'; // $ pear install File_Passwd
|
2008-12-03 22:02:59 +00:00
|
|
|
$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':
|
2008-12-03 20:04:32 +00:00
|
|
|
$plug->processSyncPasswd($params['user']);
|
2008-12-03 22:02:59 +00:00
|
|
|
break;
|
2009-06-25 19:37:46 +00:00
|
|
|
case 'IDF_Project::preDelete':
|
|
|
|
$plug->processSvnDelete($params['project']);
|
|
|
|
break;
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-12-03 22:02:59 +00:00
|
|
|
* Run svnadmin command to create the corresponding Subversion
|
|
|
|
* repository.
|
|
|
|
*
|
|
|
|
* @param IDF_Project
|
|
|
|
* @return bool Success
|
2008-12-03 20:04:32 +00:00
|
|
|
*/
|
2008-12-03 22:02:59 +00:00
|
|
|
function processSvnCreate($project)
|
|
|
|
{
|
2009-01-26 20:22:59 +00:00
|
|
|
if ($project->getConf()->getVal('scm') != 'svn') {
|
2009-01-25 20:09:31 +00:00
|
|
|
return false;
|
|
|
|
}
|
2008-12-03 22:02:59 +00:00
|
|
|
$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.");
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
2008-12-03 22:02:59 +00:00
|
|
|
if (file_exists($svn_path.'/'.$shortname)) {
|
|
|
|
throw new Exception(sprintf(__('The repository %s already exists.'),
|
|
|
|
$svn_path.'/'.$shortname));
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
2008-12-03 22:02:59 +00:00
|
|
|
$return = 0;
|
|
|
|
$output = array();
|
2009-02-25 13:28:14 +00:00
|
|
|
$cmd = sprintf(Pluf::f('svnadmin_path', 'svnadmin').' create %s',
|
2008-12-03 22:02:59 +00:00
|
|
|
escapeshellarg($svn_path.'/'.$shortname));
|
2009-01-29 19:29:45 +00:00
|
|
|
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
2008-12-03 22:02:59 +00:00
|
|
|
$ll = exec($cmd, $output, $return);
|
|
|
|
return ($return == 0);
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
2009-06-25 19:37:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove the project from the drive and update the access rights.
|
|
|
|
*
|
|
|
|
* @param IDF_Project
|
|
|
|
* @return bool Success
|
|
|
|
*/
|
|
|
|
function processSvnDelete($project)
|
|
|
|
{
|
|
|
|
if (!Pluf::f('idf_plugin_syncsvn_remove_orphans', false)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ($project->getConf()->getVal('scm') != 'svn') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$this->SyncAccess($project); // exclude $project
|
|
|
|
$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)) {
|
|
|
|
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'rm -rf '.$svn_path.'/'.$shortname;
|
|
|
|
exec($cmd);
|
|
|
|
}
|
|
|
|
}
|
2008-12-03 20:04:32 +00:00
|
|
|
|
|
|
|
/**
|
2008-12-03 22:02:59 +00:00
|
|
|
* Synchronise an user's password.
|
|
|
|
*
|
|
|
|
* @param Pluf_User
|
2008-12-03 20:04:32 +00:00
|
|
|
*/
|
2008-12-03 22:02:59 +00:00
|
|
|
function processSyncPasswd($user)
|
|
|
|
{
|
2008-12-03 20:04:32 +00:00
|
|
|
$passwd_file = Pluf::f('idf_plugin_syncsvn_passwd_file');
|
2008-12-03 22:02:59 +00:00
|
|
|
if (!file_exists($passwd_file) or !is_writable($passwd_file)) {
|
|
|
|
return false;
|
|
|
|
}
|
2008-12-03 20:04:32 +00:00
|
|
|
$ht = new File_Passwd_Authbasic($passwd_file);
|
2008-12-08 09:00:46 +00:00
|
|
|
$ht->load();
|
2008-12-03 22:02:59 +00:00
|
|
|
$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));
|
|
|
|
}
|
2008-12-03 20:04:32 +00:00
|
|
|
$ht->save();
|
2008-12-03 22:02:59 +00:00
|
|
|
return true;
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-12-03 22:02:59 +00:00
|
|
|
* Synchronize the authz file and the passwd file for the project.
|
|
|
|
*
|
|
|
|
* @param IDF_Project
|
2008-12-03 20:04:32 +00:00
|
|
|
*/
|
2008-12-03 22:02:59 +00:00
|
|
|
function processSyncAuthz($project)
|
|
|
|
{
|
2008-12-03 20:04:32 +00:00
|
|
|
$this->SyncAccess();
|
|
|
|
$this->generateProjectPasswd($project);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the repository password for the user
|
|
|
|
*/
|
2008-12-03 22:02:59 +00:00
|
|
|
function getSvnPass($user){
|
2008-12-03 20:04:32 +00:00
|
|
|
return substr(sha1($user->password.Pluf::f('secret_key')), 0, 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For a particular project: update all passwd information
|
|
|
|
*/
|
2008-12-03 22:02:59 +00:00
|
|
|
function generateProjectPasswd($project)
|
|
|
|
{
|
2008-12-03 20:04:32 +00:00
|
|
|
$passwd_file = Pluf::f('idf_plugin_syncsvn_passwd_file');
|
2008-12-03 22:02:59 +00:00
|
|
|
if (!file_exists($passwd_file) or !is_writable($passwd_file)) {
|
|
|
|
return false;
|
|
|
|
}
|
2008-12-03 20:04:32 +00:00
|
|
|
$ht = new File_Passwd_Authbasic($passwd_file);
|
2008-12-03 22:02:59 +00:00
|
|
|
$ht->setMode(FILE_PASSWD_SHA);
|
2008-12-08 09:00:46 +00:00
|
|
|
$ht->load();
|
2008-12-03 20:04:32 +00:00
|
|
|
$mem = $project->getMembershipData();
|
2008-12-03 22:02:59 +00:00
|
|
|
$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));
|
|
|
|
}
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
|
|
|
$ht->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate the dav_svn.authz file
|
2008-12-03 22:02:59 +00:00
|
|
|
*
|
|
|
|
* 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.
|
2009-06-25 19:37:46 +00:00
|
|
|
*
|
|
|
|
* @param IDF_Project Possibly exclude a project (null)
|
2008-12-03 20:04:32 +00:00
|
|
|
*/
|
2009-06-25 19:37:46 +00:00
|
|
|
function SyncAccess($exclude=null)
|
2008-12-03 22:02:59 +00:00
|
|
|
{
|
2008-12-03 20:04:32 +00:00
|
|
|
$authz_file = Pluf::f('idf_plugin_syncsvn_authz_file');
|
2008-12-03 22:02:59 +00:00
|
|
|
$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) {
|
2009-06-25 19:37:46 +00:00
|
|
|
if ($exclude and $exclude->id == $project->id) {
|
|
|
|
continue;
|
|
|
|
}
|
2008-12-03 20:04:32 +00:00
|
|
|
$conf = new IDF_Conf();
|
|
|
|
$conf->setProject($project);
|
2008-12-03 22:02:59 +00:00
|
|
|
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";
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
2008-12-03 22:02:59 +00:00
|
|
|
$fcontent .= '* = '.$access_public_priv."\n";
|
|
|
|
} else {
|
|
|
|
$fcontent .= '* = '.$access_public."\n";
|
|
|
|
}
|
|
|
|
$fcontent .= "\n";
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
|
|
|
file_put_contents($authz_file, $fcontent, LOCK_EX);
|
2008-12-03 22:02:59 +00:00
|
|
|
return true;
|
2008-12-03 20:04:32 +00:00
|
|
|
}
|
|
|
|
}
|