package ByShiftAuth; use strict; use warnings; use Apache2::Access (); use Apache2::RequestUtil (); use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED AUTH_REQUIRED); use DBI; use Digest::MD5 qw( md5_hex ); sub handler { my $r = shift; # See if this is the initial request or not, if it isn't # they are already authentication and we just need to reset # the username if( !$r->is_initial_req ) { if( defined $r->prev ) { $r->user( $r->prev->user ); } return Apache2::Const::OK; } # Check to see if it's a weekend my $day_of_week = (localtime(time))[6]; if( $day_of_week == 0 or $day_of_week == 6 ) { return Apache2::Const::HTTP_UNAUTHORIZED; } # Get the username and password my ($rc, $password) = $r->get_basic_auth_pw(); my $user = $r->user; unless ( $user and $password ) { $r->note_basic_auth_failure; return( Apache2::Const::AUTH_REQUIRED ); } # Now let's connect to our database and compare things in # our database we're going to store passwords as MD5 digests my $dbh = DBI->connect('dbi:Pg:dbname=admin', 'apache', 'secret') or die "Cannot connect to database: $!"; my $sth = $dbh->prepare( qq{ SELECT password FROM users WHERE user = ? AND current_time BETWEEN shift_begin AND shift_end }); $sth->execute( $user ); my $db_password = $sth->fetchrow; $sth->finish; # Make sure we found a password for this user, if we don't # it means they don't exist or their shift isn't in progress if( !$db_password ) { $r->note_basic_auth_failure; return( Apache2::Const::AUTH_REQUIRED ); } # Check to make sure the passwords match if( md5_hex( $password ) ne $db_passwd ) { $r->note_basic_auth_failure; return( Apache2::Const::AUTH_REQUIRED ); } return( Apache2::Const::OK );