<?php
class
IDF_Plugin_SyncSvn
{
static
public
function
entry(
$signal
, &
$params
)
{
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'
;
$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
;
case
'IDF_Project::preDelete'
:
$plug
->processSvnDelete(
$params
[
'project'
]);
break
;
case
'svnpostcommit.php::run'
:
$plug
->processSvnUpdateTimeline(
$params
);
break
;
}
}
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
);
if
(
$return
!= 0) {
Pluf_Log::error(
array
(
'IDF_Plugin_SyncSvn::processSvnCreate'
,
'Error'
,
array
(
'path'
=>
$svn_path
.
'/'
.
$shortname
,
'output'
=>
$output
)));
return
;
}
$p
=
"/home/www/indefero/scripts/svn-post-commit"
;
exec
(sprintf(Pluf::f(
'idf_exec_cmd_prefix'
,
''
).
'ln -s %s %s'
,
escapeshellarg
(
$p
),
escapeshellarg
(
$svn_path
.
'/'
.
$shortname
.
'/hooks/post-commit'
)),
$out
,
$res
);
if
(
$res
!= 0) {
Pluf_Log::warn(
array
(
'IDF_Plugin_SyncSvn::processSvnCreate'
,
'post-commit hook creation error.'
,
$svn_path
.
'/'
.
$shortname
.
'/hooks/post-commit'
));
return
;
}
$p
=
"/home/www/indefero/scripts/svn-post-revprop-change"
;
exec
(sprintf(Pluf::f(
'idf_exec_cmd_prefix'
,
''
).
'ln -s %s %s'
,
escapeshellarg
(
$p
),
escapeshellarg
(
$svn_path
.
'/'
.
$shortname
.
'/hooks/post-revprop-change'
)),
$out
,
$res
);
if
(
$res
!= 0) {
Pluf_Log::warn(
array
(
'IDF_Plugin_SyncSvn::processSvnCreate'
,
'post-revprop-change hook creation error.'
,
$svn_path
.
'/'
.
$shortname
.
'/hooks/post-revprop-change'
));
return
;
}
return
(
$return
== 0);
}
function
processSvnDelete(
$project
)
{
if
(!Pluf::f(
'idf_plugin_syncsvn_remove_orphans'
, false)) {
return
;
}
if
(
$project
->getConf()->getVal(
'scm'
) !=
'svn'
) {
return
false;
}
$this
->SyncAccess(
$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
);
}
}
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(
'plain'
);
if
(
$ht
->userExists(
$user
->login)) {
$ht
->changePasswd(
$user
->login,
'{SHA}'
.
$this
->getSvnPass(
$user
));
}
else
{
$ht
->addUser(
$user
->login,
'{SHA}'
.
$this
->getSvnPass(
$user
));
}
$ht
->save();
return
true;
}
function
processSyncAuthz(
$project
)
{
$this
->SyncAccess();
$this
->generateProjectPasswd(
$project
);
}
function
getSvnPass(
$user
){
return
$user
->password;
}
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(
'plain'
);
$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,
'{SHA}'
.
$this
->getSvnPass(
$user
));
}
else
{
$ht
->addUser(
$user
->login,
'{SHA}'
.
$this
->getSvnPass(
$user
));
}
}
$ht
->save();
}
function
SyncAccess(
$exclude
=null)
{
$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
) {
if
(
$exclude
and
$exclude
->id ==
$project
->id) {
continue
;
}
$conf
=
new
IDF_Conf();
$conf
->setProject(
$project
);
if
(
$conf
->getVal(
'scm'
) !=
'svn'
or
strlen
(
$conf
->getVal(
'svn_remote_url'
)) > 0) {
continue
;
}
$mem
=
$project
->getMembershipData();
$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"
;
}
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;
}
public
function
processSvnUpdateTimeline(
$params
)
{
$pname
=
basename
(
$params
[
'repo_dir'
]);
try
{
$project
= IDF_Project::getOr404(
$pname
);
}
catch
(Pluf_HTTP_Error404
$e
) {
Pluf_Log::event(
array
(
'IDF_Plugin_SyncSvn::processSvnUpdateTimeline'
,
'Project not found.'
,
array
(
$pname
,
$params
)));
return
false;
}
Pluf_Log::debug(
array
(
'IDF_Plugin_SyncGit::processSvnUpdateTimeline'
,
'Project found'
,
$pname
,
$project
->id));
IDF_Scm::syncTimeline(
$project
, true);
Pluf_Log::event(
array
(
'IDF_Plugin_SyncGit::processSvnUpdateTimeline'
,
'sync'
,
array
(
$pname
,
$project
->id)));
}
}