Subversion Repositories VORC

Rev

Details | Last modification | View Log | RSS feed

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