From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 7121E1382DE for ; Sun, 3 Jul 2016 15:01:55 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 1FED7E09FC; Sun, 3 Jul 2016 15:01:53 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id A2FF6E09FC for ; Sun, 3 Jul 2016 15:01:52 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 289A8340D85 for ; Sun, 3 Jul 2016 15:01:50 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 7F9DB13FF for ; Sun, 3 Jul 2016 15:01:46 +0000 (UTC) From: "Robin H. Johnson" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Robin H. Johnson" Message-ID: <1467558093.6a7d8fab58c70a80175dc107178ee5dcac733adc.robbat2@gentoo> Subject: [gentoo-commits] proj/elections:master commit in: / X-VCS-Repository: proj/elections X-VCS-Files: Votify.pm X-VCS-Directories: / X-VCS-Committer: robbat2 X-VCS-Committer-Name: Robin H. Johnson X-VCS-Revision: 6a7d8fab58c70a80175dc107178ee5dcac733adc X-VCS-Branch: master Date: Sun, 3 Jul 2016 15:01:46 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 4e0655cb-5169-4c3c-a316-b5827493517e X-Archives-Hash: a1bab1f2bf55b0a925ccad435923fbb8 commit: 6a7d8fab58c70a80175dc107178ee5dcac733adc Author: Robin H. Johnson gentoo org> AuthorDate: Sun Jul 3 15:01:33 2016 +0000 Commit: Robin H. Johnson gentoo org> CommitDate: Sun Jul 3 15:01:33 2016 +0000 URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=6a7d8fab Votify: improve election base validation, and code documentation. Signed-off-by: Robin H. Johnson gentoo.org> Votify.pm | 81 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/Votify.pm b/Votify.pm index ed5b519..8e0fe1a 100644 --- a/Votify.pm +++ b/Votify.pm @@ -13,7 +13,10 @@ use Cwd qw(abs_path); use File::Basename; use File::Spec::Functions; use List::Util; +use Data::Dumper; +use Carp::Always; use strict; +use warnings; our $datefmt = '%Y-%m-%d %H:%M:%S UTC'; our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', dirname(__FILE__)); @@ -27,42 +30,61 @@ sub import { my @REQUIRED_FILES = qw(ballot officials start stop voters); -sub get_datadir { - my $election_name = shift; +# Takes the name of an election and ensure it's validate under the basedir, +# returning the full path to the election if valid, and undef if not valid. +# Where valid is: +# A directory containing ALL of the files in @REQUIRED_FILES, either either +# their direct names, or the name of the election on the end of the files. +# Eg 'ballot' or 'ballot-election1234'. +sub validate_election_dir { + my $election_rawdir = shift; + return 0 unless defined $election_rawdir; + return 0 if substr($election_rawdir,0,1) eq "."; + + my $election_name = $election_rawdir; + $election_name =~ s/.*\///; my $election_dir = abs_path(catfile($Votify::basedir, $election_name)); - if(!validate_election_dir()) { - die "$election_name is not a valid election!" - } - return $election_dir; -} -sub validate_election_dir { - return 0 unless $_; - my $election_dir = $_; - my $election_name = $election_dir; - $election_name =~ /.*\//; - return 0 unless -d "$basedir/$election_dir"; + # Fail if it's not a directory in the basedir + return 0 unless -d $election_dir; + + # Do not try to validate hidden directories. return 0 if substr($election_name,0,1) eq "."; - my $valid = List::Util::reduce { - $a or $b ? 1 : 0; - } map { + + # Validate that the required files exist in the dir + # Part 1, convert the array to a map + my %REQUIRED_FILES_valid = map { my $file_valid = 0; # Legacy naming: - $file_valid = 1 if -f sprintf("%s/%s-%s", "$basedir/$election_name", $_, $election_name); + $file_valid = 1 if -f sprintf("%s/%s-%s", $election_dir, $_, $election_name); # New naming: - $file_valid = 1 if -f sprintf("%s/%s", "$basedir/$election_name", $_); + $file_valid = 1 if -f sprintf("%s/%s", $election_dir, $_); #printf "File %s valid=%d\n", $_, $file_valid; - $file_valid; + ($_, $file_valid); } @REQUIRED_FILES; - return $valid; + + # Part 2, ensure all of the map is true + my $valid = List::Util::reduce { + $a or $b ? 1 : 0; + } values(%REQUIRED_FILES_valid); + + # Now return. + return $election_dir if $valid; + return undef; } sub get_elections_list { my @elections; opendir(D, $Votify::basedir) or die; @elections = sort grep { - my $valid = validate_election_dir(catfile($Votify::basedir, $_)); - $valid; + -d $_ and + $_ ne "." and + $_ ne ".." and + $_ ne "" and + substr($_, 0, 1) ne "."; + } grep { + my $valid_election_dir = validate_election_dir($_); + defined $valid_election_dir; } readdir D; closedir D; return @elections; @@ -84,7 +106,8 @@ sub grabfile_int { sub get_single_election_hashref { my $election_name = shift; - my $election_dir = catfile($Votify::basedir, $election_name); + my $election_dir = validate_election_dir($election_name); + return undef unless defined $election_dir; my %election; foreach my $fn (@REQUIRED_FILES){ #print "Scan $fn\n"; @@ -101,7 +124,9 @@ sub get_single_election_hashref { sub get_elections_hash { my %elections; - %elections = map { $_ => get_single_election_hashref($_) } get_elections_list(); + my @elections_list = get_elections_list(); + #print Dumper(\@elections_list); + %elections = map { $_ => get_single_election_hashref($_) } @elections_list; return %elections; } @@ -151,11 +176,13 @@ sub officials { ###################################################################### package VoterList; +use File::Spec::Functions; sub new { my ($class, $election_name) = @_; my (@voterlist, $r); - my $datadir = Votify::get_datadir($election_name); + my $datadir = Votify::validate_election_dir($election_name); + die "Unable to get election dir for name $election_name" unless defined $datadir; my ($self) = { election => $election_name, default_filename => catfile($datadir, "confs-$election_name"), @@ -230,10 +257,12 @@ sub write { package MasterBallot; use Data::Dumper; +use File::Spec::Functions; sub new { my ($class, $election_name, $vl) = @_; - my $datadir = Votify::get_datadir($election_name); + my $datadir = Votify::validate_election_dir($election_name); + die "Unable to get election dir for name $election_name" unless defined $datadir; my ($self) = { election => $election_name, default_filename => catfile($datadir, "master-$election_name"),