Gentoo Archives: gentoo-commits

From: "Robin H. Johnson" <robbat2@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/elections:master commit in: /
Date: Sun, 03 Jul 2016 15:01:55
Message-Id: 1467558093.6a7d8fab58c70a80175dc107178ee5dcac733adc.robbat2@gentoo
1 commit: 6a7d8fab58c70a80175dc107178ee5dcac733adc
2 Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
3 AuthorDate: Sun Jul 3 15:01:33 2016 +0000
4 Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
5 CommitDate: Sun Jul 3 15:01:33 2016 +0000
6 URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=6a7d8fab
7
8 Votify: improve election base validation, and code documentation.
9
10 Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
11
12 Votify.pm | 81 +++++++++++++++++++++++++++++++++++++++++++--------------------
13 1 file changed, 55 insertions(+), 26 deletions(-)
14
15 diff --git a/Votify.pm b/Votify.pm
16 index ed5b519..8e0fe1a 100644
17 --- a/Votify.pm
18 +++ b/Votify.pm
19 @@ -13,7 +13,10 @@ use Cwd qw(abs_path);
20 use File::Basename;
21 use File::Spec::Functions;
22 use List::Util;
23 +use Data::Dumper;
24 +use Carp::Always;
25 use strict;
26 +use warnings;
27
28 our $datefmt = '%Y-%m-%d %H:%M:%S UTC';
29 our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', dirname(__FILE__));
30 @@ -27,42 +30,61 @@ sub import {
31
32 my @REQUIRED_FILES = qw(ballot officials start stop voters);
33
34 -sub get_datadir {
35 - my $election_name = shift;
36 +# Takes the name of an election and ensure it's validate under the basedir,
37 +# returning the full path to the election if valid, and undef if not valid.
38 +# Where valid is:
39 +# A directory containing ALL of the files in @REQUIRED_FILES, either either
40 +# their direct names, or the name of the election on the end of the files.
41 +# Eg 'ballot' or 'ballot-election1234'.
42 +sub validate_election_dir {
43 + my $election_rawdir = shift;
44 + return 0 unless defined $election_rawdir;
45 + return 0 if substr($election_rawdir,0,1) eq ".";
46 +
47 + my $election_name = $election_rawdir;
48 + $election_name =~ s/.*\///;
49 my $election_dir = abs_path(catfile($Votify::basedir, $election_name));
50 - if(!validate_election_dir()) {
51 - die "$election_name is not a valid election!"
52 - }
53 - return $election_dir;
54 -}
55
56 -sub validate_election_dir {
57 - return 0 unless $_;
58 - my $election_dir = $_;
59 - my $election_name = $election_dir;
60 - $election_name =~ /.*\//;
61 - return 0 unless -d "$basedir/$election_dir";
62 + # Fail if it's not a directory in the basedir
63 + return 0 unless -d $election_dir;
64 +
65 + # Do not try to validate hidden directories.
66 return 0 if substr($election_name,0,1) eq ".";
67 - my $valid = List::Util::reduce {
68 - $a or $b ? 1 : 0;
69 - } map {
70 +
71 + # Validate that the required files exist in the dir
72 + # Part 1, convert the array to a map
73 + my %REQUIRED_FILES_valid = map {
74 my $file_valid = 0;
75 # Legacy naming:
76 - $file_valid = 1 if -f sprintf("%s/%s-%s", "$basedir/$election_name", $_, $election_name);
77 + $file_valid = 1 if -f sprintf("%s/%s-%s", $election_dir, $_, $election_name);
78 # New naming:
79 - $file_valid = 1 if -f sprintf("%s/%s", "$basedir/$election_name", $_);
80 + $file_valid = 1 if -f sprintf("%s/%s", $election_dir, $_);
81 #printf "File %s valid=%d\n", $_, $file_valid;
82 - $file_valid;
83 + ($_, $file_valid);
84 } @REQUIRED_FILES;
85 - return $valid;
86 +
87 + # Part 2, ensure all of the map is true
88 + my $valid = List::Util::reduce {
89 + $a or $b ? 1 : 0;
90 + } values(%REQUIRED_FILES_valid);
91 +
92 + # Now return.
93 + return $election_dir if $valid;
94 + return undef;
95 }
96
97 sub get_elections_list {
98 my @elections;
99 opendir(D, $Votify::basedir) or die;
100 @elections = sort grep {
101 - my $valid = validate_election_dir(catfile($Votify::basedir, $_));
102 - $valid;
103 + -d $_ and
104 + $_ ne "." and
105 + $_ ne ".." and
106 + $_ ne "" and
107 + substr($_, 0, 1) ne ".";
108 + } grep {
109 + my $valid_election_dir = validate_election_dir($_);
110 + defined $valid_election_dir;
111 } readdir D;
112 closedir D;
113 return @elections;
114 @@ -84,7 +106,8 @@ sub grabfile_int {
115
116 sub get_single_election_hashref {
117 my $election_name = shift;
118 - my $election_dir = catfile($Votify::basedir, $election_name);
119 + my $election_dir = validate_election_dir($election_name);
120 + return undef unless defined $election_dir;
121 my %election;
122 foreach my $fn (@REQUIRED_FILES){
123 #print "Scan $fn\n";
124 @@ -101,7 +124,9 @@ sub get_single_election_hashref {
125
126 sub get_elections_hash {
127 my %elections;
128 - %elections = map { $_ => get_single_election_hashref($_) } get_elections_list();
129 + my @elections_list = get_elections_list();
130 + #print Dumper(\@elections_list);
131 + %elections = map { $_ => get_single_election_hashref($_) } @elections_list;
132 return %elections;
133 }
134
135 @@ -151,11 +176,13 @@ sub officials {
136 ######################################################################
137
138 package VoterList;
139 +use File::Spec::Functions;
140
141 sub new {
142 my ($class, $election_name) = @_;
143 my (@voterlist, $r);
144 - my $datadir = Votify::get_datadir($election_name);
145 + my $datadir = Votify::validate_election_dir($election_name);
146 + die "Unable to get election dir for name $election_name" unless defined $datadir;
147 my ($self) = {
148 election => $election_name,
149 default_filename => catfile($datadir, "confs-$election_name"),
150 @@ -230,10 +257,12 @@ sub write {
151 package MasterBallot;
152
153 use Data::Dumper;
154 +use File::Spec::Functions;
155
156 sub new {
157 my ($class, $election_name, $vl) = @_;
158 - my $datadir = Votify::get_datadir($election_name);
159 + my $datadir = Votify::validate_election_dir($election_name);
160 + die "Unable to get election dir for name $election_name" unless defined $datadir;
161 my ($self) = {
162 election => $election_name,
163 default_filename => catfile($datadir, "master-$election_name"),