Subversion Repositories VORC

Rev

Rev 58 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 bgadell 1
#!/usr/bin/perl
2
 
3
# Redirect error messages to a log of my choosing. (it's annoying to filter for errors in the shared env)
4
my $error_log_path = $ENV{SERVER_NAME} eq "volunteers.rollercon.com" ? "/home3/rollerco/logs/" : "/tmp/";
5
close STDERR;
6
open STDERR, '>>', $error_log_path.'vorc_error.log' or warn "Failed to open redirected logfile ($0): $!";
7
#warn "Redirecting errors to ${error_log_path}vorc_error.log";
8
 
9
use strict;
10
use cPanelUserConfig;
11
use RollerCon;
12
use CGI qw/param cookie header start_html url/;
13
use Email::Valid;
14
use WebDB;
15
use HTML::Tiny;
16
our $h = HTML::Tiny->new( mode => 'html' );
17
 
18
my ($FORM, $cookie_string, $ERRMSG);
19
my @ERRORS;
20
my $dbh = getRCDBH;
21
#my $dbh = WebDB->connect ();
22
my $depts = getDepartments (); # HashRef of the department TLAs -> Display Names...
23
my $deptDesc = getDepartmentDescriptions ();
24
my $deptLink = getDepartmentLinks ();
25
my $AccessLevel = getAccessLevels;
26
my @tshirtOptions = ("", "MS", "MM", "ML", "MXL", "M2X", "M3X");
27
 
28
# The page's form might be submitted as a POST or a GET (or both?)
29
#  The initial _view_ likely comes as a GET request (making it easier to embed in an HREF as a URL)
30
#  Unpack any values sent in the GET and add them to the FORM hash
31
$FORM->{'SUB'} = param ('submit') // '';
32
$FORM->{'RCid'} = param ('RCid') // '';
33
$FORM->{referer} = param ("referer") // "";
34
if ($FORM->{'SUB'} eq '') {
35
	if ($ENV{'REQUEST_URI'}) {
36
		my ($g, $keep) = split /\?/, $ENV{'REQUEST_URI'};
37
		if ($keep) {
38
			foreach (split /&/, $keep) {
39
				my ($k, $v) = split /=/;
40
				$k =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
41
				$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
42
				$k eq "submit" ? $FORM->{'SUB'} = $v : $FORM->{$k} = $v;
43
			}
44
		}
45
	}
46
}
47
 
48
# Keep track of the original referrer for the 'back' link/button
49
my $goback;
50
if ($FORM->{referer}) {
51
	$goback = $FORM->{referer};
52
} else {
53
	$goback = $ENV{HTTP_REFERER};
54
}
55
 
56
 
57
if ($FORM->{'SUB'} eq "Save") {
58
	process_form ($FORM);
59
} elsif ($FORM->{'SUB'} eq "New User") {
60
  display_form ("New", "New User"); # blank form
61
} elsif ($FORM->{'RCid'}) {
62
  display_form ($FORM->{'RCid'}, $FORM->{'SUB'});
63
} else {
64
 	$cookie_string = authenticate (1);
65
 	my ($EM, $PWD, $AL) = split /&/, $cookie_string;
66
 	display_form (getUser ($EM)->{'RCid'}, "View");
67
}
68
 
69
 
70
sub process_form {
71
  my $F = shift // "";
72
  push @ERRORS, "Tried to save an empty form." and return unless $F;
73
 
74
	$F->{email}       = lc WebDB::trim param ('email')   // '';
75
	$F->{password}    = WebDB::trim param ('password')   // '';
76
	$F->{derby_name}  = WebDB::trim param ('derby_name') // '';
77
	$F->{real_name}   = WebDB::trim param ('real_name')  // '';
78
	$F->{pronouns}    = WebDB::trim param ('pronouns')   // '';
79
	$F->{tshirt}      = WebDB::trim param ('tshirt')     // '';
80
	$F->{phone}       = WebDB::trim param ('phone')      // '';
81
	$F->{timeformat}  = WebDB::trim param ('timeformat') // '24hr';
82
#	$F->{level}       = param ('level')      // '';
83
#	$F->{type}        = param ('type')       // '';
84
	$F->{RCid}        = param ('RCid')       // '';
85
	$F->{access}      = param ('access')     // 0;
86
	$F->{mvp_pass}    = defined param ('mvp_pass') ? 1 : 0;
87
	$F->{department}  = join ":", map { "$_-".param ("DEPT-".$_) } map { s/^DEPT-//; $_ } grep { param ($_) ne "" } grep { /^DEPT-/ } param ;
88
  my @AUTODEPTS = map { $_->[0] } $dbh->selectall_array ("select TLA from department where autoapprove = true");
89
 
90
  if ($F->{RCid} eq "New") {
91
  # Saving a new User...
92
    # But first let's do some error checking...0
93
		if (!$F->{password})   { push @ERRORS, "Blank Password!"; }
94
		if (!$F->{real_name})  { push @ERRORS, "Blank Real Name!"; }
95
		if (!$F->{derby_name}) { $F->{derby_name} = $F->{real_name}; } # If they leave derby_name blank, use their real_name
96
		if (checkDupes ('derby_name', $F->{derby_name})) { push @ERRORS, "Derby Name already in use. Pick a different one."; $F->{derby_name} = ""; }
97
#		if (!$F->{level})      { $F->{level} = "B"; } # People keep leaving level blank.  Default 'em if they do.
98
#		if (!$F->{type})       { $F->{type} = "official"; } # and now they left the other drop-down blank!!!
99
		if (!$F->{email})      { push @ERRORS, "Blank Email (User-ID)!"; } else {
100
			$F->{email} =~ s/\s+//g; # make sure people aren't accidentally including spaces
101
			$F->{email} = lc $F->{email}; # sometimes people capitalize their email addresses and that's annoying...
102
			if (! Email::Valid->address (-address => $F->{email}, -mxcheck => 1, -tldcheck => 1)) { push @ERRORS, "Mal-formatted (or fake) Email Address!"; $F->{email} = ""; }
103
		}
104
		if (checkDupes ('email', $F->{email})) { push @ERRORS, "Email Address already in use. Pick a different one."; $F->{email} = ""; }
105
    # if (!$F->{department}) { push @ERRORS, "You need to request at least one Department!"; }
106
 
107
		if (scalar @ERRORS) {
108
			$ERRMSG = join $h->br, @ERRORS;
109
			display_form ("New", "New User", $ERRMSG, $F);
110
			return;
111
		} else {
112
			# We have a correctly formatted email address with a mail host record, go ahead and add the user
113
 
114
			# Check to see if any of the departments they've requested are set to autoapprove.
115
			$F->{department} = convertDepartments $F->{department};
116
			use tableViewer;
117
			map { $F->{department}->{$_} = inArray ($_, \@AUTODEPTS) } keys %{$F->{department}};
118
			$F->{department} = convertDepartments $F->{department};
119
 
120
#			my $sth = $dbh->prepare ("insert into official (email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, password(?), ?, ?, ?, ?, ?, ?, ?, ?)");
121
			my $sth = $dbh->prepare ("insert into official (email, password, derby_name, real_name, pronouns, tshirt, phone, timeformat, access, department, added, activation) values (?, password(?), ?, ?, ?, ?, ?, ?, ?, ?, CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles'), md5(rand()))");
122
 
123
#			$sth->execute ($F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, 0, $F->{department}, 0);
124
			$sth->execute ($F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, $F->{timeformat}, 0, $F->{department});
125
 
126
			$sth = $dbh->prepare ("select RCid, activation from official where email = ?");
127
			$sth->execute ($F->{email});
128
			($F->{RCid}, $F->{activation}) = $sth->fetchrow_array;
129
			logit ($F->{RCid}, "New User Registration");
130
			sendNewUserEMail ("New User", $F);
131
			$cookie_string = authenticate (1);
132
		}
133
	} else {
134
		$cookie_string = authenticate (1);
135
		my ($EM, $PWD, $AL) = split /&/, $cookie_string;
136
		if (lc $EM eq lc $F->{email} and $AL < 5) { # They're editing their own record (and not a sysadmin).
137
 
138
			# Don't let users change their own mvp_pass setting...
139
		  $F->{mvp_pass} = getUser($EM)->{mvp_pass};
140
			my $DBDepts = getUser($EM)->{department};
141
		  if ($F->{department} ne $DBDepts) {
142
		  	# They're trying to change one of their own departments.
143
		  	my $FORMDepts = convertDepartments $F->{department};
144
		  	$DBDepts =   convertDepartments $DBDepts;
145
        # the only change to a dept should be a request to be added, some depts are auto-approved.
146
        use tableViewer;
147
		  	map { $FORMDepts->{$_} = inArray ($_, \@AUTODEPTS) } keys %{$FORMDepts};
148
        # or they can retract their request
149
				map { do { delete $DBDepts->{$_} } if $DBDepts->{$_} == 0 and !defined $FORMDepts->{$_} } keys %{$DBDepts};
150
				# otherwise, keep the same depts as are in the DB (or have been auto-approved...)
151
		  	map { $FORMDepts->{$_} = max ($DBDepts->{$_}, $FORMDepts->{$_}) } keys %{$DBDepts};
152
		  	$F->{department} = convertDepartments $FORMDepts;
153
		  }
154
 
155
      if ($F->{password}) { # They've possibly included an updated password.
156
#    		my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?)");
157
#    		$sth->execute ($F->{RCid}, $EM, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass})
158
    		my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, pronouns, tshirt, phone, activation, timeformat, access, mvp_pass, department, added, last_login) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
159
    		$sth->execute ($F->{RCid}, lc $EM, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, getUser($EM)->{activation}, $F->{timeformat}, $F->{access}, $F->{mvp_pass}, $F->{department}, getUser($EM)->{added}, getUser($EM)->{last_login})
160
    			or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
161
    	} else { # No password was included, just keep the existing one.
162
#    		my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
163
#    		$sth->execute($F->{RCid}, $EM, $PWD, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass})
164
    		my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, pronouns, tshirt, phone, activation, timeformat, access, mvp_pass, department, added, last_login) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
165
    		$sth->execute($F->{RCid}, lc $EM, $PWD, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, getUser($EM)->{activation}, $F->{timeformat}, $F->{access}, $F->{mvp_pass}, $F->{department}, getUser($EM)->{added}, getUser($EM)->{last_login})
166
    			or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
167
    	}
168
 
169
			if ($ERRMSG) {
170
				logit ($F->{RCid}, "DB ERROR: Updating Self Details: $ERRMSG");
171
			} else {
172
				logit ($F->{RCid}, "Updated User Details");
173
			}
174
		} elsif ($AL > 1) { # A lead or higher is updating someone else's record
175
 
176
		  use List::Util qw/sum/;
177
#		  if (sum (values %{ convertDepartments ($F->{department}) }) > 0 and $F->{access} == 0) {
178
		  if (sum (values %{ convertDepartments ($F->{department}) }) > 0 and $F->{access} == 1) {
179
		    # activating a user for the first time...
180
		    $F->{access} = 1;
181
#		    sendNewUserEMail ("Activate", $F);
182
		  }
183
 
184
			if ($FORM->{password}) {
185
#				my $sth = $dbh->prepare ("replace into official (RCid, email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?)");
186
#				$sth->execute ($F->{RCid}, $F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass})
187
				my $sth = $dbh->prepare ("replace into official (RCid, email, password, derby_name, real_name, pronouns, tshirt, phone, activation, timeformat, access, mvp_pass, department, added, last_login) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
188
				$sth->execute ($F->{RCid}, $F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, getUser($F->{email})->{activation}, $F->{timeformat}, $F->{access}, $F->{mvp_pass}, $F->{department}, getUser($F->{email})->{added}, getUser($F->{email})->{last_login})
189
					or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
190
			} else {
191
#				my $sth = $dbh->prepare ("update official set email = ?, derby_name = ?, real_name = ?, phone = ?, level = ?, type = ?, access = ?, department = ?, clinic_pass = ? where RCid = ?");
192
#				$sth->execute ($F->{email}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass}, $F->{RCid})
193
				my $sth = $dbh->prepare ("update official set email = ?, derby_name = ?, real_name = ?, pronouns = ?, tshirt = ?, phone = ?, timeformat = ?, access = ?, mvp_pass = ?, department = ? where RCid = ?");
194
				$sth->execute ($F->{email}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, $F->{timeformat}, $F->{access}, $F->{mvp_pass}, $F->{department}, $F->{RCid})
195
					or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
196
			}
197
			if ($ERRMSG) {
198
				logit ($F->{RCid}, "DB ERROR: Updating Someone Else: $ERRMSG");
199
			} else {
200
				logit ($F->{RCid}, "Updated User Details (by ".getUser($EM)->{derby_name}.")");
201
				logit (getUser($EM)->{RCid}, "Updated User Details: ".$F->{derby_name}." (".$F->{RCid}.")");
202
			}
203
		} else {
204
			$ERRMSG = "Attempting to update someone else's record, and you don't have permission to do that.";
205
			logit ($F->{RCid}, "FAIL: ($EM) doesn't have access to update ($F->{email})'s record");
206
		}
207
	}
208
	$F->{password} = "*******";
209
	$F->{buttons}		= $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{RCid} }).$h->input ({ type=>"submit", name=>"submit", value=>"Edit" });
210
	if ($F->{mvp_pass}) {
211
 		$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>1, readonly=>[], disabled=>[], checked=>[] }), $h->span ({ class=>"slider round" })]);
212
 	} else {
213
 		$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>0, readonly=>[], disabled=>[] }), $h->span ({ class=>"slider round" })]);
214
	}
215
	$F->{department} = convertDepartments ($F->{department});
216
 
217
	display_form ($F->{RCid}, "View");
218
}
219
 
220
sub display_form {
221
  my $RCID = shift // "";
222
  my $view = shift; # // "New User";
223
  my $errors = shift // "";
224
  my $F = shift; # // "";
225
 
226
  if ($view eq 'Edit') {
227
  	$cookie_string = authenticate (1);
228
  	my ($EM, $PWD, $AL) = split /&/, $cookie_string;
229
  	$F = getUser ($RCID);
230
  	my $currentuser = getUser ($EM);
231
#  	$currentuser->{department} = convertDepartments ($currentuser->{department});
232
 
233
#  	if (lc $EM eq lc $F->{email} or $AL > 1) {
234
  	if (canView ($currentuser, $F)) {
235
  	  # Editing your own record OR you're a lead/higher
236
  		if (lc $EM eq lc $F->{email} or $currentuser->{access} < $F->{access}) {
237
  		  # If you're editing your own record, or someone who has higher access than you, make access level read-only
238
  			$F->{access}			= $h->input ({ type=>"hidden", name=>"access", value=>$F->{access} }).$AccessLevel->{$F->{access}};
239
  		} else {
240
  			$F->{access}			= $h->select ({ name=>"access" }, [map { $F->{access} == $_ ? $h->option ({ value=>$_, selected=>[] }, $AccessLevel->{$_}) : $h->option ({ value=>$_ }, $AccessLevel->{$_}) } (-1..$currentuser->{access})]);
241
  		}
242
  		if ($currentuser->{access} > 2) {  #this would be the place to test for other types of managers that can update the MVP Pass setting
243
				if ($F->{mvp_pass}) {
244
 					$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>1, checked=>[] }), $h->span ({ class=>"slider round" })]);
245
 				} else {
246
 					$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>0 }), $h->span ({ class=>"slider round" })]);
247
				}
248
  		} else {
249
				if ($F->{mvp_pass}) {
250
 					$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>1, readonly=>[], disabled=>[], checked=>[] }), $h->span ({ class=>"slider round" })]);
251
 				} else {
252
 					$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>0, readonly=>[], disabled=>[] }), $h->span ({ class=>"slider round" })]);
253
				}
254
  		}
255
      if ($AL == 5) {
256
    	  $F->{email}      = $h->input ({ type=>"text", name=>"email", value=>$F->{email} });
257
    	} else {
258
  		  $F->{email}      = $F->{email}.$h->input ({ type=>"hidden", name=>"email", value=>$F->{email} });
259
  		}
260
  		if ($currentuser->{RCid} eq $F->{RCid} or $currentuser->{access} > 4) {
261
  			$F->{password}   = $h->input ({ type=>"password", name=>"password" });
262
  			$F->{derby_name} = $h->input ({ type=>"text", name=>"derby_name", value=>$F->{derby_name} });
263
  			$F->{real_name}  = $h->input ({ type=>"text", name=>"real_name", value=>$F->{real_name} });
264
  			$F->{pronouns}   = $h->input ({ type=>"text", name=>"pronouns", value=>$F->{pronouns} });
265
  			$F->{tshirt}     = $h->select ({ name=>"tshirt" }, [map { $F->{tshirt} eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @tshirtOptions] );
266
  			$F->{phone}      = $h->input ({ type=>"text", name=>"phone", value=>$F->{phone} });
267
     	  $F->{timeformat} = $h->select ({ name=>"timeformat" }, [map { $F->{timeformat} eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } qw(24hr ampm)] );
268
  		} else {
269
  			$F->{password}   = '*******';
270
  		}
271
#  		$F->{level}      = "<SELECT NAME=level>".selectOptions ($F->{level}, [qw(AA A B C)])."</SELECT>";
272
#  		$F->{type}       = "<SELECT NAME=type>".selectOptions ($F->{type}, [qw(official nso referee)])."</SELECT>";
273
  		$F->{RCid}       = $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{RCid} })."$F->{RCid}&nbsp;";
274
  		$F->{buttons}		 = join " ", $h->input ({ type=>"submit", name=>"submit", value=>"Save" }), $h->input ({ type=>"reset", value=>"Reset" }), $h->input ({ type=>"submit", name=>"submit", value=>"Cancel" });
275
 
276
    	$F->{department} = convertDepartments ($F->{department});
277
    	$currentuser->{department} = convertDepartments ($currentuser->{department});
278
    	foreach my $k (keys %{$depts}) {
279
    	  next if $k eq "CMP";
280
    	  if ($currentuser->{access} > 4) {
281
    	    # SysAdmin can change anyone's department level
282
    	    $F->{department}->{$k} = $h->select ({ name=>"DEPT-".$k }, [ $h->option ({ value=>"" }, ""), map { $_ eq $F->{department}->{$k} ? $h->option ({ value=>$_, selected=>[] }, $AccessLevel->{$_}) : $h->option ({ value=>$_ }, $AccessLevel->{$_}) } (0..4) ]);
283
    	  } elsif ($currentuser->{department}->{$k} > 1 and $currentuser->{department}->{$k} > $F->{department}->{$k}) {
284
    	    # Department Leads and above can change someone's level within the dept (up to their own level -1)
285
    	    $F->{department}->{$k} = $h->select ({ name=>"DEPT-".$k }, [ $h->option ({ value=>"" }, ""), map { $_ eq $F->{department}->{$k} ? $h->option ({ value=>$_, selected=>[] }, $AccessLevel->{$_}) : $h->option ({ value=>$_ }, $AccessLevel->{$_}) } (0..$currentuser->{department}->{$k}-1) ]);
286
    	  } else {
287
    	    # Or it's your own record, you can still submit a request to be added to the dept.
288
    	    if (!defined $F->{department}->{$k}) {
289
            $F->{department}->{$k} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$k", value=>0 }), $h->span ({ class=>"slider round" })]);
290
          } elsif ($F->{department}->{$k} == 0) {
291
            $F->{department}->{$k} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$k", value=>0, checked=>[] }), $h->span ({ class=>"slider round" })]);
292
          }
293
    	  }
294
    	}
295
  	} else {
296
  		$ERRMSG = "Attempting to update someone else's record, and you don't have permission to do that.";
297
  	}
298
 
299
  } elsif ($view eq 'New User') {
300
    $errors .= $h->br."NOTE: You will not be able to sign-up for things until your account has been reviewed and approved. Watch your email for notification.";
301
  	# Skip authentication
302
 		$F->{email}      = $h->input ({ type=>"text", name=>"email", value=>$F->{email} });
303
 		$F->{password}   = $h->input ({ type=>"password", name=>"password" });
304
 		$F->{derby_name} = $h->input ({ type=>"text", name=>"derby_name", value=>$F->{derby_name} });
305
 		$F->{real_name}  = $h->input ({ type=>"text", name=>"real_name", value=>$F->{real_name} });
306
		$F->{pronouns}   = $h->input ({ type=>"text", name=>"pronouns", value=>$F->{pronouns} });
307
		$F->{tshirt}     = $h->select ({ name=>"tshirt" }, [map { $F->{tshirt} eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @tshirtOptions] );
308
 		$F->{phone}      = $h->input ({ type=>"text", name=>"phone", value=>$F->{phone} });
309
 	  $F->{timeformat} = $h->select ({ name=>"timeformat" }, [map { $F->{timeformat} eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } qw(24hr ampm)] );
310
#  	$F->{level}      = "<SELECT NAME=level>".selectOptions ($F->{level}, ["", qw(AA A B C)])."</SELECT>";
311
#  	$F->{type}       = "<SELECT NAME=type>".selectOptions ($F->{type}, ["", qw(official nso referee)])."</SELECT>";
312
 		$F->{RCid}         = $h->input ({ type=>"hidden", name=>"RCid", value=>"New" })."TBD&nbsp;";
313
  	$F->{access}			= $h->input ({ type=>"hidden", name=>"access", value=>0 })."0";
314
  	$F->{mvp_pass}	 = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>0, readonly=>[], disabled=>[] }), $h->span ({ class=>"slider round" })]);
315
 
316
    $F->{department} = convertDepartments ($F->{department});
317
  	foreach (sort keys %{$depts}) {
318
  	  next if $_ eq "CMP";
319
  	  if (defined param ("DEPT-$_")) {
320
  	    $F->{department}->{$_} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$_", value=>0, checked=>[] }), $h->span ({ class=>"slider round" })]);
321
  	  } else {
322
  	    $F->{department}->{$_} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$_", value=>0 }), $h->span ({ class=>"slider round" })]);
323
  	  }
324
  	}
325
  	$F->{buttons}		= $h->input ({ type=>"submit", name=>"submit", value=>"Save" })." ".$h->input ({ type=>"reset", value=>"Reset" })." ".$h->input ({ type=>"submit", name=>"submit", value=>"Cancel" });
326
  	$cookie_string = '';
327
  } elsif ($view eq 'View' or $view eq 'Cancel' or !$view) {
328
  	$cookie_string = authenticate (1);
329
  	my ($EM, $PWD, $AL) = split /&/, $cookie_string;
330
 
331
  	if (!$view) {
332
      $F->{'RCid'} = getUser ($EM)->{'RCid'};
333
  	}
334
 
335
  	# Check to make sure they're only looking up their own ID unless they're a lead or higher
336
  	my $currentuser = getUser ($EM);
337
    my	$targetuser = getUser ($RCID);
338
 
339
  	if (canView ($currentuser, $targetuser)) {
340
    	$F = $targetuser;
341
    	$F->{department} = convertDepartments ($F->{department});
342
      $F->{access} = $AccessLevel->{$F->{access}};
343
    	$F->{'password'} = "*******";
344
      $F->{buttons}		= $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{'RCid'} }).$h->input ({ type=>"submit", name=>"submit", value=>"Edit" });
345
			if ($F->{mvp_pass}) {
346
 				$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>1, readonly=>[], disabled=>[], checked=>[] }), $h->span ({ class=>"slider round" })]);
347
 			} else {
348
 				$F->{mvp_pass}	= $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"mvp_pass", value=>0, readonly=>[], disabled=>[] }), $h->span ({ class=>"slider round" })]);
349
			}
350
  	} else {
351
  	  logit ($currentuser->{RCid}, "SECURITY: $currentuser->{derby_name} attempted to view another user's ($RCID) info");
352
  	  $errors = "Unauthorized attempt to view another user.  This has been logged.";
353
    	$F->{email}      = "&nbsp;";
354
    	$F->{password}   = "&nbsp;";
355
    	$F->{derby_name} = "&nbsp;";
356
    	$F->{real_name}  = "&nbsp;";
357
    	$F->{pronouns}   = "&nbsp;";
358
    	$F->{tshirt}     = "&nbsp;";
359
    	$F->{phone}      = "&nbsp;";
360
    	$F->{timeformat} = "&nbsp;";
361
#    	$F->{level}      = "&nbsp;";
362
#    	$F->{type}       = "&nbsp;";
363
    	$F->{RCid}       = "&nbsp;";
364
    	$F->{access}		 = "&nbsp;";
365
    	$F->{mvp_pass}   = "&nbsp;";
366
    	$F->{buttons}		 = "&nbsp;";
367
    }
368
 
369
#  	if (lc $EM eq lc $F->{email} or $AL > 1) {
370
#      $F->{buttons}		= $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{'RCid'} }).$h->input ({ type=>"submit", name=>"submit", value=>"Edit" });
371
#  	} else {
372
#  		$F->{buttons} = "";
373
#  	}
374
  } #else {
375
  #	$cookie_string = authenticate(1);
376
  #	$FORM->{email}      = "&nbsp;";
377
  #	$FORM->{password}   = "&nbsp;";
378
  #	$FORM->{derby_name} = "&nbsp;";
379
  #	$FORM->{real_name}  = "&nbsp;";
380
  #	$FORM->{phone}      = "&nbsp;";
381
  #	$FORM->{level}      = "&nbsp;";
382
  #	$FORM->{type}       = "&nbsp;";
383
  #	$FORM->{RCid}         = "&nbsp;";
384
  #	$FORM->{access}			= "&nbsp;";
385
  #	$FORM->{mvp_pass} 	= "&nbsp;";
386
  #	$FORM->{buttons}		= "&nbsp;";
387
  #}
388
 
389
  #---------------START THE HTML--------------------
390
 
391
  my $RCAUTH_cookie = cookie (-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
392
 
393
  print header (-cookie=>$RCAUTH_cookie);
394
 
395
  #foreach (keys %ENV) {
396
  #	print "$_: $ENV{$_}\n<br>";
397
  #}
398
 
399
  if ($errors) {
400
  	$errors = $h->div ({ class=>"error" }, $errors);
401
  } else {
402
  	$errors = "";
403
  }
404
 
405
   my @printDepartments = ( $h->div ({ class=>"index", style=>"display: unset;" }, $h->p ({ class=>"heading" }, "Department Access:")) );
406
#  push @printDepartments, $h->div ({ class=>"rTableRow" }, $h->div ({ class=>"rTableCellr hint", style=>"display:block;" }, "Here is where you're signed up to volunteer at RollerCon:"));
407
  push @printDepartments, $h->div ({ class=>"rTableRowSpan" },[ $h->div ({ style=>"rTableCellr" }, $h->div ({ class=>"hint" }, "Here is where you're signed up to volunteer at RollerCon:")) ]);
408
#  push @printDepartments, $h->div ({ class=>"hint", style=>"display: unset;" }, "Here is where you're signed up to volunteer at RollerCon:");
409
  foreach (sort grep { !/^PER$/ } keys %{$F->{department}}) {
410
    push @printDepartments, $h->div ({ class=>"rTableRow" }, [
411
      $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" },
412
        [ $h->span ({ class=>"tooltip-wrap" }, [$h->img ({src=>"/images/qm.png", width=>"18", height=>"18"}), $h->div ({ class=>"tooltip-content" }, $h->div ({class=>"bold"}, $depts->{$_}).$deptDesc->{$_} . (exists $deptLink->{$_} ? $h->a ({ href=>$deptLink->{$_}, target=>"_new"}, " [More Info]") : "") )]), $depts->{$_}.":" ],
413
        $F->{department}->{$_} =~ /^\d$/ ? $AccessLevel->{$F->{department}->{$_}} : $F->{department}->{$_}),
414
    ]);
415
  }
416
 
417
  printRCHeader ("User Manager");
418
 
419
  print $errors;
420
  print $h->form ({ action=>url, method=>'POST', name=>'Req' },[
421
    $h->input ({ type=>"hidden", name=>"referer", value=>$goback }),
422
    $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "User Details:"),
423
      $h->div ({ class=>"rTable", style=>"min-width: 0%;" },[
424
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "User-ID / Email Address: ", $F->{email}) ]),
425
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Password: ",                $F->{password}) ]),
426
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Derby Name: ",              $F->{derby_name}) ]),
427
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Real Name: ",               $F->{real_name}) ]),
428
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Pronouns: ",                $F->{pronouns}) ]),
429
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "TShirt Size: ",             $F->{tshirt}) ]),
430
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Phone: ",                   $F->{phone}) ]),
431
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Time Format: ",       $F->{timeformat}) ]),
432
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Database ID: ",             $F->{RCid}) ]),
433
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "User Added: ",              $F->{added}) ]),
434
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Last Login: ",              $F->{last_login}) ]),
435
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "vORC Access Level: ",       $F->{access}) ]),
436
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "MVP Pass: ",                $F->{mvp_pass}) ]),
437
        @printDepartments,
438
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCell" }, "&nbsp;") ]),
439
        $h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr" }, $h->a ({ href=>$goback }, "[go back]"), $F->{buttons}) ])
440
      ])
441
    ])
442
  ]); #  print $h->close('form');
443
  print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Schedule:"), getSchedule ($RCID, "all")]) unless $RCID !~ /^\d+$/;
444
  print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Recent Activity:"), getLog ($RCID)]) unless $RCID !~ /^\d+$/;
445
  print $h->close ('html');
446
}
447
 
448
#sub selectOptions {
449
#	my $selectedOption = shift;
450
#	my $options = shift;
451
#	return join " ", map { $selectedOption eq $_ ?
452
#	                        $h->option ({ value=>$_, selected=>[] }, $_) :
453
#													$h->option ({ value=>$_ }, $_)
454
#						 					} @$options;
455
#}
456
 
457
 
458
sub checkDupes {
459
  my $field = shift;
460
  my $nametocheck = shift;
461
  my $han = $dbh->prepare("select RCid from official where $field = ?");
462
  $han->execute($nametocheck);
463
  my ($rcid) = $han->fetchrow();
464
  return $rcid;
465
}
466
 
467
sub getLog {
468
  my $RCID = shift;
469
 
470
  my @activity_log;
471
  my $alog = $dbh->prepare("select timestamp, event from v_log where RCid = ? limit 10");
472
  $alog->execute($RCID);
473
  while (my @logs = $alog->fetchrow_array) {
474
  	push @activity_log, $h->li ({ class=>"shaded" }, join " ", @logs);
475
  }
476
 
477
  return $h->ul ([@activity_log]).$h->h5 ($h->a ({ href=>"log.pl?filter-RCid=".$RCID }, "[Entire log history]"));
478
}
479
 
480
sub getDepartmentDescriptions {
481
 	my %HASH;
482
 	my $sth = $dbh->prepare("select TLA, description from department");
483
 	$sth->execute();
484
 	while (my ($tla, $name) = $sth->fetchrow) {
485
 	  $HASH{$tla} = $name;
486
  }
487
  return \%HASH;
488
}
489
 
490
sub getDepartmentLinks {
491
 	my %HASH;
492
 	my $sth = $dbh->prepare("select TLA, link from department where link <> ''");
493
 	$sth->execute();
494
 	while (my ($tla, $name) = $sth->fetchrow) {
495
 	  $HASH{$tla} = $name;
496
  }
497
  return \%HASH;
498
}