diff --git a/codepot/DEBIAN/control.in b/codepot/DEBIAN/control.in index 04822872..59e0117f 100644 --- a/codepot/DEBIAN/control.in +++ b/codepot/DEBIAN/control.in @@ -2,7 +2,7 @@ Package: @PACKAGE@ Version: @VERSION@ Maintainer: @PACKAGE_BUGREPORT@ Homepage: @PACKAGE_URL@ -Depends: subversion, apache2-mpm-prefork, libapache2-svn, php5, php5-ldap, php5-gd, perl, libconfig-simple-perl, libsvn-perl +Depends: subversion, apache2, libapache2-svn, libapache2-mod-perl2, libapache2-mod-php5, php5, php5-ldap, php5-gd, perl, libdbi-perl, libconfig-simple-perl, libsvn-perl, libnet-ldap-perl, libdigest-sha1-perl Recommends: php5-mysql, php5-svn (>= 0.5.1) Suggests: slapd, mysql-server Section: web diff --git a/codepot/etc/codepot.ini.in b/codepot/etc/codepot.ini.in index b71ff12a..8af75b25 100644 --- a/codepot/etc/codepot.ini.in +++ b/codepot/etc/codepot.ini.in @@ -199,19 +199,6 @@ allow_set_time_limit = "no" ;------------------------------------------------------------------------------ signin_for_code_search = "yes" -;------------------------------------------------------------------------------ -; Subversion read access is limited to the specified user type. The types -; include anonymous, authenticated, member. This applies to a public project -; only. Write access to any projects and read access to a non-public project -; require membership regardless of this item. -;------------------------------------------------------------------------------ -svn_read_access = "member" - - -;------------------------------------------------------------------------------ -; The length of a commit message must be as long as this value. -;------------------------------------------------------------------------------ -svn_min_commit_message_length = "0" ;------------------------------------------------------------------------------ ; customized footer @@ -226,3 +213,24 @@ footer = "" ; Full path to the CLOC command ;------------------------------------------------------------------------------ cloc_command_path = "@CFGDIR@/cloc.pl" + +;------------------------------------------------------------------------------ +; Subversion read access is limited to the specified user type. The types +; include anonymous, authenticated, member. This applies to a public project +; only. Write access to any projects and read access to a non-public project +; require membership regardless of this item. +;------------------------------------------------------------------------------ +svn_read_access = "member" + +;------------------------------------------------------------------------------ +; The length of a commit message must be as long as this value. +;------------------------------------------------------------------------------ +svn_min_commit_message_length = "0" + +;------------------------------------------------------------------------------ +; The operations on the files under one of svn_restricted_topdirs +; is limited. The value can be separated by a comma. +;------------------------------------------------------------------------------ +svn_restricted_topdirs = "" +svn_restriction_allowed_subdir_depth_min = 1 +svn_restriction_allowed_subdir_depth_max = 1 diff --git a/codepot/etc/pre-commit.in b/codepot/etc/pre-commit.in index 8828a248..147cc5d1 100644 --- a/codepot/etc/pre-commit.in +++ b/codepot/etc/pre-commit.in @@ -48,8 +48,11 @@ sub get_config database_name => $cfg->param ('database_name'), database_driver => $cfg->param ('database_driver'), database_prefix => $cfg->param ('database_prefix'), - - svn_min_commit_message_length => $cfg->param ('svn_min_commit_message_length') + + svn_min_commit_message_length => $cfg->param ('svn_min_commit_message_length'), + svn_restricted_topdirs => $cfg->param('svn_restricted_topdirs'), + svn_restriction_allowed_subdir_depth_min => $cfg->param('svn_restriction_allowed_subdir_depth_min'), + svn_restriction_allowed_subdir_depth_max => $cfg->param('svn_restriction_allowed_subdir_depth_max') }; return $config; @@ -314,9 +317,9 @@ sub restrict_changes_in_directory_old return ($disallowed > 0)? -1: 0; } -sub restrict_changes_in_directory +sub restrict_changes_in_topdirs { - my ($dir, $min_level, $max_level) = @_; + my ($min_level, $max_level, @topdirs) = @_; my $disallowed = 0; my $pool = SVN::Pool->new(undef); @@ -392,64 +395,66 @@ sub restrict_changes_in_directory #print STDERR "@@@@@ [$affected_file] [$action_verb] [$source_file] [$is_source_file_dir] [$is_affected_file_dir]\n"; - if ($affected_file =~ /\/${dir}\/(.*)$/) + foreach my $topdir(@topdirs) { - # the affected file is located under the given directory. - my $affected_file_nodir = "${1}"; - - if (defined($source_file)) + if ($affected_file =~ /\/${topdir}\/(.*)$/) { - # it's being copied. - if (!$is_affected_file_dir) + # the affected file is located under the given directory. + my $affected_file_nodir = "${1}"; + + if (defined($source_file)) { - # the file beging added by copying is not a directory. - # it disallows individual file copying. - # copy a whole directory at one go. - print (STDERR "Disallowed to copy ${source_file} to ${affected_file}\n"); - $disallowed++; - } - elsif ($source_file =~ /^\/${dir}\/(.*)$/) - { - # i don't want to be a copied file or directory to be - # a source of another copy operation. - print (STDERR "Disallowed to copy ${source_file} to ${affected_file}\n"); - $disallowed++; + # it's being copied. + if (!$is_affected_file_dir) + { + # the file beging added by copying is not a directory. + # it disallows individual file copying. + # copy a whole directory at one go. + print (STDERR "Disallowed to copy ${source_file} to ${affected_file}\n"); + $disallowed++; + } + elsif ($source_file =~ /^\/${topdir}\/(.*)$/) + { + # i don't want to be a copied file or directory to be + # a source of another copy operation. + print (STDERR "Disallowed to copy ${source_file} to ${affected_file}\n"); + $disallowed++; + } + else + { + # TODO: DISALLOW THIS if the parent directory is a copied directory + #my $pardir = dirname ($affected_file); + } } else { - # TODO: DISALLOW THIS if the parent directory is a copied directory - #my $pardir = dirname ($affected_file); - } - } - else - { - if ($is_affected_file_dir) - { - my @segs = split ('/', $affected_file_nodir); - my $num_segs = scalar(@segs); - # NOTE: for a string like abc/def/, split() seems to return 2 segments only. + if ($is_affected_file_dir) + { + my @segs = split ('/', $affected_file_nodir); + my $num_segs = scalar(@segs); + # NOTE: for a string like abc/def/, split() seems to return 2 segments only. - if ($affected_file_nodir eq '') - { - # it is the main directory itself. - # allow operation on it. + if ($affected_file_nodir eq '') + { + # it is the main directory itself. + # allow operation on it. + } + elsif ($num_segs < $min_level || $num_segs > $max_level) + { + # disallow deletion if the directory name to be deleted + # matches a tag pattern + print (STDERR "Disallowed to ${action_verb} a directory - ${affected_file}\n"); + $disallowed++; + } } - elsif ($num_segs < $min_level || $num_segs > $max_level) + else { - # disallow deletion if the directory name to be deleted - # matches a tag pattern - print (STDERR "Disallowed to ${action_verb} a directory - ${affected_file}\n"); + print (STDERR "Disallowed to ${action_verb} a file - ${affected_file}\n"); $disallowed++; } } - else - { - print (STDERR "Disallowed to ${action_verb} a file - ${affected_file}\n"); - $disallowed++; - } } } - } # 'svn rename' within the restricted directory is disallowed because @@ -482,10 +487,24 @@ if (check_commit_message ($cfg->{svn_min_commit_message_length}) <= 0) exit (1); } -# TODO: make 'tags' and 'min_level', 'max_level' configurable. -if (restrict_changes_in_directory ('tags', 1, 2) <= -1) + +# TODO: enable per-project settings for topdir restriction +my $min_level = $cfg->{svn_restriction_allowed_subdir_depth_min}; +if (!defined($min_level)) { $min_level = 0; } +my $max_level = $cfg->{svn_restriction_allowed_subdir_depth_max}; +if (!defined($max_level)) { $max_level = 0; } + +my $topdirs = $cfg->{svn_restricted_topdirs}; +if (defined($topdirs)) { - exit (1); + my @topdir_array = split (/\s*,\s*/, $topdirs); + if (scalar(@topdir_array) > 0) + { + if (restrict_changes_in_topdirs ($min_level, $max_level, @topdir_array) <= -1) + { + exit (1); + } + } } #my $dbh = open_database ($cfg); diff --git a/codepot/src/config.php.in b/codepot/src/config.php.in index 4f10b1e6..cdd1c44a 100644 --- a/codepot/src/config.php.in +++ b/codepot/src/config.php.in @@ -78,10 +78,16 @@ function load_ini ($file) array ('force_project_delete', 'boolean', FALSE), array ('allow_set_time_limit', 'boolean', FALSE), array ('signin_for_code_search', 'boolean', TRUE), - array ('svn_for_members_only', 'boolean', FALSE), array ('footer', 'string', ''), - array ('cloc_command_path', 'string', CODEPOT_CFG_DIR.'/cloc.pl') + array ('cloc_command_path', 'string', CODEPOT_CFG_DIR.'/cloc.pl'), + + // these items are not used by php but by subersion hooks written in perl. + array ('svn_read_access', 'string', 'member'), + array ('svn_min_commit_message_length', 'integer', 0), + array ('svn_restricted_topdirs', 'string', ''), + array ('svn_restriction_allowed_subdir_depth_min', 'integer', 0), + array ('svn_restriction_allowed_subdir_depth_max', 'integer', 0) ); foreach ($xcfgs as $x)