Subversion Repositories ORC

Rev

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