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"), |