231 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
#!/usr/bin/perl
 | 
						|
 | 
						|
use strict;
 | 
						|
 | 
						|
use Config::Simple;
 | 
						|
use DBI;
 | 
						|
use File::Basename;
 | 
						|
 | 
						|
#use SVN::Core;
 | 
						|
#use SVN::Repos;
 | 
						|
#use SVN::Fs;
 | 
						|
 | 
						|
my $CFG_FILE = '@CFGDIR@/codepot.ini';
 | 
						|
my $REPOFS = $ARGV[0];
 | 
						|
my $REPOBASE = basename($REPOFS);
 | 
						|
my $REVISION= $ARGV[1];
 | 
						|
my $USER = $ARGV[2];
 | 
						|
my $PROPNAME = $ARGV[3];
 | 
						|
my $ACTION = $ARGV[4];
 | 
						|
 | 
						|
my $QC = '';
 | 
						|
 | 
						|
sub get_config
 | 
						|
{
 | 
						|
	my $cfg = new Config::Simple();
 | 
						|
 | 
						|
	if (!$cfg->read ($CFG_FILE))
 | 
						|
	{
 | 
						|
		return undef;
 | 
						|
	}
 | 
						|
 | 
						|
	my $config = {
 | 
						|
		database_hostname => $cfg->param ("database_hostname"),
 | 
						|
		database_port => $cfg->param ("database_port"),
 | 
						|
		database_username => $cfg->param ("database_username"),
 | 
						|
		database_password => $cfg->param ("database_password"),
 | 
						|
		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')
 | 
						|
	};
 | 
						|
 | 
						|
	return $config;
 | 
						|
}
 | 
						|
 | 
						|
sub open_database
 | 
						|
{
 | 
						|
	my ($cfg) = @_;
 | 
						|
 | 
						|
	my $dbtype = $cfg->{database_driver};
 | 
						|
	my $dbname = $cfg->{database_name};
 | 
						|
	my $dbhost = $cfg->{database_hostname};
 | 
						|
	my $dbport = $cfg->{database_port};
 | 
						|
 | 
						|
	if ($dbtype eq 'postgre') { $dbtype = 'Pg'; }
 | 
						|
	elsif ($dbtype eq 'oci8') { $dbtype = 'Oracle'; }
 | 
						|
	elsif ($dbtype eq 'mysqli') { $dbtype = 'mysql'; }
 | 
						|
 | 
						|
	my $dbstr;
 | 
						|
	my $dbuser;
 | 
						|
	my $dbpass;
 | 
						|
	if ($dbtype eq 'Oracle')
 | 
						|
	{
 | 
						|
		$QC = '"';
 | 
						|
		$dbstr = "DBI:$dbtype:";
 | 
						|
		$dbuser = $cfg->{database_username} . '/' . $cfg->{database_password} . '@' . $dbhost;
 | 
						|
		$dbpass = '';
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		$dbstr = "DBI:$dbtype:database=$dbname;";
 | 
						|
		if (length($dbhost) > 0) { $dbstr .= "host=$dbhost;"; }
 | 
						|
		if (length($dbport) > 0) { $dbstr .= "port=$dbport;"; }
 | 
						|
 | 
						|
		$dbuser = $cfg->{database_username};
 | 
						|
		$dbpass = $cfg->{database_password};
 | 
						|
	}
 | 
						|
 | 
						|
	my $dbh = DBI->connect(
 | 
						|
		$dbstr, $dbuser, $dbpass,
 | 
						|
		{ RaiseError => 0, PrintError => 0, AutoCommit => 0 }
 | 
						|
	);
 | 
						|
 | 
						|
	return $dbh;
 | 
						|
}
 | 
						|
 | 
						|
sub close_database
 | 
						|
{
 | 
						|
	my ($dbh) = @_;
 | 
						|
	$dbh->disconnect ();
 | 
						|
}
 | 
						|
 | 
						|
sub is_project_member
 | 
						|
{
 | 
						|
	my ($dbh, $prefix, $projectid, $userid) = @_;
 | 
						|
 | 
						|
	my $query = $dbh->prepare ("SELECT ${QC}projectid${QC} FROM ${QC}${prefix}project_membership${QC} WHERE ${QC}userid${QC}=? AND ${QC}projectid${QC}=?");
 | 
						|
	if (!$query || !$query->execute ($userid, $projectid))
 | 
						|
	{
 | 
						|
		return (-1, $dbh->errstr());
 | 
						|
	}
 | 
						|
 | 
						|
	my @row = $query->fetchrow_array;
 | 
						|
	$query->finish ();
 | 
						|
	return (((scalar(@row) > 0)? 1: 0), undef);
 | 
						|
}
 | 
						|
 | 
						|
#sub check_commit_message
 | 
						|
#{
 | 
						|
#	my ($minlen, $newmsg) = @_;
 | 
						|
#
 | 
						|
#	my $pool = SVN::Pool->new(undef); 
 | 
						|
#	my $svn = eval { SVN::Repos::open ($REPOFS, $pool) };
 | 
						|
#	if (!defined($svn))
 | 
						|
#	{
 | 
						|
#		print (STDERR "Cannot open svn - $REPOFS\n");
 | 
						|
#		return -1; # error
 | 
						|
#	}
 | 
						|
#	
 | 
						|
#	my $fs = $svn->fs ();
 | 
						|
#	if (!defined($fs))
 | 
						|
#	{
 | 
						|
#		print (STDERR "Cannot open fs - $REPOFS\n");
 | 
						|
#		return -1; # error
 | 
						|
#	}
 | 
						|
#	
 | 
						|
#	my $log = $fs->revision_prop ($REVISION, 'svn:log');
 | 
						|
#	$log =~ s/^\s+|\s+$//g; # trim leading spaces and  trailing spaces
 | 
						|
#	if (length($log) < $minlen) 
 | 
						|
#	{
 | 
						|
#		print (STDERR "[$log] Commit message too short. must be >= $minlen\n");
 | 
						|
#		return 0;
 | 
						|
#	}
 | 
						|
#
 | 
						|
#	return 1;
 | 
						|
#}
 | 
						|
 | 
						|
#------------------------------------------------------------
 | 
						|
# MAIN
 | 
						|
#------------------------------------------------------------
 | 
						|
 | 
						|
my $newauthor = undef;
 | 
						|
 | 
						|
my $cfg = get_config ();
 | 
						|
if (!defined($cfg))
 | 
						|
{
 | 
						|
	print (STDERR "Cannot load codepot configuration file\n");
 | 
						|
	exit (1);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
if ($ACTION eq 'D')
 | 
						|
{
 | 
						|
	if ($PROPNAME eq 'svn:log' || $PROPNAME eq 'svn:author' || $PROPNAME eq 'svn:date')
 | 
						|
	{
 | 
						|
		print (STDERR "Not allowed to delete $PROPNAME\n");
 | 
						|
		exit (1);
 | 
						|
	}
 | 
						|
}
 | 
						|
elsif ($ACTION eq 'M' || $ACTION eq 'A')
 | 
						|
{
 | 
						|
	if ($PROPNAME eq 'svn:author')
 | 
						|
	{
 | 
						|
		$newauthor = do { local $/; <STDIN> }; # read <STDIN> as a whole
 | 
						|
		$newauthor =~ s/^\s+|\s+$//g; # trim leading spaces and  trailing spaces
 | 
						|
		if ($newauthor eq '') 
 | 
						|
		{
 | 
						|
			print (STDERR "Not allowed to empty the author\n");
 | 
						|
			exit (1);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	elsif ($PROPNAME eq 'svn:log')
 | 
						|
	{
 | 
						|
		my $minlen = $cfg->{svn_min_commit_message_length};
 | 
						|
		my $newmsg = do { local $/; <STDIN> }; # read <STDIN> as a whole
 | 
						|
		$newmsg =~ s/^\s+|\s+$//g; # trim leading spaces and  trailing spaces
 | 
						|
		if (length($newmsg) < $minlen) 
 | 
						|
		{
 | 
						|
			print (STDERR "Commit message too short. must be >= $minlen\n");
 | 
						|
			exit (1);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
my $dbh = open_database ($cfg);
 | 
						|
if (!defined($dbh))
 | 
						|
{
 | 
						|
	printf (STDERR "Cannot open database - %s\n", $DBI::errstr);
 | 
						|
	exit (1);
 | 
						|
}
 | 
						|
 | 
						|
my ($member, $errstr) = is_project_member ($dbh, $cfg->{database_prefix}, $REPOBASE, $USER);
 | 
						|
 | 
						|
 | 
						|
if ($member <= -1)
 | 
						|
{
 | 
						|
	close_database ($dbh);
 | 
						|
	print (STDERR "Cannot check membership of [$USER] in the $REPOBASE project - $errstr\n");
 | 
						|
	exit (1);
 | 
						|
}
 | 
						|
elsif ($member == 0)
 | 
						|
{
 | 
						|
	close_database ($dbh);
 | 
						|
	print (STDERR "[$USER] doesn't belong to the $REPOBASE project\n");
 | 
						|
	exit (1);
 | 
						|
}
 | 
						|
 | 
						|
if (defined($newauthor))
 | 
						|
{
 | 
						|
	# the new author to set must be a member of the project.
 | 
						|
 | 
						|
	my ($member, $errstr) = is_project_member ($dbh, $cfg->{database_prefix}, $REPOBASE, $newauthor);
 | 
						|
	if ($member <= -1)
 | 
						|
	{
 | 
						|
		close_database ($dbh);
 | 
						|
		print (STDERR "Cannot check membership of [$newauthor] in the $REPOBASE project - $errstr\n");
 | 
						|
		exit (1);
 | 
						|
	}
 | 
						|
	elsif ($member == 0)
 | 
						|
	{
 | 
						|
		close_database ($dbh);
 | 
						|
		print (STDERR "[$newauthor] doesn't belong to the $REPOBASE project\n");
 | 
						|
		exit (1);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
close_database ($dbh);
 | 
						|
exit (0);
 |