* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-forge_define_config_item('default_server', 'scmgit', forge_get_config ('web_host')) ;
-forge_define_config_item('repos_path', 'scmgit', forge_get_config('chroot').'/scmrepos/git') ;
+forge_define_config_item('default_server', 'scmgit', forge_get_config ('web_host'));
+forge_define_config_item('repos_path', 'scmgit', forge_get_config('chroot').'/scmrepos/git');
+forge_define_config_item('use_ssh', 'scmgit', false);
+forge_set_config_item_bool('use_ssh', 'scmgit');
+forge_define_config_item('use_dav', 'scmgit', true);
+forge_set_config_item_bool('use_dav', 'scmgit');
+forge_define_config_item('use_ssl', 'scmgit', true);
+forge_set_config_item_bool('use_ssl', 'scmgit');
+
class GitPlugin extends SCMPlugin {
function GitPlugin() {
return;
}
- if ($project->usesPlugin($this->name)) {
+ if ($project->usesPlugin($this->name) && forge_check_perm('scm', $project->getID(), 'read')) {
$result = db_query_params('SELECT sum(commits) AS commits, sum(adds) AS adds FROM stats_cvs_group WHERE group_id=$1',
array ($project->getID())) ;
$commit_num = db_result($result,0,'commits');
return $b ;
}
+ static function createUserRepo($params) {
+ $project = $params['project'];
+ $project_name = $project->getUnixName();
+ $user_name = $params['user_name'];
+ $unix_group = $params['unix_group'];
+ $main_repo = $params['main_repo'];
+ $root = $params['root'];
+
+ $repodir = $root . '/users/' . $user_name . '.git' ;
+ chgrp($repodir, $unix_group);
+ if ($project->enableAnonSCM()) {
+ chmod ($repodir, 02755);
+ } else {
+ chmod ($repodir, 02750);
+ }
+ if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
+ system ("git clone --bare $main_repo $repodir") ;
+ system ("GIT_DIR=\"$repodir\" git update-server-info") ;
+ if (is_file ("$repodir/hooks/post-update.sample")) {
+ rename ("$repodir/hooks/post-update.sample",
+ "$repodir/hooks/post-update") ;
+ }
+ if (!is_file ("$repodir/hooks/post-update")) {
+ $f = fopen ("$repodir/hooks/post-update","x+") ;
+ fwrite ($f, "exec git-update-server-info\n") ;
+ fclose ($f) ;
+ }
+ if (is_file ("$repodir/hooks/post-update")) {
+ system ("chmod +x $repodir/hooks/post-update") ;
+ }
+ system("echo \"Git repository for user $user_name in project $project_name\" > $repodir/description");
+ }
+ }
+
function createOrUpdateRepo($params) {
- $project = $this->checkParams($params);
+ $project = $this->checkParams ($params) ;
if (!$project) {
return false ;
}
}
$output = '';
+ if (forge_get_config('use_ssh','scmgit')) {
+ $unix_group = 'scm_' . $project_name ;
+ } else {
+ $unix_group = forge_get_config('apache_group');
+ }
+
// Create main repository
$main_repo = $root . '/' . $project_name . '.git' ;
- if (!is_file("$main_repo/HEAD") && !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs")) {
- exec("GIT_DIR=\"$main_repo\" git init --bare --shared=group", $result) ;
+ if (!is_dir($main_repo) || (!is_file("$main_repo/HEAD") &&
+ !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs"))) {
+ $tmp_repo = util_mkdtemp('.git', $project_name);
+ if ($tmp_repo == false) {
+ return false;
+ }
+ $result = '';
+ exec ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group", $result) ;
$output .= join("<br />", $result);
$result = '';
- exec("GIT_DIR=\"$main_repo\" git update-server-info", $result) ;
+ exec ("GIT_DIR=\"$tmp_repo\" git update-server-info", $result) ;
$output .= join("<br />", $result);
- if (is_file("$main_repo/hooks/post-update.sample")) {
- rename("$main_repo/hooks/post-update.sample",
- "$main_repo/hooks/post-update");
+ if (is_file ("$tmp_repo/hooks/post-update.sample")) {
+ rename ("$tmp_repo/hooks/post-update.sample",
+ "$tmp_repo/hooks/post-update") ;
}
- if (!is_file("$main_repo/hooks/post-update")) {
- $f = fopen("$main_repo/hooks/post-update", 'w');
- fwrite($f, "exec git-update-server-info\n");
- fclose($f);
+ if (!is_file ("$tmp_repo/hooks/post-update")) {
+ $f = fopen ("$tmp_repo/hooks/post-update", 'w') ;
+ fwrite ($f, "exec git-update-server-info\n") ;
+ fclose ($f) ;
}
- if (is_file ("$main_repo/hooks/post-update")) {
- system ("chmod +x $main_repo/hooks/post-update") ;
+ if (is_file ("$tmp_repo/hooks/post-update")) {
+ system ("chmod +x $tmp_repo/hooks/post-update") ;
+ }
+ system ("echo \"Git repository for $project_name\" > $tmp_repo/description") ;
+ system ("find $tmp_repo -type d | xargs chmod g+s") ;
+ system ("chgrp -R $unix_group $tmp_repo") ;
+ system ("chmod -R g+wX,o+rX-w $tmp_repo") ;
+ if ($project->enableAnonSCM()) {
+ system ("chmod g+wX,o+rX-w $root") ;
+ } else {
+ system ("chmod g+wX,o-rwx $root") ;
+ system ("chmod g+wX,o-rwx $tmp_repo") ;
+ }
+ $ret = true;
+ /*
+ * $main_repo can already exist, for example if it’s
+ * not a directory or doesn’t contain a HEAD file or
+ * an objects or refs subdirectory… move it out of
+ * the way in these cases
+ */
+ system("if test -e $main_repo || test -h $main_repo; then d=\$(mktemp -d $main_repo.scmgit-moved.XXXXXXXXXX) && mv -f $main_repo \$d/; fi");
+ /* here’s still a TOCTOU but we check $ret below */
+ system("mv $tmp_repo $main_repo", $ret);
+ if ($ret != 0) {
+ return false;
}
system ("echo \"Git repository for $project_name\" > $main_repo/description") ;
- system ("find $main_repo -type d | xargs chmod g+s") ;
+ system ("find $main_repo -type d | xargs chmod g+s");
+ if (forge_get_config('use_dav','scmgit')) {
+ $f = fopen(forge_get_config('config_path').'/httpd.conf.d/plugin-scmgit-dav.inc','a');
+ fputs($f,'Use Project '.$project_name."\n");
+ fclose($f);
+ system(forge_get_config('httpd_reload_cmd','scmgit'));
+ }
}
if (forge_get_config('use_ssh','scmgit')) {
- $unix_group = 'scm_' . $project_name ;
- system ("chgrp -R $unix_group $root") ;
- system ("chmod g+s $root") ;
if ($project->enableAnonSCM()) {
system ("chmod g+wX,o+rX-w $root") ;
- system ("chmod -R g+rwX,o+rX-w $main_repo") ;
+ system ("chmod g+rwX,o+rX-w $main_repo") ;
} else {
system ("chmod g+wX,o-rwx $root") ;
- system ("chmod -R g+rwX,o-rwx $main_repo") ;
+ system ("chmod g+rwX,o-rwx $main_repo") ;
}
} else {
$unix_user = forge_get_config('apache_user');
- $unix_group = forge_get_config('apache_group');
- system ("chown -R $unix_user:$unix_group $main_repo") ;
- system ("chmod -R g-rwx,o-rwx $main_repo") ;
+ system ("chown $unix_user:$unix_group $main_repo") ;
+ system ("chmod g-rwx,o-rwx $main_repo") ;
}
// Create project-wide secondary repositories
system ("mkdir -p $root/users") ;
$user_name = db_result($result,$i,'user_name');
$repodir = $root . '/users/' . $user_name . '.git' ;
-
- if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
- system ("git clone --bare $main_repo $repodir") ;
- system ("GIT_DIR=\"$repodir\" git update-server-info") ;
- if (is_file ("$repodir/hooks/post-update.sample")) {
- rename ("$repodir/hooks/post-update.sample",
- "$repodir/hooks/post-update") ;
- }
- if (!is_file ("$repodir/hooks/post-update")) {
- $f = fopen ("$repodir/hooks/post-update", 'w') ;
- fwrite ($f, "exec git-update-server-info\n") ;
- fclose ($f) ;
- }
- if (is_file ("$repodir/hooks/post-update")) {
- system ("chmod +x $repodir/hooks/post-update") ;
- }
- system("echo \"Git repository for user $user_name in project $project_name\" > $repodir/description");
- system ("chown -R $user_name:$unix_group $repodir") ;
+
+ if (!is_dir($repodir) && mkdir ($repodir, 0700)) {
+ chown ($repodir, $user_name) ;
+
+ $params = array();
+ $params['project'] = $project;
+ $params['user_name'] = $user_name;
+ $params['unix_group'] = $unix_group;
+ $params['root'] = $root;
+ $params['main_repo'] = $main_repo;
+
+ util_sudo_effective_user($user_name,
+ array("GitPlugin","createUserRepo"),
+ $params);
}
}
if (is_dir ("$root/users")) {
if ($project->enableAnonSCM()) {
- system ("chmod -R g+rX-w,o+rX-w $root/users") ;
+ system ("chmod g+rX-w,o+rX-w $root/users") ;
} else {
- system ("chmod -R g+rX-w,o-rwx $root/users") ;
+ system ("chmod g+rX-w,o-rwx $root/users") ;
}
}
$params['output'] = $output;
fwrite($config_f, "\$javascript = '". util_make_url('/plugins/scmgit/gitweb.js')."';\n");
fwrite($config_f, "\$prevent_xss = 'true';\n");
fclose($config_f);
- chmod ($fname.'.new', 0644) ;
- rename ($fname.'.new', $fname) ;
+ chmod($fname.'.new', 0644);
+ rename($fname.'.new', $fname);
- $fname = $config_dir . '/gitweb.list' ;
+ $fname = $config_dir . '/gitweb.list';
+ $f = fopen($fname.'.new', 'w');
- $f = fopen ($fname.'.new', 'w');
+ $engine = RBACEngine::getInstance();
foreach ($list as $project) {
- $repos = $this->getRepositories($rootdir . "/" . $project->getUnixName());
- foreach ($repos as $repo) {
- $reldir = substr($repo, strlen($rootdir) + 1);
- fwrite($f, $reldir . "\n");
- }
+ $repos = $this->getRepositories($rootdir . "/" . $project->getUnixName());
+ foreach ($repos as $repo) {
+ $reldir = substr($repo, strlen($rootdir) + 1);
+ fwrite($f, $reldir . "\n");
+ }
+ $users = $engine->getUsersByAllowedAction('scm',$project->getID(),'write');
+ $password_data = '';
+ foreach ($users as $user) {
+ $password_data .= $user->getUnixName().':'.$user->getUnixPasswd()."\n";
+ }
+ $faname = forge_get_config('data_path').'/gituser-authfile.'.$project->getUnixName();
+ $fa = fopen($faname.'.new', 'w');
+ fwrite($fa, $password_data);
+ fclose($fa);
+ chmod($faname.'.new', 0644);
+ rename($faname.'.new', $faname);
}
fclose($f);
chmod($fname.'.new', 0644);
if (! $project->usesPlugin($this->name)) {
return false;
}
- if (in_array('scmgit', $params['show'])) {
+ if (in_array('scmgit', $params['show']) || (count($params['show']) < 1)) {
$start_time = $params['begin'];
$end_time = $params['end'];
$repo = forge_get_config('repos_path', 'scmgit') . '/' . $project->getUnixName() . '/' . $project->getUnixName() . '.git';
- $pipe = popen("GIT_DIR=\"$repo\" git log --date=raw --since=@$start_time --until=@$end_time --all --pretty='format:%ad||%an||%s||%h' --name-status", 'r' );
+ $pipe = popen("GIT_DIR=\"$repo\" git log --date=raw --since=@$start_time --until=@$end_time --all --pretty='format:%ad||%ae||%s||%h' --name-status", 'r' );
while (!feof($pipe) && $data = fgets($pipe)) {
$line = trim($data);
$splitedLine = explode('||', $line);
$result['group_id'] = $group_id;
$result['ref_id'] = 'browser.php?group_id='.$group_id;
$result['description'] = $splitedLine[2].' (commit '.$splitedLine[3].')';
- $result['realname'] = '';
+ $userObject = user_get_object_by_email($splitedLine[1]);
+ if (is_a($userObject, 'GFUser')) {
+ $result['realname'] = make_user_link($userObject->getUnixName(), $userObject->getRealName());
+ } else {
+ $result['realname'] = '';
+ }
$splitedDate = explode(' ', $splitedLine[0]);
$result['activity_date'] = $splitedDate[0];
$result['subref_id'] = '';