<?php
class
IDF_Plugin_SyncMercurial
{
static
public
function
entry(
$signal
, &
$params
)
{
if
(!Pluf::f(
'idf_plugin_syncmercurial_passwd_file'
, false)
or
!Pluf::f(
'idf_plugin_syncmercurial_path'
, false)
or
!Pluf::f(
'idf_plugin_syncmercurial_hgrc'
, false)) {
return
;
}
include_once
'File/Passwd/Authdigest.php'
;
$plug
=
new
IDF_Plugin_SyncMercurial();
switch
(
$signal
) {
case
'IDF_Project::created'
:
$plug
->processMercurialCreate(
$params
[
'project'
]);
break
;
case
'IDF_Project::membershipsUpdated'
:
$plug
->processSyncAuthz(
$params
[
'project'
]);
break
;
case
'Pluf_User::passwordUpdated'
:
$plug
->processSyncPasswd(
$params
[
'user'
]);
break
;
}
}
function
processMercurialCreate(
$project
)
{
$shortname
=
$project
->shortname;
if
(false===(
$mercurial_path
=Pluf::f(
'idf_plugin_syncmercurial_path'
,false))) {
throw
new
Pluf_Exception_SettingError(
"'idf_plugin_syncmercurial_path' must be defined in your configuration file."
);
}
if
(
file_exists
(
$mercurial_path
.
'/'
.
$shortname
)) {
throw
new
Exception(sprintf(__(
'The repository %s already exists.'
),
$mercurial_path
.
'/'
.
$shortname
));
}
$return
= 0;
$output
=
array
();
$cmd
= sprintf(
'hg init %s'
,
escapeshellarg
(
$mercurial_path
.
'/'
.
$shortname
));
$ll
=
exec
(
$cmd
,
$output
,
$return
);
return
(
$return
== 0);
}
function
processSyncPasswd(
$user
)
{
$passwd_file
= Pluf::f(
'idf_plugin_syncmercurial_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
->getMercurialPass(
$user
));
}
else
{
$ht
->addUser(
$user
->login,
$this
->getMercurialPass(
$user
));
}
$ht
->save();
return
true;
}
function
processSyncAuthz(
$project
)
{
$this
->SyncAccess(
$project
);
$this
->generateProjectPasswd(
$project
);
}
function
getMercurialPass(
$user
){
return
substr
(sha1(
$user
->password.Pluf::f(
'secret_key'
)), 0, 8);
}
function
generateProjectPasswd(
$project
)
{
$passwd_file
= Pluf::f(
'idf_plugin_syncmercurial_passwd_file'
);
if
(!
file_exists
(
$passwd_file
)
or
!
is_writable
(
$passwd_file
)) {
throw
new
Exception (sprintf(__(
'%s does not exist or is not writable.'
),
$passwd_file
));
}
$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
->getMercurialPass(
$user
));
}
else
{
$ht
->addUser(
$user
->login,
$this
->getMercurialPass(
$user
));
}
}
$ht
->save();
}
function
SyncAccess(
$project
)
{
$shortname
=
$project
->shortname;
$hgrc_file
= Pluf::f(
'idf_plugin_syncmercurial_path'
).sprintf(
'/%s/.hg/hgrc'
,
$shortname
);
$allow_push
=
''
;
$mem
=
$project
->getMembershipData();
foreach
(
$mem
[
'owners'
]
as
$v
) {
$allow_push
.=
$v
->login.
' '
;
}
foreach
(
$mem
[
'members'
]
as
$v
) {
$allow_push
.=
$v
->login.
' '
;
}
if
(
is_file
(
$hgrc_file
)) {
$tmp_content
=
parse_ini_file
(
$hgrc_file
, true);
$tmp_content
[
'web'
][
'allow_push'
] =
$allow_push
;
}
else
{
$tmp_content
= Pluf::f(
'idf_plugin_syncmercurial_hgrc'
);
$tmp_content
[
'web'
][
'allow_push'
] =
$allow_push
;
}
$fcontent
=
''
;
foreach
(
$tmp_content
as
$key
=>
$elem
){
$fcontent
.=
'['
.
$key
.
"]\n"
;
foreach
(
$elem
as
$key2
=>
$elem2
){
$fcontent
.=
$key2
.
' = '
.
$elem2
.
"\n"
;
}
}
file_put_contents
(
$hgrc_file
,
$fcontent
, LOCK_EX);
$private_file
= Pluf::f(
'idf_plugin_syncmercurial_private_include'
);
$notify_file
= Pluf::f(
'idf_plugin_syncmercurial_private_notify'
);
$fcontent
=
''
;
foreach
(Pluf::factory(
'IDF_Project'
)->getList()
as
$project
) {
$conf
=
new
IDF_Conf();
$conf
->setProject(
$project
);
if
(
$project
->
private
== true){
$mem
=
$project
->getMembershipData();
$user
=
''
;
foreach
(
$mem
[
'owners'
]
as
$v
) {
$user
.=
$v
->login.
' '
;
}
foreach
(
$mem
[
'members'
]
as
$v
) {
$user
.=
$v
->login.
' '
;
}
foreach
(
$mem
[
'authorized'
]
as
$v
) {
$user
.=
$v
->login.
' '
;
}
$fcontent
.=
'<Location '
. sprintf(Pluf::f(
'idf_plugin_syncmercurial_private_url'
),
$project
->shortname).
'>'
.
"\n"
;
$fcontent
.=
'AuthType Basic'
.
"\n"
;
$fcontent
.=
'AuthName "Restricted"'
.
"\n"
;
$fcontent
.= sprintf(
'AuthUserFile %s'
, Pluf::f(
'idf_plugin_syncmercurial_passwd_file'
)).
"\n"
;
$fcontent
.= sprintf(
'Require user %s'
,
$user
).
"\n"
;
$fcontent
.=
'</Location>'
.
"\n\n"
;
}
}
file_put_contents
(
$private_file
,
$fcontent
, LOCK_EX);
file_put_contents
(
$notify_file
,
' '
, LOCK_EX);
return
true;
}
}